Autor Beitrag
K_Dadis
Hält's aus hier
Beiträge: 6



BeitragVerfasst: So 18.09.05 13:12 
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! :)

ausblenden volle Höhe 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:
//Variablen
var
q:Tqueue;  // ist eine Queue
a:TAdjazenliste// ist eine Adijazenliste
besuchteKnoten:array of boolean; //start-init: alles false
nachbarknoten,aktuellerKnoten:integer;

{die procedure Tqueue.pop(x) speichert das nächste Element der queue in x!
 die procedure Tqueue.append(x) hängt das Element x an die queue.}
 

begin
 {-->1. Wir starten bei knoten 0<--}

  q.append(0);//hänge Knoten 0 an die queue..
  besuchteKnoten[0]:=true; //..und markiere den Knoten als besucht.

  {-->2.nun beginnt der 'eigentliche' algorithmus<--}

  while not q.empty do //solange die queue nicht leer ist:
  begin
    q.pop(aktuellerKnoten); //nehme das nächste Element aus der queue..
    nachbarknoten:=0;
    While a[aktuellerKnoten,j]>=0 do //..und solange der aktuelle Knoten Nachbarn hat mache:
    begin
        if not besucht(nachbarknoten) then //wenn der Nachbarknoten noch nicht besucht ist, dann..
        begin
          q.Append(a[aktuellerKnoten,nachbarknoten]);//..hänge ihn an die queue..
          besuchteKnoten[nachbarknoten]:=true;       //..und markiere ihn als besucht.
        end;
        inc(nachbarknoten); //gehe zum (eventuellen) nächsten nachbarn
    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.


Zuletzt bearbeitet von K_Dadis am So 18.09.05 14:48, insgesamt 1-mal bearbeitet
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8548
Erhaltene Danke: 477

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: So 18.09.05 13:27 
Die Laufzeit kommt so zustande:

while not q.empty
=> Jeder Knoten kommt in die Liste Laufzeit "[V] + ..."

ausblenden 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|)

_________________
We are, we were and will not be.
K_Dadis Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: 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!