Graph Suchalgorithmus

7

Ich suche nach einem Graphalgorithmus mit einigen ungewöhnlichen Eigenschaften.

Jede Kante im Graphen ist entweder eine "obere" oder eine "untere" Kante.

Ein gültiger Pfad kann eine unbestimmte Anzahl von "up" s folgen, gefolgt von einer unbestimmten Anzahl von "down" s, oder umgekehrt. Es kann die Richtung jedoch nicht mehr als einmal ändern.

Z.B. könnte ein gültiger Pfad A "aufwärts" B "hoch" C "runter" E "runter" F sein ein ungültiger Pfad könnte A "nach oben" B "nach unten" C "nach oben" D

sein

Was ist ein guter Algorithmus, um den kürzesten gültigen Pfad zwischen zwei Knoten zu finden? Wie wäre es, alle kürzesten Pfade gleicher Länge zu finden?

    
1800 INFORMATION 09.09.2008, 20:54
quelle

5 Antworten

11

Unter der Annahme, dass Sie keine Heuristiken haben, sollte eine Variation des Algorithmus von Dijkstra ausreichen. Jedes Mal, wenn Sie einen neuen Vorteil in Betracht ziehen, speichern Sie Informationen über seine "Vorfahren". Überprüfen Sie dann die Invariante (nur eine Richtungsänderung) und die Rückverfolgung, wenn sie verletzt wird.

Die Vorfahren hier sind alle Kanten, die durchlaufen wurden, um auf dem kürzesten Weg zum aktuellen Knoten zu gelangen. Eine gute Möglichkeit, die Vorfahreninformationen zu speichern, wäre ein Zahlenpaar. Wenn U oben ist und D unten ist, könnte der Ahnen einer bestimmten Kante UUUDDDD sein, was das Paar 3, 4 wäre. Sie werden keine dritte Zahl wegen der Invariante brauchen.

Da wir den Algorithmus von Dijkstra verwendet haben, ist die Suche nach kürzesten Wegen bereits erledigt.

    
Christian Oudard 09.09.2008, 21:14
quelle
4

Vielleicht können Sie Ihren Graphen in einen normalen gerichteten Graphen umwandeln und dann vorhandene Algorithmen verwenden.

Eine Möglichkeit wäre, den Graphen in zwei Graphen aufzuteilen, einen mit allen aufsteigenden Kanten und einen mit allen abfallenden Kanten und mit gerichteten Kanten zwischen allen Knoten in Graphen eins und dem entsprechenden Knoten in Graphen zwei.

>

Lösen Sie zuerst, um in Diagramm eins zu beginnen und in Diagramm zwei zu enden und dann umgekehrt, dann überprüfen Sie die kürzeste Lösung.

    
Mendelt 09.09.2008 21:15
quelle
2

Man sollte denken, dass Ihr Standard BFS hier funktionieren sollte. Wenn Sie der geöffneten Liste einen Knoten hinzufügen, können Sie ihn in eine Struktur umbrechen, die angibt, in welcher Richtung er verwendet wird (nach oben oder nach unten), und ein boolesches Flag, das angibt, ob die Richtung noch geändert wurde. Diese können verwendet werden, um zu bestimmen, welche ausgehenden Kanten von diesem Knoten gültig sind.

Um alle kürzesten Pfade gleicher Länge zu finden, schließen Sie die Anzahl der Kanten ein, die in Ihrer Struktur bisher durchlaufen wurden. Wenn Sie Ihren ersten kürzesten Pfad gefunden haben, notieren Sie sich die Pfadlänge und fügen Sie der geöffneten Liste keine Knoten hinzu. Durchlaufen Sie die verbleibenden Knoten in der Liste, bis Sie alle Pfade der aktuellen Länge überprüft haben, und stoppen Sie dann.

    
user316 09.09.2008 21:16
quelle
2

A * mit einer speziell gestalteten Kosten (G-Score) und heuristischen (H-Score) -Funktion kann damit umgehen .

Bei den Kosten könnten Sie die Anzahl der Richtungsänderungen im Pfad verfolgen und bei der zweiten Änderung unendliche Kosten hinzufügen (dh die Suche nach diesen Zweigen abbrechen).

Die Heuristik braucht etwas mehr Gedanken, vor allem, wenn Sie die Heuristik zulässig (überschätzen nie Mindestabstand zum Ziel) und monoton wollen. (Nur so kann garantiert werden, dass A * eine optimale Lösung findet.)

Vielleicht gibt es mehr Informationen über die Domäne, die zum Erstellen der Heuristik verfügbar ist? (dh x, y Koordinaten der Knoten im Graphen?)

Natürlich können Sie, abhängig von der Größe des Graphen, den Sie lösen möchten, zuerst einfachere Algorithmen wie die erste Breitensuche oder den Dijkstra-Algorithmus ausprobieren: im Grunde geht jeder Suchalgorithmus, und für jeden benötigen Sie eine Kostenfunktion ( oder ähnlich) sowieso.

    
Tobi 09.09.2008 21:22
quelle
1

Wenn Sie eine Standard-Graph-Suchfunktion haben, sagen wir Graph.shortest(from, to) in einer Bibliothek, können Sie Schleifen und minimieren, in C # / Pseudocode:

%Vor%

Wenn Sie sich an den minimalen Pfad / Pfad erinnern müssen und Ihre Standardfunktion Ihnen die Daten zurückgibt, können Sie auch

aussprechen %Vor%

Dabei sollte myMin zwei [fst, nxt, C, AC, BD] Tupel vergleichen und das eine mit geringerer Entfernung oder beides zurücklassen und annehmen, dass reduce eine intelligente Funktion ist.

Dies hat etwas Speicher-Overhead, wenn unsere Graphen groß sind und überhaupt keinen Speicher verwenden (was möglich ist, wenn sie dynamisch erzeugt werden), aber nicht wirklich Geschwindigkeit Overhead, imho.

    
ilya n. 12.06.2009 09:32
quelle

Tags und Links