Fig1. Den konvekse innhyllinga av 100 tilfeldige punkter i planet (de samme som nyttes i oppgaven.)

Like dokumenter
Uke 12 inf2440 v2018. Eric Jul PSE-gruppa Ifi, UiO

INF2440 Uke 8, v2015 : Om Oblig 3, Ulike Threadpools, JIT-kompilering. Arne Maus PSE, Inst. for informatikk

Uke 13 inf2440 v2016. Arne Maus PSE-gruppa Ifi, Uio

Uke 12 IN3030 v2019. Eric Jul PSE-gruppa Ifi, UiO

INF2440 Uke 14, v2018. Eric Jul PSE, Inst. for informatikk

INF2440 Uke 14, v2016. Arne Maus PSE, Inst. for informatikk

UNIVERSITETET I OSLO

INF2440 Uke 14, v2017. Arne Maus PSE, Inst. for informatikk

To geometriske algoritmer, kap. 8.6

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

kap. 8.6 Computational Geometry Hovedkapittelet (kap. 8) dreier seg generelt om devide-and-conquer eller splitt og hersk :

Obligatorisk oppgave 5: Labyrint

Computational Geometry

INF2440 Uke 9, v2015 : Arne Maus PSE, Inst. for informatikk

I et Java-program må programmøren lage og starte hver tråd som programmet bruker. Er dette korrekt? Velg ett alternativ

Obligatorisk oppgave 1 i INF 4130, høsten 2008

UNIVERSITETET I OSLO

INF2220: Time 12 - Sortering

IN1010 V18, Obligatorisk oppgave 5

Oblig2 - obligatorisk oppgave nr. 2 (av 4) i INF1000

Hvor raskt klarer vi å sortere?

INF Triangulering. Med sterk støtte fra Petter Kristiansen. Skal først se på et eksempel fra Google Earth

N-dronningproblemet Obligatorisk oppgave 1 I120, H-2000

UNIVERSITETET I OSLO

MAT-INF 1100: Obligatorisk oppgave 1

Først litt praktisk info. Sorteringsmetoder. Nordisk mesterskap i programmering (NCPC) Agenda

Heap* En heap er et komplett binært tre: En heap er også et monotont binært tre:

Rekursjon. Binærsøk. Hanois tårn.

PG4200 Algoritmer og datastrukturer forelesning 3. Lars Sydnes 29. oktober 2014

Prøveeksamen INF2440 v Arne Maus PSE, Inst. for informatikk

Oblig 4 (av 4) INF1000, høsten 2012 Værdata, leveres innen 9. nov. kl

Obligatorisk oppgave 1: Regneklynge

MAT-INF 1100: Obligatorisk oppgave 1

Definisjon av binært søketre

2 Om statiske variable/konstanter og statiske metoder.

EKSAMEN. Dato: 18. mai 2017 Eksamenstid: 09:00 13:00

Repetisjon: Statiske språk uten rekursive metoder (C1 og C2) Dagens tema Kjøresystemer (Ghezzi&Jazayeri 2.6, 2.7)

Sorteringsproblemet. Gitt en array A med n elementer som kan sammenlignes med hverandre:

Dagens tema Kjøresystemer (Ghezzi&Jazayeri 2.6, 2.7)

UNIVERSITETET I OSLO

Kanter, kanter, mange mangekanter. Introduksjon: Steg 1: Enkle firkanter. Sjekkliste. Skrevet av: Sigmund Hansen

INF2440 Uke 10, v2014 : Arne Maus OMS, Inst. for informatikk

MAT-INF 1100: Obligatorisk oppgave 1

INF1010 siste begreper før oblig 2

Oblig2 - obligatorisk oppgave nr. 2 (av 4) i INF1000 v2008

UNIVERSITETET I OSLO

MAT-INF 1100: Obligatorisk oppgave 1

