Algorithmus zur Abdeckung der maximalen Anzahl der Punkte mit einem Kreis von gegebenem radius
Stellen wir uns vor, wir haben ein Flugzeug mit einige Punkte auf.
Wir haben auch einen Kreis von gegebenem radius.
Brauche ich einen Algorithmus, der bestimmt, wie die position des Kreises, es deckt die maximal mögliche Anzahl von Punkten. Natürlich gibt es viele solcher Positionen, so sollte der Algorithmus Rückkehr einer von Ihnen.
Genauigkeit ist nicht wichtig, und der Algorithmus kann kleine Fehler.
Hier ist ein Beispiel Bild:
Eingang:
int n
(n<=50) – Anzahl der Punkte;
float x[n]
und float y[n]
– arrays mit Punkten' in der X-und Y-Koordinaten;
float r
– radius des Kreises.
Ausgabe:
float cx
und float cy
– Koordinaten der Mitte des Kreises
Blitz Geschwindigkeit des Algorithmus ist nicht erforderlich, aber es sollte nicht zu langsam sein (weil ich weiß, dass ein paar langsame Lösungen für diese situation).
C++ - code ist bevorzugt, aber nicht obligatorisch.
- Sie haben keine Einschränkungen bei der Verteilung der Punkte?
- Das klingt wie ein großer codegolf
- Ich weiß wirklich nicht so denken. Ziemlich langweilig, keine genaue Bedingungen zum Gewinn... Aber fühlen Sie sich frei, um eine solche Frage.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Bearbeitet werden, um eine bessere Formulierung, wie vorgeschlagen :
Grundlegenden Beobachtungen :
Des Algorithmus ist dann:
O(n^3)
ist nicht gut, aber es ist mathematisch wahre Lösung.Take two points, you have (at most) two unit circles that pass through it
? Wasit
? Warum sind Sie Kommissionierung Einheit Kreise? Dies sollte wirklich besser erklärt.given a solution circle to your problem, you can move it until it contains two points of your set while keeping the same number of points of your set inside it.
- Ich glaube nicht, dass dies wahr ist. Sowieso, ignoriert, dass, betrachten ein Dreieck, das (kaum) passt in einen Kreis mit radiusr
. Der Abstand zwischen je zwei Punkten des Dreiecks ist> 2
. Betrachten wir zwei Punkte sehr, sehr weit Weg von dem Dreieck mit den gegenseitigen Abstand< 2
. Ich denke, dein Algorithmus würde nur die 2 Punkte als Lösung. Ihr Algorithmus ist falsch, meiner Meinung nach, es gar nicht verwendenr
überall.< 2
?2
deine Antwort. Sollte es nicht2*r
?r
überall.Dies ist die "disk teilverkleidungen problem" in die Literatur-das sollte Ihnen ein guter Ort, um zu starten googeln. Hier ist ein Papier abdecken eine mögliche Lösung, aber es ist ein wenig intensiver mathematisch: http://www.utdallas.edu/~edsha/papers/bin/ISPAN04_cover.pdf
Als eine Angelegenheit von Tatsache, diese fällt in den Bereich der "computational geometry", das ist faszinierend, aber kann hart sein, um einen Brückenkopf in. Gibt es eine gute übersicht von deBerg auf verschiedenen algorithmen, im Zusammenhang mit dem Thema.
Wenn Sie etwas einfaches möchten, nehmen Sie zufällige position (x,y), berechnen Sie die Anzahl der Punkte im Kreis und vergleichen mit vorherigen position. Nehmen Sie die maximale. Wiederholen Sie den Vorgang jedes mal, die Sie wollen.
Warum zum Teufel downvote? Jemals gehört, über Monte-Carlo-Methoden? Eigentlich für eine riesige Menge von Punkten, deterministischen Algorithmus kann nicht Ziel in angemessener Zeit.
Das problem kehrt zurück zu finden, die globalen optimale Funktion f
:R x R -> N
. Der Eingang für f ist der Mittelpunkt des Kreises, und der Wert, natürlich, ist die Anzahl der enthaltenen Punkte aus dem set. Der graph der Funktion wird unterbrochen, staircase-like.Könnten Sie beginnen und testen Sie die Funktion in jedem Punkt entspricht einem Punkt in der Menge, um die Punkte durch eine Verringerung der Werte von f, dann verstärken suchen, um diese Punkte (zum Beispiel bewegen sich entlang einer Spirale).
Weitere option ist zu prüfen alle Schnittpunkte der Segmente verbinden alle Paare von Punkten im set. Ihre optimale Punkt an einer dieser Kreuzungen, die ich denke, aber Ihre Zahl ist wahrscheinlich zu groß, zu berücksichtigen.
Können Sie auch hybridisieren die Optionen 1 und 2, und betrachten die Schnittpunkte der Segmente generiert aus Punkten, um 'gute Punkte'.
Jedenfalls, es sei denn, die Anzahl der gesetzten Punkte ist gering (so dass Sie überprüfen alle Kreuzungen), ich weiß nicht denke können Sie garantieren ein optimum zu finden (eine gute Lösung).
Auf den ersten Blick würde ich sagen, eine quad-tree-Lösung.
Auch, es ist ein Informations-Visualisierung/Data-mining-Methode aufgerufen, K-Mittel, die macht, Cluster von bestimmten Daten. Es kann verwendet werden, mit zusätzlicher Funktionalität in das Ende passen Ihren Zweck.
Der grundlegende Algorithmus für K-Means ist:
das sind geclustert - Diese Punkte repräsentieren die erste Gruppe centroide
Schwerpunkt
Positionen der K centroide durch Berechnung der mittleren position des dots
Die zusätzliche Funktionalität wäre dann:
Quellen:
K-means-Algorithmus - Linköping University
Quadtree - en.wikipedia.org/wiki/Quadtree
Eine schnelle Suche auf wikipedia und finden Sie die Quelle code: en.wikipedia.org/wiki/K-means_clustering
Hier sind zwei Ideen: eine O(n) - approximation algorithm und einen O(n^2 log n) exakt (nicht ungefähr) Algorithmus:
Schnelle Annäherung
Verwenden locality-sensitive-hashing. Im Grunde, hash-jeder Punkt zu einem hash-bucket enthält Punkte in der Nähe. Die Eimer sind so aufgebaut, dass Kollisionen nur geschehen zwischen nahen Punkte - im Gegensatz zu den ähnlich benannten hash-Tabellen-Kollisionen sind hier nützlich. Halten Sie eine laufende Zählung der Anzahl der Kollisionen in einen Eimer, und verwenden Sie dann die Mitte der Eimer, als die Mitte Ihres Kreises.
Ich zugeben, dass dies eine schnelle Erklärung für ein Konzept, das ist nicht super-offensichtlich, wenn Sie das erste mal hören. Eine Analogie wäre zu Fragen, eine Reihe von Menschen, welche Ihre Postleitzahl, und die meisten zip-code zum bestimmen der bevölkerungsreichste Kreis. Es ist nicht perfekt, aber eine gute schnelle Heuristik.
Es ist im Grunde die lineare Zeit in der Anzahl der Punkte, und Sie können Ihre Daten aktualisieren, legen Sie "on the fly" inkrementell neue Antworten in konstanter Zeit pro Punkt (Konstante mit Bezug auf n = Anzahl der Punkte).
Mehr über locality-sensitive-hashes im Allgemeinen oder über meine persönlichen Lieblings-version, die funktionieren würde, in diesem Fall.
Besser als brute-force-deterministischen Ansatz
Ist die Idee: für jeden Punkt, platzieren Sie den Rand des Kreises auf, dass Punkt, und fegen Sie den Kreis, um zu sehen, in welche Richtung enthält die meisten Punkte. Tun Sie dies für alle Punkte, und wir finden die globalen max.
Den Schwung um einen Punkt p kann man in n log n Zeit durch: (a) die Suche nach der Winkel-Intervall je einem anderen Punkt q, so dass, wenn wir den Kreis in Winkel theta, dann enthält q; und (b) Sortieren Sie die Intervalle so, dass wir März/kehren um p in linearer Zeit.
So dauert es O(n log n) Zeit zu finden, die am besten Kreis berühren einen festen Punkt p, und dann multiplizieren, dass durch O(n), um die Kontrollkästchen für alle Punkte. Die Gesamtzeit ist O(n^2 log n).
Wenn es wahr ist, dass die Präzision nicht wichtig ist und Algorithmus machen kann, kleine Fehler, dann denke ich, die folgenden.
Lassen
f(x,y)
ist eine Funktion, die hat ein maximum an der Stelle (0,0) und ist nur signifikant auf die inneren Punkte des Kreises mit radius R. Zum Beispielf(x,y) = e^{(x^2 + y^2)/(2 * R^2)}
.Lassen
(x_i,y_i)
Punkte undE_i(x,y) = f(x - x_i, y - y_i)
.Ihr problem zu finden, die maximal
\sum_i E_i(x,y)
.Können Sie eine Gradienten-Abstieg starten Sie es von jedem Punkt.
f
war1 inside the circle, and 0 outside
. 🙂If it is true that precision is not important...
.Könnte ich schlage vor, eine Dichte Karte? Finden Sie die min-und max-Grenzen für die x und y. Teilen Sie den Bereich der x-und y-Grenzen in bins mit Breite gleich dem Durchmesser deines Kreises. Die Anzahl der Punkte in jeder Klasse für die x-und y separat. Nun finden Sie die Kreuzung auf Ihre Dichte Karte zwischen dem höchsten Rang x bin mit dem höchsten y bin.
Dies ist ein SEHR schneller Algorithmus, um schnell zu verallgemeinern großen Daten-sets, aber es ist nicht immer richtig, um Genauigkeit zu verbessern, können Sie schneiden Sie die Behälter in kleinere und kleinere Stücke oder Verschiebung der bin-Positionen nach Links oder rechts n-mal und verwenden Sie ein voting-system wählen Sie die Antwort, dass tritt am häufigsten zwischen Studien.
Könnten Sie Verpixeln das ganze Gebiet, dann gehen Sie zu jedem Punkt, und erhöhen Sie den Wert für alle Pixel innerhalb des Kreises, der den radius um diesen Punkt. Die Pixel mit der höchsten Summe, sind gute Kandidaten.
Natürlich, verlieren Sie möglicherweise einige gute Bereiche oder "halluzinieren" guten Gebieten aufgrund von Rundungsfehlern. Vielleicht könnten Sie versuchen, eine grobe pixellation zuerst, dann verfeinern Sie die zukunftsträchtigen Bereichen.
Dies ist die berühmte K-closest-point-Algorithmus. Hier beschrieben: http://www.cs.ucsb.edu/~suri/cs235/ClosestPair.pdf