Comment tracer le chemin d'une recherche en largeur d'abord, comme dans l'exemple suivant:
Si vous recherchez une clé 11
, renvoyez la liste la plus courte reliant 1 à 11.
[1, 4, 7, 11]
python
algorithm
graph
breadth-first-search
Christopher Markieta
la source
la source
Réponses:
Vous devriez d'abord regarder http://en.wikipedia.org/wiki/Breadth-first_search .
Voici une implémentation rapide, dans laquelle j'ai utilisé une liste de liste pour représenter la file d'attente des chemins.
Une autre approche consisterait à maintenir un mappage de chaque nœud à son parent et, lors de l'inspection du nœud adjacent, à enregistrer son parent. Lorsque la recherche est terminée, effectuez simplement un retour arrière en fonction du mappage parent.
Les codes ci-dessus sont basés sur l'hypothèse qu'il n'y a pas de cycles.
la source
J'ai beaucoup aimé la première réponse de qiao! La seule chose qui manque ici est de marquer les sommets comme visités.
Pourquoi devons-nous le faire?
Imaginons qu'il y ait un autre nœud numéro 13 connecté à partir du nœud 11. Maintenant, notre objectif est de trouver le nœud 13.
Après un peu de course, la file d'attente ressemblera à ceci:
Notez qu'il y a DEUX chemins avec le numéro de nœud 10 à la fin.
Ce qui signifie que les chemins du nœud numéro 10 seront vérifiés deux fois. Dans ce cas, cela n'a pas l'air si mal car le nœud numéro 10 n'a pas d'enfants .. Mais cela pourrait être vraiment mauvais (même ici, nous vérifierons ce nœud deux fois sans raison ..) Le
nœud numéro 13 n'est pas dans ces chemins afin que le programme ne revienne pas avant d'atteindre le deuxième chemin avec le noeud numéro 10 à la fin .. Et nous le revérifierons.
Il ne nous manque qu'un ensemble pour marquer les nœuds visités et ne pas les vérifier à nouveau.
Voici le code de qiao après la modification:
La sortie du programme sera:
Sans les revérifications inutiles.
la source
collections.deque
pourqueue
as list.pop (0) engendreO(n)
des mouvements de mémoire. De plus, dans un souci de postérité, si vous voulez faire DFS, définissez simplementpath = queue.pop()
dans quel cas la variablequeue
agit en fait comme unstack
.Code très simple. Vous continuez à ajouter le chemin chaque fois que vous découvrez un nœud.
la source
J'ai pensé essayer de coder ceci pour le plaisir:
Si vous voulez des cycles, vous pouvez ajouter ceci:
la source
J'aime à la fois la première réponse de @Qiao et l'ajout de @ Or. Pour un peu moins de traitement, je voudrais ajouter à la réponse d'Or.
Dans la réponse de @ Or, le suivi du nœud visité est excellent. Nous pouvons également permettre au programme de se terminer plus tôt qu'il ne l'est actuellement. À un moment donné dans la boucle for, il
current_neighbour
devra être leend
, et une fois que cela se produit, le chemin le plus court est trouvé et le programme peut revenir.Je modifierais la méthode comme suit, faites très attention à la boucle for
La sortie et tout le reste seront les mêmes. Cependant, le code prendra moins de temps à traiter. Ceci est particulièrement utile sur les graphiques plus grands. J'espère que cela aidera quelqu'un à l'avenir.
la source