Oblig3Pi- en matematisk rettet obligatorisk oppgave nr. 3 (av 4) i INF1000 ett av to alternativer for oblig 3.

INF Obligatorisk innlevering 5

Sudokubrettet Et sudokubrett består av n n ruter. Vi bruker følgende begreper i oppgaven:

INF NOV PARALLELL SORTERING. Arne Maus, PSE, Ifi

Oblig2 - obligatorisk oppgave nr. 2 (av 4) i INF1000

UNIVERSITETET I OSLO

Oblig2 - obligatorisk oppgave nr. 2 (av 4) i INF1000 h2006

Kanter, kanter, mange mangekanter

Løsnings forslag i java In115, Våren 1996

INF Innleveringsoppgave 6

Verden. Steg 1: Vinduet. Introduksjon

Obligatorisk oppgave 1 i INF 4130, høsten 2009

INF1010 Rekursive metoder, binære søketrær. Algoritmer: Mer om rekursive kall mellom objekter Ny datastruktur: binært tre

INF2440 Eksamen 2016 løsningsforslag. Arne Maus, PSE ifi, UiO

alternativer til sortering og søking binære trær søketrær Ikke-rekursiv algoritme som løser Hanois tårn med n plater

INF2440 Uke 14, v2014. Arne Maus OMS, Inst. for informatikk

INF1010 notat: Binærsøking og quicksort

Oblig2 - obligatorisk oppgave nr. 2 (av 4) i INF1000 v2009

Java PRP brukermanual

Algoritmer og datastrukturer Løsningsforslag

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO Det matematisk-naturvitenskapelige fakultet

PG 4200 Algoritmer og datastrukturer Innlevering 2

Eksamen iin115, 14. mai 1998 Side 2 Oppgave 1 15 % Du skal skrive en prosedyre lagalle som i en global character array S(1:n) genererer alle sekvenser

Det du skal gjøre i denne oppgava er først å sette opp bakgrunnen til spillet og så rett og slett å få firkanter til å falle over skjermen.

Algoritmer og datastrukturer Kapittel 2 - Delkapittel 2.1

Plan: Parameter-overføring Alias Typer (Ghezzi&Jazayeri kap.3 frem til 3.3.1) IN 211 Programmeringsspråk

Logaritmiske sorteringsalgoritmer

Eksamen i IN 110, 18. mai 1993 Side 2 Del 1 (15%) Vi skal se på prioritetskøer av heltall, der vi hele tiden er interessert i å få ut den minste verdi

En algoritme for permutasjonsgenerering

Tetris. Introduksjon. Skrevet av: Kine Gjerstad Eide. Lag starten på ditt eget tetris spill!

Fra Python til Java, del 2

Mattespill Nybegynner Python PDF

Verden. Introduksjon. Skrevet av: Kine Gjerstad Eide og Ruben Gjerstad Eide

Quicksort. Fra idé til algoritme.

ToPlayer. Steg 1: Kom i gang med metodene setup og draw. Gjør dette: Introduksjon:

INF1010 Binære søketrær ++

Hvorfor sortering og søking? Søking og sortering. Binære søketrær. Ordnet innsetting forbereder for mer effektiv søking og sortering INF1010 INF1010

Backtracking som løsningsmetode

Obligatorisk oppgave 1 INF1020 h2005

INF2440 Uke 8, v2017. Arne Maus PSE, Inst. for informatikk

Høgskolen i Gjøvik. Avdeling for elektro- og allmennfag K O N T I N U A S J O N S E K S A M E N. EKSAMENSDATO: 11. august 1995 TID:

UNIVERSITETET I OSLO

København 20 Stockholm

2 Om statiske variable/konstanter og statiske metoder.

INF2440 Uke 10, v2015 : Arne Maus PSE, Inst. for informatikk

Sudokubrettet Et sudokubrett består av n n ruter. Vi bruker følgende begreper i oppgaven:

Om plotting. Knut Mørken. 31. oktober 2003

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

