Warum sollte die Breitensuche in der Zeit


9

Es wird oft gesagt (zB in Wikipedia ) , dass die Laufzeit der Breitensuche (BFS) auf einem Graph G=(V,E) ist O(|V|+|E|) . Jeder verbundene Graph hat jedoch |V|≤|E|+1 und selbst in einem nicht verbundenen Diagramm betrachtet BFS niemals einen Scheitelpunkt außerhalb der Komponente, die den Startscheitelpunkt enthält. Diese Komponente enthält höchstens |E| Kanten, so enthält es höchstens |E|+1 Eckpunkte, und dies sind die einzigen, die der Algorithmus besuchen wird.

Dies bedeutet, dass |V|+|E|≤2|E|+1 , warum sagen wir nicht, dass die Laufzeit nur O(|E|) ?

Dies kam in Kommentaren zu einer Frage zur Laufzeit des Disjkstra-Algorithmus zum Ausdruck .


Warum nehmen Sie an, dass es einen Startscheitelpunkt gibt? BFS bei maximalem Übereinstimmungsproblem beginnt beispielsweise mit allen nicht übereinstimmenden Eckpunkten im Hopcroft-Karp-Algorithmus. In diesem Fall, wenn der gegebene Graph
— eine Gesamtstruktur

2
@narekBojikian Während BFS auf verschiedene Arten verwendet werden kann, hat es als eigenständiger Algorithmus so gut wie immer einen Startscheitelpunkt.
— David Richerby

Antworten:


9

BFS wird normalerweise wie folgt beschrieben (aus Wikipedia ).

 1  procedure BFS(G,start_v):
 2      let Q be a queue
 3      label start_v as discovered
 4      Q.enqueue(start_v)
 5      while Q is not empty
 6          v = Q.dequeue()
 7          if v is the goal:
 8              return v
 9          for all edges from v to w in G.adjacentEdges(v) do
10             if w is not labeled as discovered:
11                 label w as discovered
12                 w.parent = v
13                 Q.enqueue(w)

Das Problem ist etwas subtil: Es versteckt sich in Zeile 3! Die Frage ist, welche Datenstruktur werden wir verwenden, um zu speichern, welche Eckpunkte entdeckt wurden?

falseΘ(|V|)|V||E|O(|V|+|E|)

Θ(|V|)O(|V||E|)O(|E|2)|V|4|V||E|≤|V|3

O(log⁡|V|)O(|E|log⁡|V|)

c|E|+1c+2c+4c+⋯+2|E|≤4|E| O(1)O(|E|)

O(|E|)4|E|O(|E|)O(|V|+|E|)


1
Ich denke, es könnte zu stark sein, um zu behaupten, dass Hash-Tabellen in der Praxis eine schlechte Cache-Leistung haben. Wenn mit Verkettung (dh verknüpften Listen) implementiert, stimme ich zu. Aber wenn es mit einem kontinuierlichen Speicherblock und offener Adressierung implementiert wird, nicht so sehr.
— Juho

Wunderbare Antwort! Eine Randnotiz: Dynamisch große Hash-Tabellen sind in der Tat eine gute Wahl, nicht nur wenn es viele kleine Komponenten gibt, sondern auch, wenn der Hash-Wert für einen Scheitelpunkt durch eine vernünftige Konstante begrenzt ist, und dies kommt häufig vor. Schöne Antwort!
— Carlos Linares López

1
David, ich hatte vor Jahren ähnliche Gedanken. Ich denke, die Antwort liegt in historischen Perspektiven.
— Kelalaka
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.