web-dev-qa-db-fra.com

Explication des temps d'exécution de BFS et DFS

Pourquoi les temps d'exécution de BFS et DFS O (V + E), en particulier quand il y a un nœud qui a un Edge dirigé vers un nœud accessible depuis le sommet, comme dans cet exemple sur le site suivant

http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/GraphAlgor/depthSearch.htm

36
miss24

E est l'ensemble de toutes les arêtes du graphe, comme G = {V, E}. Donc, | E | est le nombre de tous les bords du graphique.

Cela seul devrait suffire à vous convaincre que la complexité globale ne peut pas être | V | fois | E |, puisque nous n'itérons pas sur toutes les arêtes du graphe pour chaque sommet.

Dans la représentation de liste d'adjacence, pour chaque sommet v, nous ne traversons que les nœuds qui lui sont adjacents.

Le | V | facteur du | V | + | E | semble provenir du nombre d'opérations de file d'attente effectuées.

Notez que la complexité de l'algorithme dépend de la structure de données utilisée. effectivement, nous visitons chaque élément d'information présent dans la représentation du graphique, c'est pourquoi pour la représentation matricielle du graphique, la complexité devient V au carré.

Citant Cormen,

"Les opérations de mise en file d'attente et de retrait de la file d'attente prennent O(1) temps, donc le temps total consacré aux opérations de file d'attente est O (V). Parce que la liste d'adjacence de chaque sommet n'est analysée que lorsque le sommet est retiré de la file d'attente, chaque liste de contiguïté est analysée au plus une fois. Comme la somme des longueurs de toutes les listes de contiguïté est Θ (E), le temps total passé à balayer les listes de contiguïté est O (E). La surcharge pour l'initialisation est O ( V), et donc la durée totale de fonctionnement de BFS est O (V + E). "

40
Abhijeet Kashnia

Ce problème consomme environ 4 heures de mon temps, mais finalement je pense que j'ai un moyen facile d'obtenir l'image, au début j'étais tenté de dire O (V * E).

Résumant l'algorithme que vous trouvez dans Cormen, qui est le même sur http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/GraphAlgor/breadthSearch.htm vous avez quelque chose comme ça :

for (vi in ​​V) Some O(1) instructions for (e in Adj (vi)) {Some O(1) instructions}

La question est de savoir combien d'instructions sont exécutées ici? ce sera le Sigma-Sum (Adj (vi)), et cette valeur est délimitée par 2 | E |.

Au début, nous pensons automatiquement à multiplier le nombre d'itérations des boucles internes et externes, mais dans ce cas, le nombre total d'itérations sur la boucle interne est fonction de l'itérateur externe, donc aucune multiplication n'est possible.

18
Jose Francisco

Vous visitez chaque Edge au plus deux fois. Il y a des bords E. Il y aura donc 2 opérations de visite E Edge. De plus, les nœuds n'ont pas de bords ou en d'autres termes, avec le degré 0. Il peut y avoir au plus V de tels nœuds. La complexité se révèle donc être, O (2 * E + V) = O (E + V)

8
Fallen

Cela devient clair lorsque vous voyez un graphique comme une structure de données représentée comme une liste adjacente

enter image description here

Vous voyez les sommets: A, B, C, D, E et les sommets adjacents pour chaque Vert/Nœud sous forme de liste de ces vertices. Vous devez "voir" toutes les cases pour vérifier s'il a été "visité" en cas de graphique cyclique ou vous devez simplement parcourir tous les enfants s'il s'agit d'un graphique en forme d'arbre

0
AleC

Vous parcourez le | V | nœuds, pour au plus | V | fois. Puisque nous avons une borne supérieure de | E | arêtes au total dans le graphique, on verra au plus | E | bords. Différents sommets auront un nombre variable de nœuds adjacents, donc nous ne pouvons pas multiplier simplement | V | * | E | (cela signifie que pour chaque sommet, nous traversons | E | arêtes, ce qui n'est pas vrai, | E | est le nombre total d'arêtes sur tous les nœuds), plutôt, nous vérifions les nœuds V, et nous vérifions un total de E bords. À la fin, nous avons O (| V | + | E |)

Pour DFS, c'est quelque chose de similaire, nous parcourons toutes les listes d'adjacence de sommets, appelant DFS (v) s'il n'a pas été visité, ce qui signifie que nous encourons | V | pas de temps, plus le temps nécessaire pour visiter les nœuds adjacents (essentiellement, ils forment un bord, et nous avons un total de | E | bords, d'où le temps O (V + E).

    private static void visitUsingDFS(Node startNode) {
        if(startNode.visited){
            return;
        }
        startNode.visited = true;
        System.out.println("Visited "+startNode.data);
        for(Node node: startNode.AdjacentNodes){
            if(!node.visited){
                visitUsingDFS(node);
            }
        }
    }
0
Bavinho