Algoritmer og datastrukturer Kapittel 2 - Delkapittel 2.2

Like dokumenter
Algoritmer og datastrukturer Kapittel 2 - Delkapittel 2.1

Algoritmer og datastrukturer Kapittel 9 - Delkapittel 9.2

Algoritmer og datastrukturer Kapittel 3 - Delkapittel 3.1

Algoritmer og datastrukturer Kapittel 4 - Delkapittel 4.4

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

Algoritmer og datastrukturer Kapittel 1 - Delkapittel 1.8

Algoritmer og datastrukturer Kapittel 9 - Delkapittel 9.1

Algoritmer og datastrukturer E Løkker i Java

Algoritmer og datastrukturer Eksamen

Algoritmer og datastrukturer Kapittel 9 - Delkapittel 9.2

G høgskolen i oslo. Emne: Algoritmer og datastrukturer. Emnekode: 80131A. Faglig veileder: UlfUttersrud. Gruppe(r) : Dato:

To geometriske algoritmer, kap. 8.6

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

Algoritmer og datastrukturer Løsningsforslag

Algoritmer og datastrukturer Kapittel 4 - Delkapittel 4.3

Ny/utsatt EKSAMEN. Dato: 5. januar 2018 Eksamenstid: 09:00 13:00

Algoritmer og datastrukturer Eksamen 22. februar 2011

Algoritmer og datastrukturer Kapittel 1 - Delkapittel 1.3

Algoritmer og datastrukturer Eksamen

Algoritmer og datastrukturer Kapittel 11 - Delkapittel 11.2

Algoritmer og datastrukturer Kapittel 1 - Delkapittel 1.3

Algoritmer og datastrukturer Eksamen

Algoritmer og datastrukturer Løsningsforslag

Algoritmer og datastrukturer Vedlegg A.2 BitOutputStream

Algoritmer og datastrukturer Eksamen

Algoritmer og datastrukturer A.1 BitInputStream

Algoritmer og Datastrukturer

Kap.8 Sortering og søking sist oppdatert 16.03

Oppgave 3 a. Antagelser i oppgaveteksten. INF1020 Algoritmer og datastrukturer. Oppgave 3. Eksempelgraf

Algoritmer og datastrukturer Kapittel 9 Delkapittel 9.2

Fagnr: A. Ant. vedlegg: 1 (2 sider)

Emnekode: I-Dato: I ~ Antall oppgaver: I I Aiie -sk:i=rftlige - bme trykte og håndskrevne, samt alle typer

Fagnr: A. Ant. vedlegg: 1 (2 sider)

~ta11 oppgaver: 4. Nle skriftlige hjelpemidler-både trykte og håndskrevne, er tillatt

Det finnes ingenting. som kan gjøres med interface. men som ikke kan gjøres uten

EKSAMEN. Algoritmer og datastrukturer

Binære søketrær. Et notat for INF1010 Stein Michael Storleer 16. mai 2013

INF1010 notat: Binærsøking og quicksort

EKSAMEN. Dato: 9. mai 2016 Eksamenstid: 09:00 13:00

Algoritmer og Datastrukturer

EKSAMEN med løsningsforslag

Fagnr: SO 131 A. Ant. vedlegg: 1 (2 sider)

EKSAMEN. Emne: Algoritmer og datastrukturer

Algoritmer og Datastrukturer

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

INF2220: Forelesning 1. Praktisk informasjon Analyse av algoritmer (kapittel 2) (Binær)trær (kapittel )

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

TOD063 Datastrukturer og algoritmer

Gjøre noe i hele treet = kalle på samme metode i alle objekten. Java datastruktur Klassestruktur

Algoritmer og datastrukturer Løsningsforslag

Algoritmer og datastrukturer Eksamen

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

PG4200 Algoritmer og datastrukturer Forelesning 5 Implementasjon av lister

Algoritmer og datastrukturer Løsningsforslag

Eks 1: Binærtre Binærtretraversering Eks 2: Binærtre og stakk

Fra Kap.10 Binære søketre (BS-tre) Sist oppdatert Definere en abstrakt datastruktur binært søketre. Vise hvordan binær søketre kan brukes

Kapittel 8: Sortering og søking

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

Lenkelister, iteratorer, indre klasser. Repetisjonskurs våren 2018 kristijb

Algoritmer og datastrukturer A.1 Filbehandling på bit-nivå

Oppgavesettet består av 7 sider, inkludert denne forsiden. Kontroll& at oppgaven er komplett før du begynner å besvare spørsmålene.

