Prof. Dr. Peter Sanders G.V. Batz, C. Schulz, J. Speck Karlsruher Institut für Technologie Institut für Theoretische Informatik 9. Übungsblatt zu Algorithmen I im SS 2010 http://algo2.iti.kit.edu/AlgorithmenI.php {sanders,batz,christian.schulz,speck}@kit.edu Musterlösungen Aufgabe 1 (Breitensuche, 1 + 1 + 1 + 1 Punkte) Gegeben sei folgender gerichteter Graph mit der Knotenmenge {A, B, . . . , I}: D B C A H I F E G In diesem Graph werde nun eine Breitensuche durchgeführt, und zwar ausgehend vom Knoten A. a) Zählen Sie die Knoten des Graphen in einer Reihenfolge auf, in der diese von einer Breitensuche jeweils zum ersten mal berührt werden. Heben Sie im Graph außerdem alle Kanten (z.B. farbig) hervor, die Bezüglich dieser Breitensuche tree Kanten sind. b) Sind im Graph bzgl. dieser Breitensuche irgendwelche backward Kanten vorhanden? Wenn ja, heben Sie diese hervor. c) Sind im Graph bzgl. dieser Breitensuche irgendwelche cross Kanten vorhanden? Wenn ja, heben Sie diese hervor. d) Sind im Graph bzgl. dieser Breitensuche irgendwelche forward Kanten vorhanden? Wenn ja, heben Sie diese hervor. Musterlösung: Aufzählung in Reihenfolge der ersten Berührung durch Breitensuche: A, C, F, E, D, H, G, B, I. Kanten vom Typ forward können bei Breitensuche nicht auftreten. Die anderen Kantenarten sind wie in der Legende angegeben hervorgehoben: D B C A H I F E G 1 backward cross tree Aufgabe 2 (Bipartite Graphen, 2 + 6 + 2 Punkte) Ein ungerichteter zusammenhängender Graph G = (V, E) mit |V | ≥ 1 heißt bipartit, wenn die Knotenmenge V so in zwei Mengen V1 und V2 aufgeteilt werden kann, dass für jede Kante (u, v) ∈ E gilt u ∈ V1 und v ∈ V2 oder v ∈ V1 und u ∈ V2 . Mit anderen Worten existiert eine Zerlegung von V , so dass Kanten nur zwischen Knoten aus V1 und V2 bestehen, nicht aber zwischen Knoten der Vi selbst. a) Zeigen oder wiederlegen Sie jeweils die Bipartitheit der folgenden beiden Graphen! B C A B A D F E G F C H I D E b) Entwickeln Sie einen Algorithmus, der in O(n + m) entscheiden, ob ein ungerichteter zusammenhängender Graph bipartit ist. Im Fall der Bipartitheit soll der Algorithmus eine mögliche Unterteilung V1 , V2 ausgeben, sonst nicht bipartit. Geben Sie Pseudocode an. c) Erweitern Sie ihren Algorithmus, so dass im Falle der Nichtbipartitheit ein Zeuge ausgegeben wird. Hinweis: Pseudocode ist nicht zwingend erforderlich. Musterlösung: a) • Der linke Graph ist bipartit: Definiere V1 := {A, C, E}, V2 := {B, F, D}. • Der rechte Graph ist nicht bipartit: es existiert ein Kreis ungerade Länge K = hA, F, E, H, B, Ai und ein ungerichteter zusammenhängender Graph ist genau dann bipartit, wenn er keinen Kreis ungerader Länge enthält. b) Beim Entwurf nutzen wir die Eigenschaft aus, dass es zwischen zwei nicht aufeinander folgenden Leveln bei einer Breitensuche keine Kanten geben kann, da diese sonst von der Breitensuche schon vorher gefunden worden wären. D.h. man kann die Knoten der Level der Breitensuche jeweils abwechselnd in die V1 und V2 packen. Sollte die Breitensuche eine Kreuzkante finden, so ist der Graph nicht bipartit, da der Graph dann einen Kreis ungerader Länge als Teilgraph enthält. Kreise ungerader Länge sind nicht bipartit. 1: function isBipartit(G = (V [1..n], E[1..m]) 2: (parent, d) := bfs(V [1], G) // BFS in G from first node 3: V1 , V2 : Queue of Vertices 4: f [1..n]: Array of {weiß, schwarz} 5: for i := 1 to n do 6: if d[i] mod 2 = 0 then 7: V1 .push back(i) 8: f [i] = white 9: else 10: V2 .push back(i) 11: f [i] = black 12: end for 13: for i := 1 to m do 14: {u, v} := E[i] 15: if f [u] = f [v] then return “nicht bipartit” 16: end for 17: return (V1 , V2 ) 2 c) Am einfachsten ist es einen Kreis ungerader Länge auszugeben. Man kann dazu den Algorithmus aus Aufgabenstellung b) leicht modifizieren. Wenn man f [u] = f [v] gefunden hat, so startet man bei u eine Rückverfolgung der Parentzeiger bis man bei V [1] angekommen ist und hängt die dabei besuchten Knoten einschließlich u an eine Liste K an. Wir nehmen dabei zunächst vereinfachend an, dass V [1] der kleinste gemeinsame Vorgänger von u und v im BFS Baum ist. Man beachte, dass es sich bei der Kante {u,v} um eine Kreuzkante handeln muss, da G ungerichtet ist und somit in dem durch die BFS erzeugten Baum keine Forwärts- und Rückwärtskanten exisitieren können. An die Liste K werden nun in umgrehter Reihenfolge die Knoten vom Pfad v → V [1], die man wieder über das parent Array der Breitensuche erhält, angehängt. Schließlich wird noch u an K angehängt. Nun haben wir einen Kreis K = u → V [1] → v → u. Dieser hat ungerade Länge, da die Längen von u → V [1],V [1] → v entweder beide gerade oder beide ungerade sind und genau eine Kante extra nämlich die von v nach u in K enthalten ist. Sollte V [1] nun nicht der kleinste gemeinsame Vorgänger von u und v sein, so wird es noch ein wenig komplizierter, da der Pfad von V [1] zum kleinsten gemeinsamen Vorgänger von u und v nicht im Kreis enthalten sein soll. Da die beiden Knoten auf dem gleichen Level sind, kann man zum Beispiel die Parentzeiger von u und v wechselseitig verfolgen bis man den kleinsten gemeinsamen Vorgänger gefunden hat und dann entsprechend wie oben den Kreis K zusammenbauen. Aufgabe 3 (Dichte und spärliche Graphen, 2 + 2 + 2 + 2 + 2 Punkte) Eine Familie von Graphen ist eine unendliche Menge von Graphen, mit der Eigenschaft dass sich für jedes n0 ∈ N≥0 stets ein Graph mit n ≥ n0 Knoten in der Menge befindet. a) Zeigen Sie: Vollständige ungerichtete Graphen mit n Knoten haben Θ(n2 ) Kanten. b) Eine Familie von ungerichteten Graphen heiße eine Familie spärlicher Graphen, wenn jeder Graph O(n) Kanten hat bei n Knoten. Zeigen Sie: In einer Familie spärlicher Graphen liegt der maximale Knotengrad nicht notwendig in O(1). c) Eine Familie von ungerichteten Graphen heiße eine Familie gleichmäßig spärlicher Graphen, wenn jeder Knoten jedes Graphen O(1) Kanten hat bei n Knoten. Zeigen Sie: Eine Familie gleichmäßig spärlicher Graphen ist auch eine Familie spärlicher Graphen. d) Eine Familie von ungerichteten Graphen heiße eine Familie dichter Graphen, wenn jeder Graph Ω(n2 ) Kanten hat bei n Knoten. Zeigen Sie: In einer Familie dichter Graphen hat nicht unbedingt jeder Knoten eines Graphen Ω(n) Kanten bei n Knoten. e) Eine Familie von ungerichteten Graphen heiße eine Familie gleichmäßig dichter Graphen, wenn jeder Knoten jedes Graphen Ω(n) Kanten hat bei n Knoten. Zeigen Sie: Eine Familie gleichmäßig dichter Graphen ist auch eine Familie dichter Graphen. Musterlösung: a) Ein vollständiger ungerichteter Graph mit n Knoten hat n(n − 1)/2 Kanten. Dies liegt daran, dass jeder der n Knoten jeweils genau eine Kante hat zu jedem der n − 1 anderen Knoten, aber keine zu sich selbst. Allerdings zählt jede Kante für zwei Knoten, weshalb halbiert werden muss. Weiter ist 1 n(n − 1) ≤ n(n − 1) = n2 − n ≤ n2 2 und 1 1 1 2 1 2 n(n − 1) ≥ n − n = n2 2 2 2 4 3 für genügend große n. Es gilt also n(n − 1)/2 = Θ(n2 ). b) Als Gegenbeispiel geben wir eine Familie von spärlichen Graphen an: Zu jedem n enthalte die Familie genau einen ungerichteten Graph mit n ≥ 2 Knoten. Dieser habe folgende Form: 2 1 3 n Offenbar hat dieser Graph, wie von der Definition einer Familie spärlicher Graphen gefordert, O(n) Kanten. Jedoch hat Knoten 1 immer n−1 Kanten für alle n ∈ N>0 . Es ist aber n−1 6∈ O(1). Wichtig: Ein Graph mit einer festen Anzahl Knoten ist kein ausreichendes Gegenbeispiel. Da es hier um asymptotische Aussagen (O-Kalkül) geht, muss ein Gegenbeispiel von n abhängen. c) Man betrachte eine Familie gleichmäßig spärlicher Graphen. Nach Definition gibt es Konstanten c > 0 und n0 > 0, so dass alle Graphen dieser Famile mit n ≥ n0 Knoten höchstens c Kanten haben an jedem Knoten. Insgesamt hat jeder Graph der Familie mit n ≥ n0 Knoten also höchstens cn Kanten. Also haben die Graphen der Famile O(n) Kanten bei n Knoten. Somit gilt die Behauptung. d) Als Gegenbeispiel geben wir eine Familie von dichten Graphen an: Zu jedem n enthalte die Familie genau einen ungerichteten Graph mit n Knoten. Dieser bestehe aus einem vollständigen Graph mit n − 1 Knoten und einem weiteren isolierten Knoten (d.i. ein Knoten ohne Kanten). Der vollständige Teilgraph mit n − 1 Knoten hat (n − 1)(n − 2)/2 = Ω(n2 ) Kanten, also gilt das auch für den Gesamtgraph, da dieser allenfalls mehr Kanten hat. Somit ist die Definition einer Familie spärlicher Graphen erfüllt. Der isolierte Knoten hat nun 0 Kanten für alle n. Es ist aber 0 6∈ Ω(n), also gilt die Behauptung. Wichtig: Genau wie in Teilaufgabe b) ist ein Graph mit einer festen Anzahl Knoten kein ausreichendes Gegenbeispiel. e) Man betrachte eine Familie gleichmäßig dichter Graphen. Nach Definition gibt es Konstanten c > 0 und n0 > 0, so dass alle Graphen dieser Famile mit n ≥ n0 Knoten mindestens cn Kanten haben an jedem Knoten. Insgesamt hat jeder Graph der Familie mit n ≥ n0 Knoten also mindestens cn2 Kanten. Also haben die Graphen der Famile Ω(n2 ) Kanten bei n Knoten. Somit gilt die Behauptung. Zusatzaufgabe (Durchmesser von Intervallgraphen, 1 + 3 + 2 + 2 Punkte) Der Abstand zweier Knoten u, v eines ungerichteten zusammenhängenden Graphen G = (V, E) sei definiert als minP ∈P(u,v) |P | wobei P(u, v) die Menge aller Pfade zwischen u und v bezeichne und |P | die Anzahl der Kanten in P . Weiter heiße D := maxu,v∈V minP ∈P(u,v) |P | der Durchmesser von G. Es sei eine endliche Menge M von abgeschlossenen Intervallen [a, b] über R gegeben. Für ein Intervall S S I 0 = [a0 , b0 ] mit I 0 ⊆ I∈M I heiße U ⊆ M dann eine Überdeckung falls I 0 ⊆ I∈U I. Eine Überdeckung von I 0 mit der kleinstmöglichen Anzahl von Intervallen heißt minimale Überdeckung. Gegeben sei eine Liste L von n > 1 Intervallen Ii = [ai , bi ] (mit ai ≤ bi ), diese Intervalle stellen implizit einen Intervallgraphen dar. Über die Liste ist weiter nichts bekannt, außer dass der Intervallgraph zusammenhängend ist. 4 Hinweis: Die Intervalle Ii und Ij sind im Intervallgraphen durch eine Kante verbunden, falls Ii ∩Ij 6= ∅. Zum Beispiel wären die Intervalle [3, 4] und [4, 5] durch eine Kante verbunden. a) Es sei die Liste L = {[0, 3], [10, 12], [2, 8], [1, 3], [8, 11], [4, 6], [7, 9]} gegeben. Bestimmen Sie den Durchmesser des dazugehörigen Intervallgraphen. b) Es sei ā := maxi=1..n ai und b̄ := mini=1..n bi . Zeigen Sie: • Falls ā ≤ b̄ ist der Durchmesser des Intevallgraphen 1. • Falls ā > b̄ so ist der Durchmesser des Intervallgraphen um 1 größer als die Größe der minimalen Überdeckung des Intervalls I ∗ := [b̄, ā] durch Intervalle aus L. c) Geben Sie einen Algorithmus an, der den Durchmesser des durch L gegebenen Intervallgraphen in O(n log n) Schritten berechnet. Bitte erläutern Sie kurz die Korrektheit des Algorithmus und seine Laufzeit. d) Geben Sie einen Algorithmus an, der den Durchmesser des durch L gegebenen Intervallgraphen in O(d · n) Schritten berechnet. Wobei d der Durchmesser des Intervallgraphen ist. Bitte erläutern Sie kurz die Korrektheit des Algorithmus und seine Laufzeit. Musterlösung: a) Der Durchmesser ist 3. Die minimale Überdeckung von [3, 10] ist {[2, 8], [8, 11]} und damit ergibt sich der Durchmesser nach Aufgabenteil b). b) Falls ā ≤ b̄, so gilt für jedes beliebige Paar Ii , Ij von Intervallen ai ≤ bj und aj ≤ bi . O.B.d.A. gelte nun bj ≤ bi , dann ist ai ≤ bj ≤ bi und damit der Schnitt der beiden Intervalle nicht leer. Da damit jedes Paar von Intervallen durch eine Kante verbunden ist, ist der Durchmesser 1. Falls ā > b̄. Es sei Ii , Ij Intervalle mit bi < aj . Es gilt dann: 1. Für jeden Weg von Ii nach Ij im Intervallgraphen liefern die Intervalle (inneren Knoten) auf diesem Weg eine Überdeckung von [bi , aj ]. Dies gilt insbesondere auch für kürzeste Wege. 2. Jede minimale Überdeckung von [bi , aj ] enthält alle inneren Knoten eines Weges von Ii nach Ij im Intervallgraphen. Es sei p + 1 die Länge eines kürzesten Weges W von Ii nach Ij und q die Größe einer minimalen Überdeckung U von [bi , aj ]. Aus W ergibt sich eine Überdeckung von [bi , aj ] der Größe p und aus U ein Weg von Ii nach Ij der Länge ≤ q + 1. Deshalb gilt p = q. Damit ist eine minimale Überdeckung auch die Intervallfolge eines kürzesten Weges und umgekehrt. Dies gilt insbesondere auch für die Intervalle Ig = [ag , b̄] und Ih = [ā, bh ]. Sei U ∗ = {I10 , . . . , Ik0 } eine minimale Überdeckung von I ∗ so ist der Durchmesser des Intervallgraphen mindestens k +1. Da für zwei Intervalle Ii = [ai , bi ] und Ij = [aj , bj ] mit bi < aj das Intervall [bi , aj ] auch von U ∗ überdeckt wird, kann die minimale Überdeckung von [bi , aj ] nicht größer als k sein. Damit sind alle Abstände im Intervallgraphen durch k + 1 nach oben beschränkt. Daher ist der Durchmesser des Intervallgraphen höchstens k + 1. Lösungsanhang: (Für die, die es ganz genau wissen möchten.) Es sei Ii , I10 , . . . , Ik0 , Ij eine Folge von Intervallen, die einen Weg der Länge k + 1 zwischen Ii und Ij im Intervallgraphen beschreiben. Die Intervallmenge {Ii , I10 , . . . , Ik0 , Ij } stellt damit einen zusammenhängenden Intervallgraphen dar. Annahme: Es gibt ein x ∈ (bi , aj ) so dass es kein ` ∈ {1, . . . , k} mit x ∈ I`0 gibt. Da Ii ∩ I10 6= ∅ ist b01 < x, analog ist x < a0k . Es sei M< Die Menge aller Intervalle I`0 mit b0` < x und M> die Menge aller Intervalle I`0 mit x < a0` . Die Menge {I10 , . . . , Ik0 } ist disjunkte Vereinigung von M< und M> . Kein Intervall aus M< ∪ {Ii } schneidet ein Intervall aus M> ∪ {Ij }. Damit ist der Intervallgraph zu {Ii , I10 , . . . , Ik0 , Ij } jedoch nicht zusammenhängend. Widerspruch! Damit ist aber {I10 , . . . , Ik0 } eine Überdeckung von [bi , aj ]. 5 Umgekehrt sei nun U = {I10 , . . . , Ik0 } eine minimale Überdeckung von [bi , aj ]. Annahme: Der durch U ∪ {Ii , Ij } gegebene Intervallgraph hat mehr als eine Zusammenhangskomponente. Es sei Mi die Zusammenhangskomponente die Ii enthält. Es sei I`0 ein Intervall mit minimalem a in der Menge (U ∪ {Ii , Ij }) \ Mi . Wäre a0` < ai so wäre auch b0` < ai da I`0 nicht in der gleichen Zusammenhangskomponente wie Ii liegt. Damit wäre I`0 aber nicht in der minimalen Überdeckung U enthalten (analog: a0` ≤ aj ). Daher ist bi < a0` und auch b0r < a0` für alle Intervalle b̂0 +a0 Ir0 ∈ Mi . Es sei b̂0 das maximale b aller Intervalle in Mi . Damit ist x := 2 ` in keinem Intervall aus U ∪ {Ii , Ij } enthalten. Da x ∈ (bi , aj ) muss es in der Überdeckung U aber ein Intervall geben, dass x enthält. Widerspruch! Damit ist die Überdeckung zusammenhängend, und enthält einen Weg von Ii nach Ij im Intervallgraphen. c) Algorithmus: 1. Lese die Liste der Intervalle als Zahlenpaare in ein Array L der Größe n + 1 ein, und bestimme gleich b̄ und ā wi in Aufgabenteil b). Der Array enthält an jeder Stelle von 1 bis n ein 2-Tupel von reellen Zahlen (a, b). An der letzten Stelle füge (∞, ∞) ein. 2. Falls ā ≤ b̄ return 1. 3. Sortiere L nach den a. 4. Setze c := b̄ und j := 1. 5. Setze i := j. 6. While L[j].a ≤ c do j := j + 1. 7. Wähle aus den Intervallen L[i], . . . , L[j − 1] eines mit maximalem b und gib das Intervall aus. 8. Setze c auf das maximale b. Falls c < ā gehe zu 5., sonst terminiere. Laufzeit: Die Laufzeit von Zeile 1. liegt in O(n), die von Zeile 2. und 4. in O(1). Die Laufzeit von Zeile 3. liegt in O(n log n) (z.B. mit Mergesort). Bleibt noch die Schleife der Zeilen 5.-8.. Wenn d der Durchmesser des Intervallgraphen ist, so wird die Schleife maximal d − 1 mal ausgeführt. In Zeile 5. und 8. werden in jedem Durchlauf die gleichen Operationen mit konstanter Laufzeit ausgeführt. Da d < n tragen die Zeilen 5. und 8. maximal O(n) zur Laufzeit bei. Für alle Durchläufe zusammen wird in den Zeilen 6. und 7. für jedes Element aus L eine konstante Anzahl von Operationen ausgeführt. Damit tragen die Zeilen 6. und 7. maximal O(n) zur Laufzeit bei. Korrektheit: Zu zeigen ist wegen b) nur noch, dass der Algorithmus im Fall ā > b̄ eine minimale Überdeckung des Intervalls [b̄, ā] findet. Dazu überlegt man sich (Induktion!), dass nach der `-ten Ausführung der äußeren Schleife das maximale mit ` Intervallen überdeckbare Teilintervall [b̄, c] von [b̄, ā] berechnet wurde. Wenn es eine minimale Überdeckung von [b̄, ā] mit k Intervallen gibt, so wird eine Solche auch im k-ten Schritt gefunden. d) Algorithmus: 1. Lese die Liste der Intervalle als Zahlenpaare in ein Array L der Größe n + 1 ein, und bestimme gleich b̄ und ā wi in Aufgabenteil b). Der Array enthält an jeder Stelle von 1 bis n ein 2-Tupel von reellen Zahlen (a, b). An der letzten Stelle füge (∞, ∞) ein. 2. Falls ā ≤ b̄ return 1. 3. Setze c := b̄. 4. Gehe durch ganz L und schreibe alle Intervalle mit a ≤ c in ein Array L0 . 5. Wähle aus den Intervallen in L0 eines mit maximalem b und gib das Intervall aus. 6. Setze c auf das maximale b. Falls c < ā gehe zu 4., sonst terminiere. 6 Laufzeit: Die Laufzeit von Zeile 1. liegt in O(n), die von Zeile 2. und 3. in O(1). Bleibt noch die Schleife der Zeilen 4.-6.. Wenn d der Durchmesser des Intervallgraphen ist, so wird die Schleife maximal d − 1 mal ausgeführt. In Zeile 6. werden in jedem Durchlauf die gleichen Operationen mit konstanter Laufzeit ausgeführt. Damit trägt die Zeile 6. maximal O(d) zur Laufzeit bei. Für jeden Durchlauf wird in den Zeilen 4. und 5. ein Array der maximalen Größe n + 1 durchlaufen. Dabei werden für jeden Schritt eine konstante Anzahl von Operationen ausgeführt. Damit tragen die Zeilen 4. und 5. maximal O(d · n) zur Laufzeit bei. Korrektheit: Analog zu c). 7