Entwickler-Ecke
Algorithmen, Optimierung und Assembler - Breitensuche Laufzeit
K_Dadis - So 18.09.05 13:12
Titel: Breitensuche Laufzeit
Hallo,
ich weiß, dass die Laufzeit der Breitensuche O(|V|+|E|) beträgt. Nur ich versteh´s leider nicht!
Vielleicht kann mir einer das anhand folgenden quelltextes erklären! :)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33:
| var q:Tqueue; a:TAdjazenlistebesuchteKnoten:array of boolean; nachbarknoten,aktuellerKnoten:integer;
begin
q.append(0); besuchteKnoten[0]:=true;
while not q.empty do begin q.pop(aktuellerKnoten); nachbarknoten:=0; While a[aktuellerKnoten,j]>=0 do begin if not besucht(nachbarknoten) then begin q.Append(a[aktuellerKnoten,nachbarknoten]); besuchteKnoten[nachbarknoten]:=true; end; inc(nachbarknoten); end; end; end; |
Meine falsche Überlegung bisher:
Wenn der Graph zusammenhängend ist, dann werden insgesamt |V| Element in der queue abgearbeitet.
Anschließend wird für JEDEN Knoten überprüft, ob der Nachbar schon besucht wurde. Jeder Knoten kann maximal |V|-1 Nachbarn haben!
Das macht also |V| * |V-1| Vergleiche -> O(|V|²)!
warum also Laufzeit O(|V|+|E|)??
Edit: habe "j" mit "nachbarknoten" vollständig ersetzt, da ich es an einer stelle vergessen hatte.
Gausi - So 18.09.05 13:27
Die Laufzeit kommt so zustande:
while not q.empty
=> Jeder Knoten kommt in die Liste Laufzeit "[V] + ..."
Delphi-Quelltext
1:
| While a[aktuellerKnoten,j]>=0 do |
=> Hier wird jeder Nachbarknoten des aktuellen Knotens betrachtet. Wieviele Nachbarknoten gibt es denn insgesamt? Richtig, maximal hat jeder |V-1| Nachbarn. Aber: die Anzahl der Nachbarn kann man doch besser durch die Kantenzahl abschätzen, oder? Insgesamt haben alle Knoten zusammen nur soviele Nachbarn, wie es Kanten gibt. Da kommt zwar irgendwo ein Faktor 2 rein oder raus, aber das ist ja wurscht. Daher:
Alle Knoten in die Queue: |V|
Alle Nachbarn durchgehen und als besucht markieren: |E|
Insgesamt: O(|V|+|E|)
K_Dadis - So 18.09.05 15:16
Erstmal vielen Dank(!) für die schnelle Antwort, aber ich steh immernoch auf dem Schlauch! :cry:
Dieses "+" zeichen stört mich irgendwie.
Jeder Knoten kann |V|-1 Nachbarn haben. Da sind wir uns ja einig.
Nehmen wir mal an, dass jeder Knoten mit jedem verbunden ist, d.h. jeder Knoten hat |V|-1 Nachbarknoten.
bzw. es gibt dann (ahh Geistesblitz!!) |E|=|V|*|V-1| Kanten
Daher stimmt mein O(|V|*|V-1|) wieder, für den falls, dass |E|=|V|*|V-1|
denn dann ist O(|V|+|E|)= O( |V|+|V|*(|V|-1) )=O(|V|²).
Für alle anderen Fälle genügt es den index "nachbarknoten" zu betrachten und "nachbarknoten" ändert nun mal |E| seinen Wert!
Beispiel:
Knoten 1 hat 4 Nachbarn
Knoten 2 hat 3 Nachbarn
Knoten 3 hat 1 Nachbarn
Knoten 4 hat 2 Nachbarn
Knoten 5 hat 2 Nachbarn
Knoten 1 wird abgearbeiter (4 nachbarknoten,|nachbarknoten|=4)
Knoten 2 wird abgearbeiter (3 nachbarknoten,|nachbarknoten|=7)
Knoten 3 wird abgearbeiter (1 nachbarknoten,|nachbarknoten|=8)
Knoten 4 wird abgearbeiter (2 nachbarknoten,|nachbarknoten|=10)
Knoten 5 wird abgearbeiter (2 nachbarknoten,|nachbarknoten|=12)
->|nachbarknoten|=|E|
da immer überprüft wird ob ein Knoten nachbarn hat ist die maximale Laufzeit= 2* |V| + |E| <=> O(|V|+|E|)
PS: hab´s nur mal zuende gedacht, falls jmd (so wie ich) auch auf dem schlauch stand *g*
Danke nochmal!
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!