Zweifach zusammenhängend

Neue Frage »

Auf diesen Beitrag antworten »
Shizmo Zweifach zusammenhängend

Hallo, ich soll einen Algorithmus in Pseudocode angeben, der einen Graphen prüft, ob er zweifach zusammenhängend ist oder nicht.

Ich bin mir noch nicht ganz sicher, wie es am einfachsten ist, dies zu prüfen. Erst dachte ich mir es würde reichen, wenn ich prüfe, dass jeder Knoten mindestens 2 Ausgangskanten hat, aber das reicht nicht. Also irgendwie muss es immer ein Kreis sein. Hmm...
 
Auf diesen Beitrag antworten »
eulerscheZahl

Mit Tarjan findest du Artikulationspunkte und zweifache Zusammenhangskomponenten in Zeit O(|V|+|E|).
Auf diesen Beitrag antworten »
Shizmo

Danke für deine Antwort.

Die Laufzeit ist in dem Fall egal, ich werde den morgen mal durchgehen und versuchen zu verstehen.

Aber hast du vllt noch eine Idee, auf welche Eigenschaften ich noch überprüfen muss.
Wollte es eigtl auf der Basis von DFS oder so machen, falls das überhaupt möglich ist.

LG
Auf diesen Beitrag antworten »
eulerscheZahl

Tarjan basiert auf einer Tiefensuche.

Ein sehr primitiver Algorithmus, der auch prüft, ob ein Graph zweifach zusammenhängend ist:
code:
1:
2:
3:
4:
5:
Für jedes Knotenpaar s,t in G:
    finde einen Weg von s nach t
    G' = G ohne Knoten auf Weg zwischen s und t
    wenn s und t in G' nicht mehr verbunden sind, ist der Graph nicht zweifach zusammenhängend, also gib FALSCH zurück
gib WAHR zurück
 
Auf diesen Beitrag antworten »
Shizmo

Hallo, danke für deine Antwort, hab mir jetzt den Tarjan-Algorithmus etwas angeschaut und hab eine etwas abgespecktere Version entdeckt und diese noch etwas bearbeitet.

Mein Problem ist allerdings, dass der Startknoten nicht überprüft wird und immer wenn er bei diesem am Ende angelangt, false ausgibt. Ansonsten könnte es evtl funktionieren. großes Grinsen

code:
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:
//Initialisieren
for each n in G
   n.visited = false
   n.dfs = NIL
   n.lowlink = NIL
   n.PI = NIL

counter = 0

findArtPoint(start)


