www.wikidata.de-de.nina.az
Das Problem des dichtesten Punktpaares englisch closest pair of points problem ist die Suche nach den zwei am dichtesten beieinander liegenden Punkten in einer Ebene Gegeben ist eine beliebige Menge von Punkten in der Ebene und gesucht sind zwei dieser Punkte sodass der euklidische Abstand minimal ist Ein ahnliches Problem ist die Suche nach den zwei am weitesten voneinander entfernten Punkten in der Ebene also den zwei Punkten mit dem maximalen euklidischen Abstand Inhaltsverzeichnis 1 Kleinster Abstand von Punkten in der Ebene 1 1 Brute force Algorithmus 1 2 Divide and conquer Algorithmus 1 3 Programmierung 1 4 Randomisierter Algorithmus 1 4 1 Funktionsweise 1 4 2 Gitterstruktur und Hashfunktion 1 4 3 Einfugen neuer Punkte 1 4 4 Laufzeit 2 Grosster Abstand von Punkten in der Ebene 2 1 Rotating calipers Algorithmus 2 2 Programmierung 3 Literatur 4 EinzelnachweiseKleinster Abstand von Punkten in der Ebene BearbeitenBrute force Algorithmus Bearbeiten Der Brute force Algorithmus berechnet die Abstande zwischen allen moglichen Punktpaaren und wahlt das Punktpaar mit dem kleinsten Abstand aus Wenn n displaystyle n nbsp die Anzahl der Punkte ist gibt es n 2 n n 1 2 1 2 n 2 n displaystyle tbinom n 2 tfrac n cdot n 1 2 tfrac 1 2 cdot n 2 n nbsp mogliche Punktpaare fur die die Abstande berechnet werden mussen Die Laufzeit des Algorithmus ist also quadratisch und liegt in O n 2 displaystyle O n 2 nbsp Divide and conquer Algorithmus Bearbeiten Siehe auch Teile und herrsche Informatik Zunachst wird die gegebene Menge der Punkte einmal nach x Koordinaten und einmal nach y Koordinaten sortiert Man erhalt zwei sortierte Listen L x displaystyle L x nbsp und L y displaystyle L y nbsp Der Divide Schritt teilt die nach x Koordinaten sortierte Liste L x displaystyle L x nbsp in zwei Halften P L displaystyle P L nbsp und P R displaystyle P R nbsp links und rechts des Medians auf Der rekursive Aufruf geschieht nun jeweils fur die beiden Halften Man erhalt das jeweils dichteste Punktpaar beider Halften ohne dass eventuelle Punktpaare zwischen beiden Halften berucksichtigt werden Der Conquer Schritt kombiniert nun diese beiden Halften Es wird das Punktpaar mit dem kleinsten gefundenen Abstand ausgewahlt Hierbei sind zwei Falle zu beachten Das Punktpaar liegt in der linken oder der rechten Halfte In diesem Fall gibt es keine weiteren Probleme Es gibt zwei Punkte in unterschiedlichen Halften deren Abstand kleiner ist als der bisher in den Halften gefundene Dieser Fall ist nun gesondert zu berucksichtigen nbsp Prufung der Nachbarn von PEs ist nicht notig alle solchen Punktpaare einzeln durchzuprufen Ist d displaystyle delta nbsp der kleinste gefundene Abstand in einer der beiden Halften dann ist dies eine obere Grenze fur den kleinsten Abstand Daher mussen nur noch Punkte betrachtet werden deren Abstand zum Median in x Richtung hochstens d displaystyle delta nbsp betragt Ausserdem mussen fur diese Punkte nur noch Partner betrachtet werden deren Abstand in y Richtung kleiner als d displaystyle delta nbsp ist Daraus ergibt sich fur jeden dieser Punkte dass lediglich der Abstand zu einer konstanten Anzahl von anderen Punkten zu prufen ist Denkt man sich ein Gitter der Weite d 2 displaystyle tfrac delta 2 nbsp in der Umgebung des Medians dann kann in jeder Gitterzelle nur einer dieser Punkte liegen weil sonst bereits ein Abstand kleiner als d displaystyle delta nbsp gefunden worden ware Weil nur diejenigen Gitterzellen zu prufen sind die von P aus hochstens Abstand d displaystyle delta nbsp haben sind maximal 24 weitere Abstande fur jeden Punkt zu berechnen namlich jeweils maximal 12 Abstande nach oben und nach unten womit statt quadratischer Laufzeit nur noch lineare Laufzeit notwendig ist Insgesamt ergibt sich fur die Anzahl der berechneten Abstande die Rekursionsgleichung T n 2 T n 2 24 n displaystyle T n 2 cdot T tfrac n 2 24 cdot n nbsp sodass die Laufzeit in O n log n displaystyle O n cdot log n nbsp liegt Programmierung Bearbeiten Das folgende Computerprogramm in der Programmiersprache C zeigt eine Implementierung des Divide and conquer Algorithmus Bei der Ausfuhrung des Programms wird die Methode main verwendet die das Punktpaar und den kleinsten Abstand zwischen dem Punktpaar das auf der Konsole ausgibt 1 Die Funktion getSmallestDistanceBruteForce verwendet fur Teilbereiche aus 2 oder 3 Punkten den Brute force Algorithmus Der Conquer Schritt wird von der rekursiven Funktion getSmallestDistanceRecursive durchgefuhrt die sich selbst fur die linke Halfte und fur die rechte Halfte aufruft Die Funktion getSmallestDistanceOfStrip bestimmt das Punktpaar und den kleinsten Abstand fur den Streifen der Punkte aus beiden Halften enthalt Die Laufzeit dieser Funktion ist linear zur Anzahl der Punkte include lt iostream gt include lt sstream gt using namespace std Deklariert den Datentyp fur Punkte mit x Koordinate und y Koordinate in der Ebene struct Point int x y Vergleichsfunktion fur das Sortieren der Punkte nach der x Koordinate int compareX const void a const void b Point point1 Point a point2 Point b return point1 gt x point2 gt x Vergleichsfunktion fur das Sortieren der Punkte nach der y Koordinate int compareY const void a const void b Point point1 Point a point2 Point b return point1 gt y point2 gt y Diese Funktion berechnet den euklidischen Abstand zwischen zwei Punkten double getDistance Point point1 Point point2 return sqrt point1 x point2 x point1 x point2 x point1 y point2 y point1 y point2 y Diese Funktion gibt den kleinsten Abstand der Punkte bis zum gegebenen Index zuruck indem alle Paare von Punkten durchlaufen und gepruft werden double getSmallestDistanceBruteForce Point points Point amp point1 Point amp point2 int index double minimumDistance FLT MAX for int i 0 i lt index i for int j i 1 j lt index j Die for Schleifen durchlaufen alle Paare von Punkten double currentDistance getDistance points i points j Ruft die Funktion fur die Berechnung des euklidischen Abstands auf if currentDistance lt minimumDistance Pruft ob der Abstand zwischen den aktuellen Punkten kleiner als der bisher kleinste Abstand ist point1 points i point2 points j minimumDistance currentDistance return minimumDistance Diese Funktion gibt den kleinsten Abstand der Punkte im gegebenen Streifen zuruck wenn der Abstand kleiner als der vorgegebene Abstand ist double getSmallestDistanceOfStrip Point points Point amp point1 Point amp point2 int index double distance double minimumDistance distance Initialisiert den kleinsten Abstand qsort points index sizeof Point compareY Sortiert die Punkte nach der y Koordinate mithilfe der Vergleichsfunktion compareY for int i 0 i lt index i for int j i 1 j lt index amp amp points j y points i y lt minimumDistance j Durchlauft die Punkte so lange die Differenz der y Koordinaten kleiner als der vorgegebene Abstand ist double currentDistance getDistance points i points j Ruft die Funktion fur die Berechnung des euklidischen Abstands auf if currentDistance lt minimumDistance Pruft ob der Abstand zwischen den aktuellen Punkten kleiner als der bisher kleinste Abstand ist point1 points i point2 points j minimumDistance currentDistance return minimumDistance Diese rekursive Funktion gibt den kleinsten Abstand der Punkte zuruck Sie verwendet das Teile und herrsche Verfahren indem sie die Menge der Punkte in zwei Halften teilt und den kleinsten Abstand fur die beiden Halften und den Streifen zwischen den beiden Halften berechnet double getSmallestDistanceRecursive Point points Point amp point1 Point amp point2 int index if index lt 3 return getSmallestDistanceBruteForce points point1 point2 index Wenn das Array aus 2 oder 3 Punkten besteht wird die Brute Force Funktion aufgerufen int medianIndex index 2 Point medianPoint points medianIndex Point leftPoint1 leftPoint2 rightPoint1 rightPoint2 Deklariert Referenzen fur die Punkte mit dem kleinsten Abstand double leftDistance getSmallestDistanceRecursive points leftPoint1 leftPoint2 medianIndex Rekursiver Aufruf der Funktion fur die linke Halfte der Punkte double rightDistance getSmallestDistanceRecursive points medianIndex rightPoint1 rightPoint2 index medianIndex Rekursiver Aufruf der Funktion fur die rechte Halfte der Punkte Bestimmt den kleineren der beiden Abstande und weist die Referenzen auf die Punkte zu double distance if leftDistance lt rightDistance Wenn der Abstand in der linken Halfte kleiner ist point1 leftPoint1 point2 leftPoint2 distance leftDistance else point1 rightPoint1 point2 rightPoint2 distance rightDistance Erzeugt ein Array mit einem Streifen von Punkten auf deren x Koordinate einen kleineren Abstand hat Point stripPoints new Point index int j 0 for int i 0 i lt index i if abs points i x medianPoint x lt distance Pruft ob der Abstand der x Koordinate zwischen den aktuellen Punkten kleiner als der bisher kleinste Abstand ist stripPoints j points i j getSmallestDistanceOfStrip stripPoints point1 point2 j distance Aufruf der Funktion fur den Streifen von Punkten aus beiden Halften Wenn der Abstand in diesem Streifen kleiner ist wird dieser zuruckgegeben Diese Funktion gibt den kleinsten Abstand der Punkte und Referenzen auf die zwei Punkte mit dem kleinsten Abstand zuruck double getSmallestDistance Point points Point amp point1 Point amp point2 int numberOfPoints qsort points numberOfPoints sizeof Point compareX Sortiert die Punkte nach der x Koordinate mithilfe der Vergleichsfunktion compareX return getSmallestDistanceRecursive points point1 point2 numberOfPoints Aufruf der rekursiven Funktion Diese Funktion gibt den Punkt in der Form x y zuruck string pointToString Point point stringstream text text lt lt lt lt point gt x lt lt lt lt point gt y lt lt lt lt endl return text str Typumwandlung von stringstream nach string Hauptfunktion die das Programm ausfuhrt int main Point points 2 3 12 30 40 50 5 1 12 10 3 4 Deklariert und initialisiert ein Array mit 6 Punkten int numberOfPoints sizeof points sizeof points 0 Point point1 point2 Deklariert Referenzen fur die zwei Punkte mit dem kleinsten Abstand cout lt lt Der kleinste Abstand zwischen zwei Punkten ist lt lt getSmallestDistance points point1 point2 numberOfPoints lt lt endl Aufruf der Funktion Ausgabe auf der Konsole cout lt lt Erster Punkt lt lt pointToString amp point1 Ausgabe auf der Konsole cout lt lt Zweiter Punkt lt lt pointToString amp point2 Ausgabe auf der Konsole Randomisierter Algorithmus Bearbeiten Funktionsweise Bearbeiten Der randomisierte Algorithmus beruht darauf dass die Punkte in zufalliger Reihenfolge in eine Hashtabelle eingefugt werden wobei das Einfugen eines Punktes ebenso wie das Testen ob er den vorher bekannten minimalen Abstand d displaystyle delta nbsp unterbietet konstante Laufzeit hat Die Hashtabelle bildet alle Gitterzellen der Grosse d 2 2 displaystyle left tfrac delta 2 right 2 nbsp auf den eventuell darin liegenden Punkt ab Es muss zwar bei jeder solchen Aktualisierung von d displaystyle delta nbsp die Hashtabelle neu aufgebaut werden die Gesamtzahl der Einfugeoperationen in samtliche dieser Hashtabellen liegt aber trotzdem in O n displaystyle O n nbsp Ohne Beachtung wie die Hashtabelle konkret genutzt wird ergibt sich folgender Algorithmus Bilde eine zufallige Reihenfolge der Punkte P1 Pn d Abstand zwischen P1 und P2 Fuge P1 und P2 in die Hashtabelle ein Gittergrosse d 2 Fur i 3 n Falls Pi einen Abstand d lt d zu einem der Punkte P1 Pi 1 hat d d Baue die Hashtabelle neu auf Gittergrosse d 2 Fuge Pi in die Hashtabelle ein Gitterstruktur und Hashfunktion Bearbeiten Man kann vereinfachend annehmen dass alle Punkte Koordinaten zwischen 0 0 und 1 1 haben Gegebenenfalls kann hierfur eine Koordinatentransformation vorgenommen werden Die Ebene in der die Punkte liegen wird sodann durch ein Gitter der Weite d 2 displaystyle tfrac delta 2 nbsp uberdeckt Es wird nun eine universelle Hashfunktion benotigt sie ermoglicht es einerseits von einer gegebenen Gitterzelle in konstanter Laufzeit festzustellen ob sich in dieser Gitterzelle einer der Punkte befindet und andererseits neue Punkte in konstanter Laufzeit in die bestehende Hashtabelle einzufugen Einfugen neuer Punkte Bearbeiten nbsp Einfugen von PBei jedem Einfugen eines neuen Punktes P ist zu prufen ob dadurch der bereits bekannte minimale Abstand d displaystyle delta nbsp unterschritten wird Anhand der Koordinaten von P lasst sich sofort bestimmen in welcher der Gitterzellen der Punkt P liegt Aufgrund der Aufteilung in Gitterzellen der Grosse d 2 2 displaystyle left tfrac delta 2 right 2 nbsp muss nur festgestellt werden ob in einer der umliegenden Gitterzellen schon ein Punkt liegt Umliegend sind dabei alle Gitterzellen die einen solchen Abstand begrunden konnten also nur das umgebende 5x5 Rechteck Alle Punkte die ausserhalb dieses Bereichs liegen konnen keinen kleineren Abstand zu P haben weil sie aufgrund der Gittergrosse mindestens den Abstand 2 d 2 d displaystyle 2 cdot tfrac delta 2 delta nbsp haben Weil in jeder Gitterzelle nur ein einziger Punkt liegen kann denn sonst ware vorher bereits ein kleinerer Abstand gefunden worden mussen also auch nur hochstens 25 Punkte gepruft werden Sofern in diesem Bereich keine Punkte liegen kann P bedenkenlos in die bestehende Hashtabelle eingefugt werden Sind jedoch in diesem Bereich bereits weitere Punkte vorhanden so wird der Abstand d displaystyle delta nbsp auf den neu gefundenen minimalen Abstand gesetzt Dies hat zur Folge dass die bisherige Hashtabelle nutzlos geworden ist weil ihre Gitterweite nicht mehr mit d 2 displaystyle tfrac delta 2 nbsp ubereinstimmt Wir benotigen also eine neue Hashtabelle mit korrektem d displaystyle delta nbsp Wir erstellen einfach eine solche Tabelle fur alle Punkte bis zu P von Grund auf neu Der Effizienz halber kann man sich beim Neuerstellen die Abstandsprufung sparen weil der minimale Abstand aller Punkte zu P bereits bekannt ist Schliesslich hat man nach dem Einfugen eines neuen Punktes immer eine korrekte Hashtabelle mit Gitterweite d 2 displaystyle tfrac delta 2 nbsp und in jedem Gitterquadrat liegt hochstens ein Punkt Laufzeit Bearbeiten Relevant fur die Laufzeit ist lediglich die Anzahl der Einfuge Operationen neuer Punkte Trivialerweise muss jeder Punkt mindestens einmal eingefugt werden also ist die Laufzeit mindestens linear Fraglich ist jedoch wie sich der gelegentlich vorkommende Neuaufbau der Hashtabelle auswirkt weil hierfur alle bereits bekannten Punkte erneut eingefugt werden mussen Hierfur ist es notwendig die Wahrscheinlichkeit anzugeben mit der beim Einfugen eines Punkts ein Neuaufbau erforderlich wird und die dafur notwendigen Kosten einzuberechnen Intuitiv sieht man dass mit zunehmender Anzahl der Punkte der Aufwand fur die Reorganisation immer grosser wird die Wahrscheinlichkeit dafur aber immer kleiner Der Erwartungswert fur die Laufzeit kann wie folgt berechnet werden Die Wahrscheinlichkeit dafur dass der Punkt P i displaystyle P i nbsp beim Einfugen einen kleineren Abstand erzeugt ist gleich 2 i displaystyle tfrac 2 i nbsp denn dafur musste P i displaystyle P i nbsp einer der 2 Punkte sein die diesen Abstand zueinander haben Definieren wir nun die Zufallsvariable X i 0 1 displaystyle X i longrightarrow 0 1 nbsp Sie sei 1 falls beim Einfugen des Punkts P i displaystyle P i nbsp ein kleinerer Abstand entsteht und sonst 0 Dann gilt Die Gesamtanzahl der Einfugeoperationen ist n i 2 n i X i displaystyle n sum i 2 n i cdot X i nbsp also die Anzahl n displaystyle n nbsp der eingefugten Punkte plus die Anzahl der Einfugeoperationen durch die Neuorganisationen der Hashtabelle Fur den Erwartungswert gilt aufgrund dessen Linearitat E X n i 2 n i E X i n i 2 n i 2 i n 2 n 1 3 n 2 displaystyle E X n sum i 2 n i cdot E X i n sum i 2 n i cdot tfrac 2 i n 2 cdot n 1 3 cdot n 2 nbsp Das heisst die Gesamtanzahl der erwarteten Einfugeoperationen ist lediglich gleich 3 n 2 displaystyle 3 cdot n 2 nbsp Insgesamt ist die erwartete Laufzeit somit linear liegt also in O n displaystyle O n nbsp Grosster Abstand von Punkten in der Ebene BearbeitenRotating calipers Algorithmus Bearbeiten Der Rotating calipers Algorithmus ist danach benannt dass ein Messschieber um die Aussenseite eines konvexen Polygons gedreht wird Jedes Mal wenn ein Messschenkel flach an einer Seite des Polygons liegt bildet es ein antipodales Punktpaar wobei der Punkt oder die Seite den entgegengesetzte Messschenkel beruhrt Die vollstandige Drehung des Messschiebers um das Polygon erkennt alle antipodalen Punktpaare und bestimmt das Punktepaar mit dem grossten Abstand Um den Algorithmus auf beliebige Punkte in der Ebene anwenden zu konnen muss erst die konvexe Hulle der Punkte bestimmt werden Dafur wird die Laufzeit O n log n displaystyle O n cdot log n nbsp benotigt Zwei Punkte mit maximalem Abstand mussen auf den Rand des konvexen Polygons liegen das die konvexe Hulle bildet Der Algorithmus beginnt mit den Punkten P n displaystyle P n nbsp und P 1 displaystyle P 1 nbsp und berechnet den Flacheninhalt der Dreiecke P n P 1 P k displaystyle P n P 1 P k nbsp Zunachst wird k 2 displaystyle k 2 nbsp gesetzt und so lange erhoht wie der Flacheninhalt zunimmt So wird der antipodalen Punkt fur P 1 displaystyle P 1 nbsp bestimmt Auf ahnliche Weise wird der antipodale Punkt fur P 2 displaystyle P 2 nbsp bestimmt wird indem der Flacheninhalt der Dreiecke P 1 P 2 P k displaystyle P 1 P 2 P k nbsp berechnet wird und der Index k displaystyle k nbsp weiter erhoht wird so lange der Flacheninhalt zunimmt Diese Schritte werden mit den anderen Punkten P i displaystyle P i nbsp wiederholt bis der Index k displaystyle k nbsp erreicht ist also i k displaystyle i k nbsp ist Die Abstande der antipodalen Punktpaare werden berechnet und mit dem grossten bisher gefundenen Abstand verglichen Die Laufzeit fur die Berechnung der Flacheninhalte und Abstande liegt in O n displaystyle O n nbsp Insgesamt ergibt sich die Laufzeit O n log n O n O n log n displaystyle O n cdot log n O n O n cdot log n nbsp Programmierung Bearbeiten Das folgende Computerprogramm in der Programmiersprache C zeigt eine Implementierung des Rotating calipers Algorithmus Bei der Ausfuhrung des Programms wird die Methode main verwendet die das Punktepaar und den kleinsten Abstand zwischen dem Punktpaar das auf der Konsole ausgibt 2 Die Funktion getConvexHull bestimmt die konvexe Hulle der Punkte mit dem Graham Scan Algorithmus Die Funktion getOrientation bestimmt die Orientierung der Dreiecke mithilfe des Flacheninhalts Code Schnipsel include lt iostream gt include lt sstream gt include lt stack gt include lt vector gt using namespace std Deklariert den Datentyp fur Punkte mit x Koordinate und y Koordinate in der Ebene struct Point int x y Point lowestPoint Globale Variable fur den Punkt mit der kleinsten y Koordinate Diese Funktion berechnet das Doppelte des Flacheninhalts des Dreiecks aus den drei Punkten Wenn die Punkte im Uhrzeigersinn sind ist das Vorzeichen positiv Wenn die Punkte im Gegenuhrzeigersinn sind ist das Vorzeichen negativ int getArea Point point1 Point point2 Point point3 return point1 y point2 y point2 x point3 x point2 y point3 y point1 x point2 x Diese Funktion bestimmt die Orientierung des drei Punkte Wenn die Punkte im Uhrzeigersinn sind wird der Wert 1 zuruckgegeben Wenn die Punkte im Gegenuhrzeigersinn sind wird der Wert 1 zuruckgegeben Wenn die Punkte kollinear sind wird der Wert 0 zuruckgegeben int getOrientation Point point1 Point point2 Point point3 int area getArea point1 point2 point3 Aufruf der Funktion die das Doppelte des Flacheninhalts mit Vorzeichen berechnet if area gt 0 Wenn das Vorzeichen positiv ist sind die Punkte im Uhrzeigersinn return 1 if area lt 0 Wenn das Vorzeichen negativ ist sind die Punkte im Gegenuhrzeigersinn return 1 return 0 Wenn der Flacheninhalt gleich 0 ist sind die Punkte kollinear Diese Funktion berechnet das Doppelte des Flacheninhalts des Dreiecks aus den drei Punkten int absoluteArea Point point1 Point point2 Point point3 return abs getArea point1 point2 point3 Aufruf der Funktion die das Doppelte des Flacheninhalts mit Vorzeichen berechnet Diese Funktion berechnet den euklidischen Abstand zwischen zwei Punkten double getDistance Point point1 Point point2 return sqrt point1 x point2 x point1 x point2 x point1 y point2 y point1 y point2 y Vergleichsfunktion fur das Sortieren der Punkte nach Orientierung im Uhrzeigersinn int compareByOrientation const void a const void b Point point1 Point a point2 Point b int orientation getOrientation lowestPoint point1 point2 Aufruf der Funktion die die Orientierung der Punkte bestimmt if orientation 0 Wenn die Punkte kollinear sind werden die Abstande zum Referenzpunkt verglichen return int getDistance point1 lowestPoint getDistance point2 lowestPoint if orientation 1 Wenn die Punkte im Uhrzeigersinn sind ist der erste Punkt grosser return 1 return 1 Wenn die Punkte im Gegenuhrzeigersinn sind ist der zweite Punkt grosser Diese Funktion bestimmt die konvexe Hulle der gegebenen Punkte mit dem Algorithmus Graham Scan vector lt Point gt getConvexHull Point points int numberOfPoints Bestimmt den Punkt mit der kleinsten y Koordinate und seinen Index Wenn die y Koordinate gleich ist wird der Punkt mit der Punkt mit der kleinsten x Koordinate bestimmt lowestPoint INT MAX INT MAX int index 1 for int i 0 i lt numberOfPoints i for Schleife die alle Punkte durchlauft if points i y lt lowestPoint y Vergleicht die y Koordinate der Punkte lowestPoint y points i y lowestPoint x points i x index i else if lowestPoint y points i y amp amp points i x lt lowestPoint x Vergleicht die x Koordinate der Punkte wenn die y Koordinate gleich ist lowestPoint x points i x index i points index points 0 points 0 lowestPoint Setzt den Punkt an den Anfang des Arrays qsort points numberOfPoints sizeof Point compareByOrientation Sortiert die Punkte nach Orientierung im Uhrzeigersinn stack lt Point gt pointStack Stack fur die konvexe Hulle pointStack push points 0 Fugt den ersten Punkt der konvexen Hulle hinzu int k 1 while k lt numberOfPoints 1 amp amp getOrientation points 0 points k points k 1 0 Bestimmt den nachsten Punkt der nicht kollinear ist k pointStack push points k Fugt den zweiten Punkt der konvexen Hulle hinzu for int i k 1 i lt numberOfPoints i for Schleife die alle weiteren Punkte des Stack durchlauft und die konvexe Hulle erzeugt Point point pointStack top pointStack pop Entfernt das oberste Element vom Stack while getOrientation pointStack top point points i gt 0 Bestimmt den nachsten Punkt der mit den beiden obersten Elementen des Stack im Uhrzeigersinn ist point pointStack top pointStack pop Entfernt das oberste Element vom Stack pointStack push point pointStack push points i Fugt den nachsten Punkt dem Stack hinzu vector lt Point gt convexHull Vektor fur die konvexe Hulle int n pointStack size for int i 0 i lt n i for Schleife die alle Punkte des Stack durchlauft und dem Vektor hinzufugt convexHull push back pointStack top Fugt das oberste Element des Stack dem Vektor hinzu pointStack pop return convexHull Diese Funktion gibt den grossten Abstand der Punkte und Referenzen auf die zwei Punkte mit dem kleinsten Abstand zuruck und verwendet den Rotating calipers Algorithmus double getLargestDistance Point points Point amp point1 Point amp point2 int numberOfPoints vector lt Point gt convexHull getConvexHull points numberOfPoints Aufruf der Funktion fur die konvexe Hulle Point hull new Point convexHull size Referenz auf das Array fur die konvexe Hulle int n convexHull size Variable fur die Anzahl der Punkte der konvexen Hulle for int i 0 i lt n i for Schleife die das Array fur die konvexe Hulle fullt hull i convexHull i if n 1 Wenn die konvexe Hulle aus 1 Punkt besteht ist der grosste Abstand gleich 0 return 0 if n 2 Wenn die konvexe Hulle aus 2 Punkten besteht ist der grosste Abstand der Abstand dieser 2 Punkte return sqrt getDistance hull 0 hull 1 int k 1 Variable fur den Index des ersten Punkts while absoluteArea hull n 1 hull 0 hull k 1 n gt absoluteArea hull n 1 hull 0 hull k while Schleife die den Punkt mit dem grosste Abstand zum ersten und letzten Punkt der konvexe Hulle bestimmt k double maximumDistance 0 int i 0 int j k Bestimmt die zwei Punkte der konvexe Hulle mit dem grossten Abstand mit dem Rotating calipers Algorithmus while i lt k amp amp j lt n while Schleife die den Index des ersten Punkts durchlauft double currentDistance getDistance hull i hull j Ruft die Funktion fur die Berechnung des euklidischen Abstands auf if currentDistance gt maximumDistance Pruft ob der Abstand zwischen den aktuellen Punkten grosser als der bisher grosste Abstand ist point1 hull i point2 hull j maximumDistance currentDistance while j lt n amp amp absoluteArea hull i hull i 1 n hull j 1 n gt absoluteArea hull i hull i 1 n hull j while Schleife die den Index des zweiten Punkts durchlauft double currentDistance getDistance hull i hull j 1 n Ruft die Funktion fur die Berechnung des euklidischen Abstands auf if currentDistance gt maximumDistance Pruft ob der Abstand zwischen den aktuellen Punkten grosser als der bisher grosste Abstand ist point1 hull i point2 hull j 1 n maximumDistance currentDistance j i return maximumDistance Diese Funktion gibt den Punkt in der Form x y zuruck string pointToString Point point stringstream text text lt lt lt lt point gt x lt lt lt lt point gt y lt lt lt lt endl return text str Typumwandlung von stringstream nach string Hauptfunktion die das Programm ausfuhrt int main Point points 4 0 0 2 1 7 1 10 2 3 Deklariert und initialisiert ein Array mit 5 Punkten int numberOfPoints sizeof points sizeof points 0 Point point1 point2 Deklariert Referenzen fur die zwei Punkte mit dem grossten Abstand cout lt lt Der grosste Abstand zwischen zwei Punkten ist lt lt getLargestDistance points point1 point2 numberOfPoints lt lt endl Aufruf der Funktion Ausgabe auf der Konsole cout lt lt Erster Punkt lt lt pointToString amp point1 Ausgabe auf der Konsole cout lt lt Zweiter Punkt lt lt pointToString amp point2 Ausgabe auf der Konsole Literatur BearbeitenThomas H Cormen Charles E Leiserson Ronald L Rivest und Clifford Stein Algorithmen Eine Einfuhrung Oldenbourg Verlag 2004 ISBN 3 486 27515 1 Seiten 959 963 Kapitel 33 4 Berechnung des dichtesten Punktepaares Jon Kleinberg Eva Tardos Algorithm Design Pearson International Edition 2006 ISBN 0 321 37291 3 Seiten 225ff Divide amp Conquer Seiten 741ff Randomisierter Algorithmus Einzelnachweise Bearbeiten GeeksforGeeks Closest Pair of Points using Divide and Conquer algorithm GeeksforGeeks Maximum distance between two points in coordinate plane using Rotating Caliper s Method Abgerufen von https de wikipedia org w index php title Dichtestes Punktpaar amp oldid 231249134