EKSAMEN. Dato: 28. mai 2018 Eksamenstid: 09:00 13:00

INF1510 Oblig #1. Kjetil Heen, februar 2016

Transkript:

Oblig3 i INF2440 våren 2015-ver3. Den konvekse innhyllinga til en punktmengde - et rekursivt geometrisk problem. Innleveringsfrist fredag 27. mars kl. 23.59 En punktmengde P i planet består av n forskjellige punkter p i (i =0,1,2,,n-1) med heltalls-koordinater og vi kan anta at ikke alle punktene ligger på én og samme linje. Den konvekse innhyllinga til denne punktmengden er en mangekant (et polygon) med linjer mellom noen av disse punktene slik at alle de andre punktene er på innsiden av denne mangekanten og også slik at alle indre vinklene i denne mangekanten er 180 sagt litt enklere : det er ingen innoverbulker på dette sett av linjer rundt punktmengden (fig1). Fig1. Den konvekse innhyllinga av 100 tilfeldige punkter i planet (de samme som nyttes i oppgaven.) Når vi noterer en slik konveks innhylling, starter vi med et vilkårlig av punktene i innhyllinga, og nevner punktene i rekkefølge mot klokka. I figur 1 kan det være: 16,55, 23, 50, 31, 60, 73, 5, 93, 95, 65, 1, 80, 78, 48, 94, 10, 99. Legg merke til at hvis det er flere punkter på en linje (her f.eks 31, 60, 73, 5, 93 og 95), så skal alle disse punktene med på innhyllinga. Det er altså ikke lov å gå rett fra 31 til 95, vi må spesifisere alle linjene 31-60, 60-73, 73-5, 5-93 og 93-95; ikke hoppe over noen av tallene mellom.

Hvordan finner vi innhyllinga av n punkter? Vi ser at følgende to punkter opplagt er på innhyllinga det med minst x-verdi og det med størst x- verdi. Er det flere med denne samme minste eller største x-verdi, velger man bare en av de største og en av de med minst x-verdi (i eksempelet f.eks. 16 og 5). Resten av algoritmen baserer seg på en enkel geometrisk sats. Ligningen for en linje Enhver linje fra et punkt p1 (x1,y1) til p2(x2,y2) kan skrives på formen: aaaa + bbbb + cc = 0 Hvor: aa = yy1 yy2, bb = xx2 xx1 oooo cc = yy2 xx1 yy1 xx2. Merk at dette er en rettet linje fra p1 til p2. Figur2. En linje fra p1 (1,2) til p2(7,4) har da linjeligningen: (2 4)xx + (7 1)yy + (4 1 2 7) = 0; dddddd: 2xx + 6yy 10 = 0 Linjeligningen betyr at alle punkter på denne linja passer inn i formelen; setter vi x og y til ethvert punkt på denne linja får vi 0 som svar. Denne linja kan vi også si deler planet i to de punkter som er på venstre side sett i retningen på linja: fra p1 til p2, og de som på høyre side i retningen fra p1 til p2. Avstanden til linja fra andre punkter. Setter vi inn punkter som ikke er på linja p1-p2, ser vi at alle punkter, eks. p3(5,1) på høyre side av linja gir et tall < 0 innsatt i linjeligninga: aaaa + bbbb + cc, og alle punkter til venstre for linja, som p4(3,6), gir et tall >0. Jo lenger fra linja punktene er, desto større negative og positive tall blir det. Generelt er det slik at avstanden vinkelrett ned fra et punkt p(x,y) til en linje: aaaa + bbbb + cc er: aaaa + bbbb + cc dd = aa 2 + bb 2