//Eigentliches Programm
findArtPoint(Vertex v)

   v.visited = true
   v.dfs = counter++
   v.lowlink = v.dfs

   for each w in Adj[v]
      if (! w.visited) {
         w.PI = v
         findArtPoint(w);
         if (w.lowlink >= v.dfs)
            return false

      else if (v.PI != w)
         v.lowlink = Minimum(v.lowlink, w.dfs)
Auf diesen Beitrag antworten »
eulerscheZahl

Wenn der Startknoten einen Grad > 1 hat, ist er Artikulationspunkt. Das liegt daran, dass die Teiläste untereinander nicht verbunden sind und deshalb jeder Weg von einem Ast zum anderen über den Startknoten laufen muss.

Du musst also nur noch den Grad des Startknotens prüfen.
Auf diesen Beitrag antworten »
Shizmo

Hey danke fuer deine Antwort, aber egal was hier der Startknoten wäre, jeder hat Grad > 1 , aber es gibt keinen Artikulationspunkt. verwirrt

Auf diesen Beitrag antworten »
eulerscheZahl

Du darfst nur die Vorwärtskanten zählen. Wenn die Wurzel mehr als eine nicht gestrichelte Kante hat, dann ist sie ein Artikulationspunkt.
Auf diesen Beitrag antworten »
Shizmo

Egal ob ungerichtet oder gerichtet?
Ich hab vergessen dazu zu schreiben, dass es sich um ungerichtete Graphen handelt.
Auf diesen Beitrag antworten »
eulerscheZahl

Bei der Tiefensuche machst du daraus einen gerichteten Graphen.

Dass es um einen ungerichteten Graphen geht war klar. Sonst würde es starke Zusammenhangskomponente heißen, nicht zweifache.

Beim gerichteten Graphen kommen noch mehr Kantentypen hinzu: Crosskanten (zwischen den Zusammenhangskomponenten) und Vorwärtskanten, die über mehrere Knoten gehen.
Auf diesen Beitrag antworten »
Shizmo

Zitat:
Original von eulerscheZahl
[...]
Du musst also nur noch den Grad des Startknotens prüfen.


Hast du einen Vorschlag, wie ich das in den bisjetzigen Pseudocode implementieren könnte?
Auf diesen Beitrag antworten »
eulerscheZahl

So zum Beispiel
code:
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:
//Initialisieren
for each n in G
   n.visited = false
   n.dfs = NIL
   n.lowlink = NIL
   n.PI = NIL
   n.outDegree = 0

counter = 0

bool biconnected = !findArtPoint(start) && start.outDegree == 1


//Eigentliches Programm
findArtPoint(Vertex v)

   v.visited = true
   v.dfs = counter++
   v.lowlink = v.dfs

   for each w in Adj[v]
      if (! w.visited) {
         w.PI = v
         n.outDegree++
         findArtPoint(w);
         if (w.lowlink >= v.dfs)
            return false

      else if (v.PI != w)
         v.lowlink = Minimum(v.lowlink, w.dfs)

edit: du solltest vielleicht auch noch irgendwann true zurückgeben.
Auf diesen Beitrag antworten »
Shizmo

Hmm, also Zeile 24 soll v.outDegree++ heißen oder?

Wenn ich aber so einen Graph habe (Anhang) wird false returned und der StartKnoten hat zu dem Zeitpunkt auch den outDegree-Wert = 1, also true, was aber nicht stimmt. (Der linke Knoten ist der Startknoten)
Auf diesen Beitrag antworten »
eulerscheZahl

Ja, das hätte ein v werden sollen.
Wo ist denn das Problem bei deinem Graphen (tut mir leid, ich bin gerade denkfaul nach 2.5h Programmierwettbewerb).
Auf diesen Beitrag antworten »
Shizmo

Hja, das glaub ich dir geschockt

Linker Knoten = A, mittlerer B und rechter Knoten = C.

A.visited = true
A.dfs = 1
A.lowlink = 1

B.Pi = A
A.outDegree = 1

B.visited = true
B.dfs = 2
B.lowlink = 2

C.Pi = B
B.outDegree = 1

C.visited = true
C.dfs = 3
C.lowlink = 3

if (C.lowlink >= B.dfs) (3>2) => return false

=> bool biconnected = true && start.outDegree == 1

Also true.
Aber der Graph ist nicht biconnected.
Auf diesen Beitrag antworten »
eulerscheZahl

Kann es sein, dass ich einfach die Negation falsch gesetzt habe?

Mein Gedanke war: wenn findArtPoint true zurückgibt, hat der Graph einen Artikulationspunkt.
Jetzt gibt der Algorithmus aber false zurück, wenn ein Artikulationspunkt gefunden wird.
Auf diesen Beitrag antworten »
Shizmo

Wird keiner gefunden gibt er aber auch ein false zurück und start.outDegree ist immer 1.

Ich hab grad gemerkt, dass mir dieser Minimum-Vergleich fehlt, vermutlich klappt es deswegen nicht. Versteh aber auch nicht ganz für was der ist.

Hab mal eine andere Version, die funktioniert soweit, allerdings nicht für einen trivialen Graph (also mit nur zwei Knoten).

code:
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:
34:
35:
36:
37:
38:
39:
40:
41:
time = 0
isBiconnected = true

for each v in V
   v.color = weiß
   v.PI = NIL

BICONNECTED(startNode)


return isBiconnected
--------------------------

BICONNECTED(u)

u.color = gray
u.d = time
u.l = u.d

time++

for each v in Adj[u]
   if v.color == white
      v.PI = u
      MDFS-visit(v)

      /* Kleineren Low-Wert des Kindes uebernehmen. */
      u.l = min{u.l, v.l}

      /* u ist Artikulationspunkt */
      if v.l > u.d
         isBiconnected = false
         return

   /* Rueckwaertskante */
   if v.color == gray and u.PI != v
      /* Merken, welche am weitesten zurueck reicht. */
      u.l = min{u.l, v.d}

u.color = black
Auf diesen Beitrag antworten »
eulerscheZahl

Zitat:
Ich hab grad gemerkt, dass mir dieser Minimum-Vergleich fehlt, vermutlich klappt es deswegen nicht. Versteh aber auch nicht ganz für was der ist.

Es kann sein, dass ein Knoten mehrere Rückkanten hat. Dann sprichst du immer so weit zurück nach oben wie möglich.
Auf diesen Beitrag antworten »
Shizmo

Okay, aber warum macht man das? Generell, was ist dieses lowlink?
Auf diesen Beitrag antworten »
eulerscheZahl

Grundüberlegung:
Bei der Tiefensuche entsteht ein Baum. Es kann auch keine Querverbindung zwischen den Ästen mit gleicher Wurzel geben.

Betrachten wir zwei Knoten u und v:
es gibt einen Weg von u nach v, der durch die Tiefensuche gefunden wurde. Wenn es aber keinen anderen Weg gibt, um von v aus wieder über u zu kommen, ist u ein Artikulationspunkt (der einzige Weg von Knoten oberhalb von u nach v führt eben über u).

lowlink gibt an, wie weit man maximal zurück nach oben kommt. Kommt man nicht höher als bis u, ist u ein Artikulationspunkt.


Sag Bescheid, wenn du meine Vorlesungsmitschrift willst. Da ist der Beweis ausführlicher.
Auf diesen Beitrag antworten »
Shizmo

Ich glaub es hat grade klick gemacht.

Zitat:
Original von eulerscheZahl
Grundüberlegung:
Bei der Tiefensuche entsteht ein Baum.
[...]


Bin grad nochmal alles durchgegangen und habe mir Tiefensuchbäume aufgezeichnet und somit ist alles viel klarer geworden.

Vielen Dank für deine Hilfe!!!!
 
Neue Frage »
Antworten »


Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »