Wie verfolgen Sie den Pfad einer Breitensuche, so dass im folgenden Beispiel:
Wenn Sie nach einem Schlüssel suchen 11
, geben Sie die kürzeste Liste zurück, die 1 bis 11 verbindet.
[1, 4, 7, 11]
python
algorithm
graph
breadth-first-search
Christopher Markieta
quelle
quelle
Antworten:
Sie sollten zuerst auf http://en.wikipedia.org/wiki/Breadth-first_search schauen .
Unten ist eine schnelle Implementierung, in der ich eine Liste von Listen verwendet habe, um die Warteschlange von Pfaden darzustellen.
Ein anderer Ansatz wäre, eine Zuordnung von jedem Knoten zu seinem übergeordneten Knoten beizubehalten und bei der Inspektion des benachbarten Knotens seinen übergeordneten Knoten aufzuzeichnen. Wenn die Suche abgeschlossen ist, führen Sie einfach eine Rückverfolgung gemäß der übergeordneten Zuordnung durch.
Die obigen Codes basieren auf der Annahme, dass es keine Zyklen gibt.
quelle
Die erste Antwort von Qiao hat mir sehr gut gefallen! Das einzige, was hier fehlt, ist, die Scheitelpunkte als besucht zu markieren.
Warum müssen wir das tun?
Stellen wir uns vor, dass ein weiterer Knoten Nummer 13 mit Knoten 11 verbunden ist. Jetzt ist es unser Ziel, Knoten 13 zu finden.
Nach einem kurzen Lauf sieht die Warteschlange folgendermaßen aus:
Beachten Sie, dass es am Ende ZWEI Pfade mit der Knotennummer 10 gibt.
Dies bedeutet, dass die Pfade von Knoten Nummer 10 zweimal überprüft werden. In diesem Fall sieht es nicht so schlecht aus, weil Knoten Nummer 10 keine Kinder hat. Aber es könnte wirklich schlecht sein (auch hier werden wir diesen Knoten ohne Grund zweimal überprüfen.)
Knoten Nummer 13 ist nicht in Diese Pfade, damit das Programm nicht zurückkehrt, bevor es zum zweiten Pfad mit Knoten Nummer 10 am Ende gelangt. Und wir werden es erneut überprüfen.
Wir vermissen lediglich einen Satz, um die besuchten Knoten zu markieren und nicht erneut zu überprüfen.
Dies ist der Code von qiao nach der Änderung:
Die Ausgabe des Programms lautet:
Ohne die Unccecery erneut zu prüfen ..
quelle
collections.deque
fürqueue
list.pop (0)O(n)
Speicherbewegungen zu verwenden. Wenn Sie der Nachwelt halber DFS ausführen möchten, legen Sie einfach fest,path = queue.pop()
in welchem Fall sich die Variablequeue
tatsächlich wie eine verhältstack
.Sehr einfacher Code. Sie hängen den Pfad jedes Mal an, wenn Sie einen Knoten entdecken.
quelle
Ich dachte, ich würde versuchen, dies zum Spaß zu programmieren:
Wenn Sie Zyklen möchten, können Sie Folgendes hinzufügen:
quelle
Ich mag sowohl die erste Antwort von @Qiao als auch die Hinzufügung von @ Or. Um etwas weniger zu verarbeiten, möchte ich die Antwort von Or ergänzen.
In der Antwort von @ Or ist es großartig, den besuchten Knoten zu verfolgen. Wir können auch zulassen, dass das Programm früher als derzeit beendet wird. Irgendwann in der for-Schleife muss der
current_neighbour
der seinend
, und sobald dies geschieht, wird der kürzeste Pfad gefunden und das Programm kann zurückkehren.Ich würde die Methode wie folgt modifizieren, genau auf die for-Schleife achten
Die Ausgabe und alles andere wird gleich sein. Die Verarbeitung des Codes dauert jedoch weniger lange. Dies ist besonders nützlich bei größeren Diagrammen. Ich hoffe das hilft jemandem in der Zukunft.
quelle