Løsningsforslag. Oppgave 1.1. Oppgave 1.2

INF1010 LISTER. Listeelementer og listeoperasjoner. Foran. Bak

Kapittel 9: Sortering og søking Kort versjon

Kapittel 9: Sortering og søking Kort versjon

Kapittel 9: Sortering og søking Kort versjon

Løsningsforslag Test 2

Sist gang (1) IT1101 Informatikk basisfag. Sist gang (2) Oppgave: Lenket liste (fysisk) Hva menes med konseptuelt og fysisk i forb med datastrukturer?

INF110 Algoritmer og datastrukturer TRÆR. Vi skal i denne forelesningen se litt på ulike typer trær:

b) 17 går ikke opp i 84 siden vi får en rest på 16 når 84 deles med 17 c) 17 går opp i 357 siden

En implementasjon av binærtre. Dagens tema. Klassestruktur hovedstruktur abstract class BTnode {}

En algoritme for permutasjonsgenerering

NIO 1. runde eksempeloppgaver

Algoritmer og Datastrukturer

INF-MAT5370. Trianguleringer i planet (Preliminaries)

Definisjon: Et sortert tre

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

UNIVERSITETET I OSLO

PRIORITETSKØ. Aksjehandel. Datastruktur for aksjehandel. Nøkler og Totalorden-relasjonen

Algoritmer og datastrukturer Kapittel 4 Delkapittel 4.2

Oppgave 1. Løsningsforslag til eksamensoppgave. ITF20006 Algoritmer og datastrukturer Postorden traversering:

UNIVERSITETET I OSLO

Algoritmer og Datastrukturer

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

Norsk informatikkolympiade runde

Definisjon av binært søketre

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

Algoritmer og datastrukturer Kapittel 11 Delkapittel 11.2

Liste som abstrakt konsept/datatype

Kapittel 8: Sortering og søking INF100

OPPGAVE 1 OBLIGATORISKE OPPGAVER (OBLIG 1) (1) Uten å selv implementere og kjøre koden under, hva skriver koden ut til konsollen?

Kapittel 8: Sortering og søking INF100

UNIVERSITETET I OSLO

Grunnleggende Datastrukturer

Hva er en algoritme? INF HØSTEN 2006 INF1020. Kursansvarlige Ragnar Normann E-post: Dagens tema

Quicksort. Fra idé til algoritme.

Sortering med Comparable og Comparator

Dagens temaer. Sortering: 4 metoder Søking: binærsøk Rekursjon: Hanois tårn

INF1010 Sortering. Marit Nybakken 1. mars 2004

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister

Transkript:

Delkapittel 2.2 Konvekse polygoner Side 1 av 7 Algoritmer og datastrukturer Kapittel 2 - Delkapittel 2.2 2.2 Konvekse polygoner 2.2.1 Konveksitet La p 0, p 1, p 2....., p n-1 være en samling på n punkter i xy-planet. Den konvekse innhylningen H (engelsk: the convex hull) til disse punktene er den minste konvekse mengden som omfatter alle punktene, og det konvekse polygonet er randen eller kanten til H. Litt uformelt kan vi si at det konvekse polygonet er det polygonet vi får ved kun å ta med punktene i «ytterkant». Til venstre er det konvekse polygonet for de 10 punktene p 0, p 1,..... p 9 tegnet inn. Figur 2.2.1 a): Konvekst polygon Vi ser at hvert punkt enten ligger på selve polygonet eller det ligger inne i polygonet. I tillegg ser vi at alle de indre vinklene i polygonet er mindre enn 180 grader. Det å finne det konvekse polygonet til en samling punkter er et viktig problem i plangeometri. Da holder det selvfølgelig å finne de punktene som utgjør hjørnene i polygonet. Noen slike hjørner kan vi fort finne. I avsnitt 1.4.5 så vi på hvordan punkter kunne ordnes leksiografisk. Da kunne vi enten ordne med hensyn på x-koordinaten først, og så med hensyn på y- koordinaten, eller eventuelt omvendt. Hvis vi velger det minste og største punktet med hensyn på begge de to leksiografiske ordningene, så får vi hjørnepunkter. I figur 2.2.1 a) over ville vi på denne måten ha fått hjørnepunktene p 6, p 3, p 0 og p 4. I figur 2.2.1 b) nedenfor ville det ha blitt p 5, p 7, p 6 og p 1. Det er p 7 og ikke p 8, som er størst. De har samme x- koordinat, og da er det størst som har størst y-koordinat. Eksempel 1 Flg. 10 punkter er gitt: (3,3), (5,6), (6,3), (2,5), (6,5), (1,2), (4,1), (7,4), (7,2) og (4,4). Vi nummererer punktene fra 0 til 9. Det første punktet kaller vi p 0, det neste p 1, osv. Til venstre, i figur 2.2.1 b), har vi plottet punktene. I avsnitt 1.4.5 laget vi en komparator som var basert på en leksiografisk ordning. Den var laget slik at vi først ordnet etter x- koordinaten, og så etter y-koordinaten. Figur 2.2.1 b): Et koordinatsystem Koden for class XkoordinatKomparator satt opp på nytt nedenfor. Den brukes et program som finner minste og største punkt mhp. komparatoren. Et punkt lager vi ved hjelp av class Point fra java.awt.