Fig3. Avstanden fra et punkt til en linje. Linja deler planet i to: de med negativ avstand (til høyre) og de med positiv avstand (til venstre) fra linja. Vi ser på to punkter i fig 3: p3(5,1) og p4(3,6), finner at avstanden fra p4 til linja p1-p2 er: 2 3+6 6 10 = 20 2 5+6 1 10 = 3,16.., mens avstanden fra p3(5,1) til p1-p2 er: = 14 = 2,21.. ( 2) 2 +6 2 40 40 6,32 Algoritmen for den konvekse innhyllinga Vi kan nå formulere algoritmen for den konvekse innhylling etter å ha gjort én observasjon til: - Det punktet som har lengst negativ avstand fra en linje pi-pj, er selv et punkt på den konvekse innhyllinga (se fig 4 punktet P og linja I - A)). Algoritme: Fig.4. Starten på å finne innhyllinga fra maxx (I) til minx (A). 1. Trekk linja mellom de to punktene vi vet er på innhyllinga fra maxx -minx (I - A i fig4). 2. Finn det punktet med størst negativ (eller 0) avstand fra linja (i fig 4 er det P). Har flere punkter samme avstand, velger vi bare ett av dem. 3. Trekk linja fra de to punktene på linja til dette nye punktet på innhyllinga (i fig5: I-P og P-A).

4. Fortsett rekursivt ut fra de to nye linjene og finn da for hver av disse linjene et nytt punkt på innhyllinga i størst ikke-positiv avstand ( 0). 5. Gjenta pkt. 3 og 4 inntil det ikke er flere punkter på utsida av disse linjene. 6. Gjenta steg 2-4 for linja minx-maxx, og finn alle punkter på innhyllinga under denne. I figur 5 (neste side) er denne prosessen illustrert. Her er illustrasjonen på å finne punktene på innhyllinga over linja I-A. Du kan forvente å finne om lag 1.4* nn elementer i den konvekse innhyllinga av n tilfeldig valgte punkter i planet, men alle verdier fra 3 til n er mulig (vi får n hvis alle punktene er på en sirkel). Fig 5. Vi finner rekursivt punktet P på innhyllinga fra linja I-A (det med størst negativ avstand fra maxx-minx), så C fra P-I, R fra I-C og til sist Q fra I-R. Denne rekursive algoritmen skal du altså programmere først sekvensielt og så lage en parallell versjon av og finne speedup for når n=100, 1000, 10 000,,10 mill. Om å generere n ulike punkter. a) Datastrukturen din for n punkter skal være to int-arrayer x og y, hver n lange: int []x = new int[n], y = new int[n]; For å fylle disse arrayene med x- og y-verdier som ikke gir to like punkter, skal du bruke den ferdigkonstruerte klassen NPunkter som du finner i mappa til Oblig3. b) For hver verdi av n du skal ha i programmet ditt, skal du først lage et objekt av klassen NPunkter : NPunkter p = new NPunkter(n); og så fylle x[] og y[] arrayene dine ved et kall på metoden i objektet p: p.fyllarrayer(int [] x, int [] y); Grunnen til at skal bruke denne klassen, som du heller ikke skal endre på, er at alle besvarelsene for en gitt n skal ha de samme punktene. Da vil det bli mye lettere for gruppelærerne å rette obligene (det er heller ikke helt lett å relativt raskt generere opp til 10 mill. tilfeldige punkter som man er sikker på alle er ulike, men denne oppgaven er altså ikke en del av Oblig 3). c) Denne generering av n punkter skal ikke inkluderes i tidtakingen.

