2017-08-10 3 views
1

Juste une question rapide et stupide, à propos de BFS traversal sur les graphesnoeud marquage visité sur BFS quand dequeuing

je trouve sur de nombreux sites le pseudo-code pour un BFS est à peu près quelque chose comme ceci:

BFS (Graph, root): 

create empty set S 
create empty queue Q  
add root to S //mark as visited here 
Q.enqueue(root)      
while Q is not empty: 
    current = Q.dequeue() 
    if current is the goal: 
     return current 
    for each node n that is adjacent to current: 
     if n is not in S: 
      add n to S //mark as visited here 
      Q.enqueue(n) 

Je viens de trouver un peu plus simple de marquer un nœud donné comme visité après l'avoir défini plutôt que d'en avoir un, parce que dans l'approche ultérieure, nous aurons besoin d'écrire une étape supplémentaire. Je sais que ce n'est pas une grande chose, mais je suppose qu'il est plus logique de marquer un nœud comme visité à un endroit au lieu de deux. est plus concis, plus facile à retenir et même à apprendre.

La version modifiée sera comme ceci:

BFS (Graph, root): 

create empty set S 
create empty queue Q  
Q.enqueue(root)      
while Q is not empty: 
    current = Q.dequeue() 
    add current to s //just add this and remove the other 2 lines 
    if current is the goal: 
     return current 
    for each node n that is adjacent to current: 
     if n is not in S: 
      Q.enqueue(n) 

Je veux juste savoir si ce changement est correct, pour autant que je sais que cela ne devrait pas changer le comportement du traversal du tout, fait il?

Répondre

1

L'attente de marquer le sommet comme visité après la suppression de la file d'attente modifiera le comportement de BFS. Considérez le graphique suivant:

   A 
      /\ 
      / \ 
      B  C 
      \ /
       \/
       D 
       /|\ 
      /| \ 
      E F G 

A chaque étape, Q et S ressemblera à ceci:

Q   S 
===== ======= 
{A}  {} 
{B,C} {A} 
{C,D} {A,B} 
{D,D} {A,B,C} // dequeue C - D is not in the visited list, so enqueue D again 

Comme vous pouvez le voir, nous avons D dans la file d'attente deux fois. Tous les enfants de D sera également ajouté à la file d'attente deux fois ...

Q    S 
============= ======== 
{D,E,F,G}  {A,B,C,D} 
{E,F,G,E,F,G} {A,B,C,D} 

... et ainsi de suite. Si deux autres nœuds dans la file d'attente pointent vers le même nœud (non visité), vous obtiendrez plus de duplication. En plus du traitement inutile, si vous effectuez le suivi du chemin d'un nœud à l'autre à l'aide d'une liste de prédécesseurs ou d'un ordre de découverte d'enregistrement, vos résultats peuvent être différents de ce que vous attendiez. Que ce soit un problème ou non, bien sûr, cela dépend de votre problème particulier. De toute évidence, ce scénario ne peut se produire que dans les graphes généraux et non dans les arbres, mais BFS est un algorithme de graphes, et mémoriser deux implémentations différentes, une pour les graphes et une pour les arbres, est moins concise et facile à mémoriser. une implémentation qui fonctionne pour tous les cas.