Delkapittel 2.2 Konvekse polygoner Side 2 av 7 public class XkoordinatKomparator implements Comparator, Serializable public int compare(object o1, Object o2) Point p1 = (Point)o1; // gjør om fra Object til Point Point p2 = (Point)o2; // gjør om fra Object til Point if (p1.x < p2.x) return -1; // p1 har minst x-koordinat if (p1.x > p2.x) return 1; // p1 har størst x-koordinat // Nå har p1 og p2 like x-koordinater if (p1.y < p2.y) return -1; // p1 har minst y-koordinat if (p1.y > p2.y) return 1; // p1 har størst y-koordinat return 0; // class XkoordinatKomparator Programkode 2.2.1 a) I utgangspunktet er punktene representert ved hjelp av to heltallstabeller, en tabell for x- koordinater og en for y-koordinater: int[] x = 3,5,6,2,6,1,4,7,7,4; int[] y = 3,6,3,5,5,2,1,4,2,4; Point[] p = new Point[x.length]; // en punkt-tabell for (int i = 0; i < p.length; i++) p[i] = new Point(x[i],y[i]); Comparator c = new XkoordinatKomparator(); Point a = p[tabell.min(p,0,p.length,c)]; // finner minste Point b = p[tabell.maks(p,0,p.length,c)]; // finner største System.out.println("(" + a.x + "," + a.y + ") er minst"); System.out.println("(" + b.x + "," + b.y + ") er størst"); Programkode 2.2.1 a) Vi forutsetter her at det finnes to generisk metoder min og maks som tar en tabell, et fra/til interval og en komparator som parametere. I tillegg antas det at disse metodene ligger som statiske metoder i class Tabell. 2.2.2 Innpakkingsmetoden Innpakkingsmetoden (engelsk: the gift wrapping algorithm) kalles også Jarvis' marsj (engelsk: Jarvis' march) etter R.A.Jarvis som lanserte den i 1973. Det er en metode som finner de punktene i en punktsamling som utgjør hjørnene i det konvekse polygonet. Metoden starter med at vi finner et hjørnepunkt og vi kaller det et ankerpunkt. Vi så i avsnitt 2.2.1 at vi lett kan finne et hjørnepunkt ved å bruke en leksiografisk ordning av punktene. Vi tenker oss så at det i hvert punkt står en loddrett pinne (loddrett på xy-planet). En lang tråd festes i ankerpunktets pinne og holdes stram på en slik måte at alle de andre punktene/pinnene ligger på den ene siden av tråden. Så roterer vi tråden mot punktmengden mens den holdes stram. De punktene/pinnene som tråden fortløpende treffer er hjørner i det

