Comment tracer le chemin d'une Largeur de Recherche?
Comment tracer le chemin d'une Largeur de Recherche, tel que dans l'exemple suivant:
Si vous recherchez la clé 11
, de retour de la plus court liste de connecter de 1 à 11.
[1, 4, 7, 11]
- C'était en fait un vieux de la tâche qui m'a été d'aider un ami sur mois, basée sur l'Kevin Bacon Loi. Ma solution finale a été très bâclée, en gros, j'ai fait un autre en Largeur d'abord de la recherche pour "revenir en arrière" et revenir en arrière. Je wan pas à trouver une meilleure solution.
- Excellent. - Je envisager de revoir un vieux problème dans une tentative de trouver une meilleure réponse à une admirable trait à un ingénieur. Je vous souhaite bonne chance dans vos études et de carrière.
- Merci pour les éloges, je crois si je n'ai pas l'apprendre maintenant, je vais être aux prises avec le même problème à nouveau.
- double possible de Comment obtenir le chemin d'accès entre 2 nœuds à l'aide de Largeur tout d'Abord de Recherche?
Vous devez vous connecter pour publier un commentaire.
Vous devriez avoir regarder http://en.wikipedia.org/wiki/Breadth-first_search premier.
Ci-dessous est une mise en œuvre rapide, dans lequel j'ai utilisé une liste de liste de représenter la file d'attente de chemins.
Une autre approche serait de maintenir une cartographie à partir de chaque nœud à son parent, et lors de l'inspection du nœud adjacent, enregistrement de son parent. Lorsque la recherche est terminé, il suffit de backtrace selon le parent cartographie.
Les codes ci-dessus sont basées sur l'hypothèse qu'il n'y a pas de cycles.
parent
) dans la deuxième méthode. Il est facile de modifier la méthode pour gérer les cycles. En fait, BFS est souvent mise en œuvre à l'aide d'une file d'attente avec une table de hachage(pour indiquer si un nœud est visité).node==end
), ajoutez le chemin d'accès à une autre liste qui contiendra tous les chemins que vous avez trouvé, alorscontinue
au lieu dereturn
. Si vous utilisez une visité d'empêcher les cycles, n'ajoutez pas votre nœud de fin de la visités jamais (sinon un seul chemin d'accès peut jamais avoir ce nœud de fin).J'ai aimé qiao première réponse beaucoup!
La seule chose qui manque ici, c'est pour marquer les sommets visité.
Pourquoi nous avons besoin de le faire?
Permet d'imaginer qu'il y a un autre noeud le numéro 13 est connecté à partir de nœud 11. Maintenant, notre objectif est de trouver nœud 13.
Après un peu de la file d'attente va ressembler à ceci:
Noter qu'il existe DEUX chemins avec nœud numéro 10 à la fin.
Ce qui signifie que les chemins d'accès du nœud numéro 10 sera vérifié deux fois. Dans ce cas, il n'a pas l'air si mal parce que le numéro de nœud 10 n'ont pas d'enfants.. Mais il pourrait être vraiment mauvais (même ici, nous allons vérifier que le nœud à deux reprises pour aucune raison..)
Nœud numéro 13 n'est pas dans les chemins de sorte que le programme ne sera pas de retour avant d'arriver à la deuxième chemin avec le numéro de nœud 10 à la fin..Et nous allons les enregistrer..
Tous nous manquer, c'est un jeu pour marquer les nœuds visités et de ne pas vérifier de nouveau..
C'est qiao du code après la modification:
La sortie du programme seront:
Sans unneccecery revérifie..
collections.deque
pourqueue
sous forme de liste.pop(0) engagerO(n)
de la mémoire des mouvements. Aussi, pour le bien de la postérité, si vous voulez faire DFS juste mispath = queue.pop()
auquel cas la variablequeue
en fait agit comme unstack
.Je pensais que je voudrais essayer ce code pour le fun:
Si vous voulez cycles vous pourriez ajouter ce:
assume no cycles
🙂Très facile code. Vous gardez en ajoutant le chemin à chaque fois que vous découvrez un nœud.
J'aime les deux @Qiao première réponse et @Ou de l'ajout. Pour une vue d'un peu moins de traitement, je voudrais ajouter Ou de réponse.
Dans @Ou la réponse de garder une trace de visité nœud est grande. On peut aussi autoriser le programme à quitter plus tôt qu'il ne l'est actuellement. À un certain point dans la boucle de la
current_neighbour
devra être leend
, et une fois que cela arrive le plus court chemin est trouvé et le programme peuvent revenir.Je voudrais modifier la méthode à suivre, attention à la boucle de
La sortie et tout le reste sera le même. Toutefois, le code prendra moins de temps. Ceci est particulièrement utile sur les grands graphes. J'espère que cela aide quelqu'un dans le futur.