Effektivitet: a) Du er egentlig ikke er interessert i den virkelige avstanden for et punkt til en linje, men bare et mål for denne avstanden hvor den som har størst tall vinner. Formelen for avstanden d kan da forenkles. b) Det vil ta lenger tid hvis du hver gang må gå gjennom hele punktmengden P for å finne de få punktene som er på utsida av en linje. Du skal derfor la programmet teste på stadig mindre punktmengder. c) Husk at du ikke ukritisk bare bruker tråder istedenfor rekursjon (tenk om lag som for Quicksort). Tråder skal bare brukes i toppen av rekursjonstreet. d) Er ArrayList <Integer> rask nok til å holde til dels store punktmengder, eller bør du lage en egen klasse IntList med de samme metodene du trenger og hvor de heltallene du skal lagre ligger i en enkel heltallsarray (jfr. Ukeoppgavene Uke9)? Krav til innleveringa. Oblig 3 leveres i Devilry innen fredag 27. mars kl. 23.59. I leveransen skal du ha: a) Koden både for den sekvensielle og parallelle løsningen. b) En utskrift på den konvekse innhyllinga for n=1000. c) En rapport med både en tabell og en kurve som viser speedup som funksjon av n (= 100, 1000,., 10 mill ) og din vurdering på hvorfor kjøretidene blir så lave som de blir, og om hvorfor du får den speedup du får. Ta med data om den maskinen du har kjørt testene på (modell-betegnelse, klokkefrekvens, antall kjerner) og hovedhukommelsens størrelse, og om mulig: cachenes størrelse og forsinkelse (kjør programmet latency.exe hvis du er på en Windows-maskin) og gjerne med en tegning fra TegnUt av tilfellet n=100. Tips. Dette er noe du ikke behøver å følge, men gir tips på ulike punkter hvor du kan få problemer: I) Den sekvensielle løsningen a) Hvordan representere et punkt. Bruk indeksen i x[] og y[] innholdet av disse endrer seg ikke under kjøring; de bare leses. b) Debugging Svært få, om noen, greier å få riktig kode første gang. Vi trenger å feilrette koden, og på et grafisk problem som dette, vil være greit å få tegnet ut punktene for et lite eksempel og den innhyllinga man etterhvert finner. Hvis dere ikke vil bruke en egen tegnepakke, kan dere bruke klassen TegnUt slik fra mainklassen (for eksempler hvor n <200) slik: TegnUt tu = new TegnUt (this, kohyll); Første linje er for å få tegnet ut punktene og den konvekse innhyllinga som forventes å være lagt inn i en IntList kohyll (en triviell forenkling av ArrayList <Integer> -se ukeoppgave 9). c) Finne punktene på den konvekse innhyllinga i riktig rekkefølge. Tips: Du bruker to metoder for det sekvensielle tilfellet (antar her at du bruker ArrayList, men denne kan trivielt byttes ut med en raskere IntList hvis du lager en slik):

sekvmetode() som finner minx, maxx og starter rekursjonen. Starter du på maxx-minx, legges maxx inn i lista med innhyllinga (men ikke minx enda), og starter rekursjonen med to kall på den rekursive metoden: sekvrek (int p2, int p2, int p3, ArrayList <Integer> m, ArrayList <Integer> kohyll ) som får en mengde punkter m, som inneholder alle punktene som ligger på eller under linja p1-p2, og p3 er allerede funnet som det det med størst negativ avstand fra p1-p2. kohyll er mengden hvor du skal notere punktene på den konvekse innhyllinga du finner i riktig rekkefølge. Merk at du først tar rekursjon først på høyre del (linja I-P, fig. 5) og så på venstre del(linja P-A) fordi vi vil ha punktene i rekkefølge notert mot klokka. Du kan la hvert kall på sekvrek legge inn ett punkt: p3 i innhyllinga-lista, men hvor i koden er det? Når legges minx inn i innhyllingslista? d) Få med alle punktene på innhyllinga hvor flere/mange ligger på samme linje (avstand = 0) som i høyre kant i fig. 6, og i riktig rekkefølge. Husk at når du finner at største negative avstand =0,må du ikke inkluderer p1 eller p2 som mulig nytt punkt (de er allerede funnet) Si at du har funnet p1=31 og p2=5 i fig. Du bør da bare være interessert i å finne de punktene som ligger mellom p1 og p2 på linja (60 og 73), og da må du teste om nytt punkt p3 har både y og x- koordinater mellom tilsvarende koordinater for p1 og p2. Da finner du ett av punktene med kall på sekrek over linja p1-p2 (31-5). Gjenta rekursivt til det ikke lenger er noen punkter mellom nye p1 og p2. Punktene videre oppetter linja (f.eks. 5-95) finnes av rekursjon tilsvarende som for 60 og 73. Fig 6. Mange punkter med samme avstand =0