Delkapittel 2.2 Konvekse polygoner Side 3 av 7 konvekse polygonet. Vi roterer til vi har kommet helt rundt punktmengden og tilbake til ankerpunktet. Vi tar utgangspunkt i figur 2.2.2 a). Der velger vi punktet med minst x-koordinat som ankerpunkt. Det er p 5 = (1,2). Figur 2.2.2 a): Innpakkingsmetoden gjenspeiler denne ordningen: Deretter skal vi finne det største punktet med hensyn på en bestemt ordning. Gitt to punkter p og q som begge er forskjellige fra ankerpunktet a. Vi sier at p er mindre enn q mhp. a hvis p ligger på høyre side av den rette linjen som går gjennom a og q, orientert fra a til q, eller p ligger på denne linjen mellom a og q. Vi lager en komparator som public class AnkerpunktKomparator implements Comparator, Serializable private Point a; // et ankerpunkt public AnkerpunktKomparator(Point ankerpunkt) a = ankerpunkt; public int compare(object o1, Object o2) Point p = (Point)o1; // gjør om o1 til Point Point q = (Point)o2; // gjør om o2 til Point int d = (q.x - a.x)*(p.y - a.y) - (q.y - a.y)*(p.x - a.x); if (d!= 0) return d; return (q.x - a.x)*(p.x - q.x) + (q.y - a.y)*(p.y - q.y); // AnkerpunktKomparator Programkode 2.2.2 a) Det er a = p 5 = (1,2) som er ankerpunkt. Hva er det største punktet blant resten mhp. vår nye ordning? Det er det punktet p k som er slik at når vi trekker en rett linje gjennom p 5 og p k, vil alle de andre punktene ligge til høyre for linjen, eller eventuelt på linjen fra p 5 og p k. Vi ser at det må være p 3 som dermed blir det nye ankerpunktet. Linjestykket fra p 5 til p 3 blir en kant i det konvekse polygonet. Vi finner så det største, mhp. p 3, av resten av punktene. Det må være p 1 siden resten av punktene ligger på høyre side av den rette linjen gjennom p 3 og p 1. Punktet p 1 blir dermed nytt ankerpunkt for den videre søkingen. Linjestykket fra p 3 til p 1 blir en kant i det konvekse polygonet. Se figur 2.2.2 b). Vi finner så det største mhp. p 1, av resten av punktene. Det er p 7 og ikke p 4. Den måten vi har definert «større enn» mhp. p 1 gjør at p 7 er «større enn» p 4.

Delkapittel 2.2 Konvekse polygoner Side 4 av 7 Det neste punktene vi finner på denne måten er p 8 og p 6. Dermed er vi ferdige. Se figur 2.2.2 c) og figur 2.2.2 d). Dermed fant vi flg. hjørnepunkter: p 5, p 3, p 1, p 7, p 8 og p 6. Figur 2.2.2 b): Innpakkingsmetoden Figur 2.2.2 c): Avslutningen av innpakkingsmetoden Et problem som vi har underslått i diskusjonen ovenfor er hvordan algoritmen skal stoppe. Det må bli når vi kommer tilbake til ankerpunktet vi startet med. Ved ombytting legger vi startpunktet bakerst. Dermed deltar punktet under letingen etter nye "maks-punkter". int[] x = 3,5,6,2,6,1,4,7,7,4; int[] y = 3,6,3,5,5,2,1,4,2,4; int n = x.length; // for å forenkle notasjonen Point[] p = new Point[n]; // en punkt-tabell for (int i = 0; i < n; i++) p[i] = new Point(x[i],y[i]); // Finner et startpunkt, f.eks. det minste punktet m.h.p // XkoordinatKomparatoren. Det blir punktet lengst ned til venstre. // Ved en ombytting legger vi punktet bakerst - i posisjon n-1. Tabell.bytt(p,n-1,Tabell.min(p,0,n,new XkoordinatKomparator())); // Finner det neste hjørnepunktet, d.v.s. det største punktet // mhp. startpunktet og legger det først - i posisjon 0.

Delkapittel 2.2 Konvekse polygoner Side 5 av 7 Tabell.bytt(p,0,Tabell.maks(p,0,n-1,new AnkerpunktKomparator(p[n-1]))); // Finner nye hjørner inntil vi er tilbake til startpunktet int k = 1; for ( ; k < n; k++) int m = Tabell.maks(p,k,n,new AnkerpunktKomparator(p[k-1])); Tabell.bytt(p,k,m); if (m == n-1) break; // vi har kommet rundt // hjørnepunktene ligger nå i p[0:k] for (int i = 0; i <= k; i++) System.out.println(p[i]); Programkode 2.2.2 b) 2.2.3 Graham's scan Graham's scan er oppkalt etter R.L. Graham som lanserte denne metoden i 1972. Første skritt i algoritmen er å finne et ankerpunkt. Deretter sorteres punktene mhp. ankerpunktet. Koden for dette er svært enkel. Under sorteringen bruker vi her innsettingssortering, men senere, når vi har utviklet mer avanserte sorteringsmetoder, vil vi naturligvis bruke dem isteden. Vi antar at innsettingssortering ligger i class Tabell og har tre parametere - en tabell, en dimensjon og en komparator. int[] x = 3,5,6,2,6,1,4,7,7,4; int[] y = 3,6,3,5,5,2,1,4,2,4; int n = x.length; // for å forenkle notasjonen Point[] p = new Point[n]; // en punkt-tabell // legger inn x- og y-verdiene for (int i = 0; i < n; i++) p[i] = new Point(x[i],y[i]); Comparator c = new PunktKomparator(); // leksiografisk komparator // f.eks. minst etter leksiografisk ordning blir et ankerpunkt Point a = new Point(p[Tabell.min(p,0,n,c)]); // sorterer mhp. ankerpunktet - her kan en selvfølgelig // bruke en annen sorteringsmetode Tabell.innsettingssortering(p,new AnkerpunktKomparator(a)); // skriver ut punktene i sortert rekkefølge for (int i = 0; i < n; i++) System.out.println(p[i]); Programkode 2.2.3 a) I Programkode 2.2.3 a) har vi for eksemplets skyld valgt de 10 punktene (3,3), (5,6), (6,3), (2,5), (6,5), (1,2), (4,1), (7,4), (7,2) og (4,4), og de er tegnet inn i den samme rekkefølgen i Figur 2.2.3 a). Ankerpunktet som velges blir p 5 = (1,2). Stigende sortering mhp. p 5 gir rekkefølgen: (1,2), (4,1), (7,2), (6,3), (7,4), (3,3), (6,5), (4,4), (5,6) og (2,5).

