2016-06-02 8 views
4

Das Problem bei der Hand:Algorithmus für> 2D-Skyline Abfrage/Efficient Frontier

eine Menge von N Punkten in einem D-dimensionalen Raum gegeben, mit allen ihren Koordinaten> = 0 (in 2D die Punkte alle in der sein würden, 1. Quadrant, in 3D im 1. Oktant, und so weiter ...), entfernen Sie alle Punkte, die einen anderen Punkt haben, dessen Wert in jeder Koordinate größer oder gleich ist.

In 2D ist das Ergebnis folgendermaßen aus: enter image description here

(Bild von Vincent Zoonekynd Antwort here), und es ist ein einfacher Algorithmus, detaillierter in dieser Antwort, die in N*log(N) läuft. Mit Chunking hätte ich es zu N*log(H) gebracht haben, aber Optimierungen auf das sind für eine andere Frage.

Ich war daran interessiert, die Lösung auf 3 Dimensionen bei der Verlängerung (und möglicherweise 4, wenn es noch sinnvoll ist), aber mein aktueller 3D-Algorithmus ist ziemlich langsam, umständlich und verallgemeinern nicht auf 4D schön:

  • Sortier Punkte auf der x-Achse, mit Anmerkungen versehen, die Position eines jeden Punktes
  • eine Art von Segmentbaum mit N Blättern initialisieren, wo Blätter werden die Punkte y-Werte halten, und ein Knoten max(child1, child2)
  • Sortierpunkte auf der z-Achse halten
  • Für jeden Punkt von dem größten z:
    • prüfen, welche Position sie in der x-Ordnung waren, versuchen Sie es in dem Segmentbaum
    • Check in dieser Position an erster Stelle, wenn es ein Punkt bereits nach unten ist (so hat es> z), an einer höheren Stelle (so hat es> x) mit einem größeren y (das kostet log (N), danke Baum)
    • Wenn dieser Punkt gefunden wird, wird der aktuelle Punkt verworfen, andernfalls wird er eingefügt und der Baum ist aktualisiert

Dieses Angebot läuft noch in N*log(N), aber erfordert 2 verschiedene Sorten und eine 2*N -große Struktur.

Erweiterung würde erfordern eine andere Art und eine prohibitive 2*N^2-big Quad-Struktur.

Gibt es effizientere (insbesondere CPU-bezogene) Ansätze?


Ich glaube nicht, es relevant ist, aber ich bin in C schreiben, der Code ist here.

+0

Ich glaube, ich habe Ihr Problem schon einmal kennen gelernt - können Sie gehen durch ein Beispiel dessen, was Sie eigentlich wollen, mit ein paar Punkten für Illustration? –

+0

@DAdams Ich glaube, das Bild erklärt es viel besser als ich kann, nur vorstellen, es in 3D.Sie beginnen mit allen Punkten dort und der Algorithmus gibt Ihnen nur die Quadrate zurück. In 2D ist es einfach zu sehen. – 12345ieee

+1

Bemerkenswert, dass die gleiche Frage für C# gefragt wurde, und die selbe Lösung, die ich vorschlug, wurde angenommen http://stackoverflow.com/questions/12407730/finding -Skyline-Set –

Antwort

0

Wenn ich dies in N-Dimensionen mache, würde ich einen k-d-Baum des nächsten Nachbarn verwenden. Der Baum ist ein schneller Weg, um Punkte basierend auf ihrer Entfernung von einem Ort im N-D-Raum zu sortieren. Standardmäßig sortiert der K-D-Baum Punkte basierend auf seiner euklidischen Distanz zu einem bestimmten Ort, indem er verschachtelte Bäume erstellt.

Es gibt eine Möglichkeit, die Entfernungsmetrik so zu ändern, dass sie genau Ihren Anforderungen entspricht. Nachdem Sie den Baum gebaut haben, wollen Sie einfach die Punkte, die am weitesten von Ihrer Herkunft entfernt sind.

euklidischen Entfernung Metric:

sqrt (sum_over_dimensions (coord ** 2))

Ich schlage vor, schlagen die Metrik (was falsch sein kann):

sum_over_dimensions (Koord)

Links:

Wiki K-D-Baum:

https://en.wikipedia.org/wiki/K-d_tree

Überlauf Beitrag über K-D-Baum-Metriken:

Can I use arbitrary metrics to search KD-Trees?

Definition mathematischer Metrik:

https://en.wikipedia.org/wiki/Metric_(mathematics)

Zusammenfassend - ich vermute, dass Sie, wenn Sie genug Zeit für das Problem aufwenden, eine robuste N-dimensionale Lösung für Ihr Problem erstellen könnten, die "Worst-Case-Komplexität von O (kn log n)" hat. [wobei k die Anzahl der Dimensionen ist] ". Ich vermute auch, dass es schwierig ist, es besser zu machen, weil großdimensionale Algorithmen für den nächsten Nachbarn ein bekanntes ungelöstes Problem sind.

+0

Ich stimme der Computerklasse (IMHO können Sie O (k \ * Nlog (H)), wobei H ist die Anzahl der Punkte in der Grenze, aber H ist heuristisch N^(k-1)/k, so dass es klappt zurück zu deinem). Ich habe mehr Reserven mit Ihrer "Entfernung vom Ursprung" Idee. Jede Summe_i (coord_i ** a) für eine in R würde fehlschlagen, da die "Treppe" stark abfallen kann (wie die Funktion 1/x in 2D). Ich werde jedoch über K-d-Bäume lesen, danke. – 12345ieee

+0

Ich bin froh, dass der k-d-Baum dich in die richtige Richtung weist :) In Bezug auf die "Entfernung" -> Um klar zu sein, ich vermute, dass es eine korrekte Metrik gibt, die dir die Punkte liefert, die NICHT euklidisch sind. In Ihrer Notation schlug ich die Metrik vor: distance = sum_i (coord_i) [und das ist wahrscheinlich auch falsch] –

+0

Nach der "Entfernung von der Mitte" Idee, aber es ist ziemlich klar, dass keine Entfernung (im mathematischen Sinne, nicht nur euklidisch/Manhattan) kann das Problem lösen. Theoretisch liegt es daran, dass Sie versuchen, ein k-dimensionales Problem auf Vergleiche in einer Dimension zu reduzieren. In der Praxis, in 2D die Kurven d (Ursprung, p) = const für eine Entfernung d betrachten, kann ich immer Punkte schleichen, die nicht gelöscht werden sollten, egal wie groß const ist, setzen sie auf (enorm, 0); Umgekehrt kann ich Punkte setzen, die nicht gelöscht werden sollen. Es sei denn, ich missverstanden etwas, auf keinen Fall. – 12345ieee