II) Den parallelle løsningen a) Du kan/bør ikke bruke Model2-koden direkte, men dele det parallelle tilfellet også opp i to metoder. Den første parallell-kalles fra main-tråden (mellom de to setningene der du tar tiden på det parallelle tilfellet). Den finner først ut hvor langt ned i kalltreet vi skal bruke tråder. Har vi k kjerner i maskinen, kan det være fornuftig å gå ned til et lag i kalltreet hvor det er om lag k noder på tvers av treet. Eksempel: har vi 8 kjerner, og kaller toppen i treet for nivå1, vil nivå4 ha 8 noder. Inntil dette nivået vi da nye tråder erstatte rekursive kall, på etterfølgende nivåer brukes så vanlig rekursive kall fra hver av de trådene vi har startet. b) Den første parallelle metoden som kalles fra og kjører på main-tråden, lager altså to tråder. De etterfølgende trådene startes fra disse to trådene og deres etterkommer -tråder. Disse startes av den andre parallelle metoden, som kalles fra run()-metodene. c) Den andre parallelle metoden har de samme parametere som tilsvarende sekvensielle:p1,p2,p3, og søkemengden, og i tillegg to til: nivået i treet og mengden (IntArray) av punkter på innhyllingen som denne tråden hittil har funnet. d) I den andre parallelle, rekursive metoden avgjøres det så om vi skal fortsette å lage tråder eller om det er rekursjon som nå gjelder. Før det, har vi funnet punktet som ligger i mest negativ avstand og søkemengden for neste kall (=de punktene som er negative satt inn i linja fra p1-p2) og vi har også deklarert og generert to mengder, en til hver av de to rekursjonene (IntList eller ArrayList<Integer>) som skal holde den konkvekse innhyllinga dette kaller finner. e) Denne metoden minner sterkt om den tilsvarende sekvensielle metoden, og etter at vi har kommet ned på det nivået hvor vi ikke lager nye tråder lenger, kan vi faktisk bruke den sekvensielle rekursive metoden her. f) Husk at når vi starter tråder så må vi først skape begge, og så etterpå legge oss å vente (f.eks. med join()) på dem. Ellers blir det ikke parallellitet. Finne punktene på den konvekse innhyllinga i den parallelle løsningen i riktig rekkefølge. Vi får imidlertid et ekstra problem, mens man i den sekvensielle løsningen kan få punktene på innhyllinga i riktig rekkefølge ved å legge dem inn riktig rekkefølge (ett punkt per rekursivt kall), kommer punktene i en parallell løsning fra ulike tråder og i uforutsigbar rekkefølge. En måte å løse dette på er å bruke: 1. Trådene startes i toppen av rekursjonstreet bare ned til et visst nivå for alle nodene i treet (nivået er som sagt avhengig av hvor mange kjerner vi har).. 2. Etter at det ikke startes flere nye tråder, vil hver tråd gå over til den sekvensielle løsningen (på sin del av data). 3. Fra hver av disse sekvensielle utførelsene får vi punktene i riktig rekkefølge (mot klokka). 4. Problemet er da å skjøte sammen disse riktige små -delene av innhyllinga (+ de få punktene som finnes av trådene i toppen av rekursjonstreet) om lag slik: Først det høyretråden har produsert, så det punktet noden selv finner, så venstre-trådens punkter. 5. Punkt 4 gjøres så (på tilbaketrekking etter å ha funnet sine punkter) oppover til vi kommer til toppen og er ferdig.