Delkapittel 2.2 Konvekse polygoner Side 6 av 7 Dette kan også ses på som en ordning med stigende vinkel. På Figur 2.2.3 a) er det trukket en linje fra ankerpunktet til de andre punktene. Der ser vi hvor store vinklene er. Lag et program som kjører Programkode 2.2.3 a) og sjekk at utskriften blir som påstått! På figur 2.2.3 b) har vi døpt om punktene slik at de nå er nummerert etter sin sorterte rekkefølge. Figur 2.2.3 a): Punktsortering Neste skritt i Graham's scan er å traversere og fortløpende tegne kanter i punktrekkefølgen. Vi trekker en kant fra p 0 til p 1, så en fra p 1 til p 2, osv. Så lenge som vi under denne traverseringen beveger oss mot klokken, så fortsetter vi. Første gang det går galt er når vi går fra p 3 til p 4. Da har vi "snudd oss" med klokken. Vi går da to posisjoner bakover - tilbake til p 2, hopper så over p 3, og går rett til p 4. Fra p 4 polygonet. Figur 2.2.3 b): Starten på Graham's scan går vi videre til p 5. Når vi så går videre til p 6 gjør vi en sving med klokken. Se figur 2.2.3 c). Dermed må vi trekke oss to posisjoner bakover - tilbake til p 4, hopper så over p 5 og går rett til p 6. Vi får samme problemet på nytt når vi går fra p 7 til p 8. Dermed hopper vi over p 7, går rett til p 8, videre til p 9 og til slutt til p 0. Vi har funnet det konvekse Det vil være situsjoner der det ikke er nok å trekke seg to posisjoner bakover. Det vi gjør er at for hver posisjon vi trekker oss bakover til, undersøker vi om vi får reist mot klokken ved å gå videre derfra direkte til det punktet der vi oppdaget at vi hadde gått med klokken. Figur 2.2.3 c): Starten på Graham's scan Dette er ikke så vanskelig å få implementert. Vi trenger kun en enkel måte å kunne "trekke oss bakover". Det gjør vi ved fortløpende å legge de punktene vi besøker på en stakk (engelsk: stack). En stakk er en datastruktur der det vi sist la inn er det vi først får tatt ut. Datastrukturen stakk blir diskutert i kapitlet Stakker, køer og prioritetskøer. Vi tar utgangspunkt i programkode 2.2.3 a) og fortsetter der vi sluttet:

Delkapittel 2.2 Konvekse polygoner Side 7 av 7 Stack s = new Stack(); // Denne henter vi fra java.util // legger de tre første punktene på stakken s.push(p[0]); s.push(p[1]); s.push(p[2]); Point b, p1, p2; // hjelpevariabler Comparator bc; // en komparator for (int i = 3; i < n; i++) p2 = p[i]; while (true) p1 = (Point)s.pop(); // tar fra stakken b = (Point)s.peek(); // ser på den øverste bc = new AnkerpunktKomparator(b); if (bc.compare(p2,p1) > 0) // ingen med klokken "knekk" - legger p1 tilbake s.push(p1); break; s.push(p2); // legger p2 på stakken // Skriver ut hjørnepunktene while (!s.empty()) p1 = (Point)s.pop(); System.out.println("(" + p1.x + "," + p1.y +")"); Programkode 2.2.3 b) Copyright Ulf Uttersrud, 2009. All rights reserved.