Musterlösung 6 - id.ethz.ch

Werbung
ETH Zürich
Institut für Theoretische Informatik
Prof. Dr. Angelika Steger, Prof. Dr. Thomas Holenstein
Ralph Keusch
HS 2015
Algorithmen und Komplexität
Lösungsvorschlag zu Übungsblatt 6
Lösungsvorschlag zu Aufgabe 1
Wir lösen die Aufgaben, indem wir den minimalen Spannbaum T von G so umbauen, dass ein
minimaler Spannbaum T 0 von G 0 entsteht. Wir fassen G 0 auf als G mit einer modifizierten Gewichtsfunktion w0 : G → N. Nach Annahme haben wir w0 (e) < w(e) für die modifizierte Kante
e und w0 ( f ) = w( f ) für alle anderen Kanten f .
Wenn man e zur Kantenmenge von T hinzufügt, erhält man genau einen Kreis C. Es bezeichne
emax die Kante aus C mit dem grösstem Gewicht unter w0 . Dann ist T 0 := T ∪ {e} \ {emax } ein
Spannbaum von G, da durch Entfernen einer Kante aus C der Graph wieder kreisfrei wird und
zusammenhängend bleibt. (Es ist möglich, dass emax gleich der modifizierten Kante e ist - dann
ist T 0 = T.)
Lemma 1. T 0 ist ein minimaler Spannbaum von G unter w0 .
e irgendein Spannbaum von G. Wir zeigen, dass w0 ( T
e ) ≥ w 0 ( T 0 ).
Beweis. Sei T
e die Kante e nicht enthält, gilt w0 ( T
e) = w( T
e) ≥ w( T ) = w0 ( T ) = w0 ( T 0 ) +
• Wenn T
0
0
0
0
w (emax ) − w (e) ≥ w ( T ) wegen der Annahme, dass T minimaler Spannbaum von G unter
w ist und nach Konstruktion von T 0 .
e die Kante e enthält, entfernen wir diese und erhalten zwei getrennte Komponenten
• Wenn T
e
von T. Eine der restlichen Kanten von C, nennen wir sie f , verbindet diese Komponenten
e1 mit Gewicht w0 ( T
e1 ) = w0 ( T
e) − w0 (e) +
und vervollständigt so einen neuen Spannbaum T
e1 ) ≥ w0 ( T ) wegen der Annahme, dass T minimaler Spannw0 ( f ). Wieder haben wir w0 ( T
baum von G unter w ist. Es folgt
e) = w0 ( T
e1 ) − w0 ( f ) + w0 (e) ≥ w0 ( T ) − w0 (emax ) + w0 (e) = w0 ( T 0 ).
w0 ( T
Algorithmisch lässt sich der Graph T 0 leicht aus T und e konstruieren: Mit Tiefensuche in T ∪ {e}
findet man den Kreis C in Zeit O(|V |), und die schwerste Kante emax in C findet man in Zeit
O(| E(C )|) = O(|V |).
Bemerkung: Die Tiefensuche hat einen Kreis gefunden, wenn sie ausgehend von einem Knoten v
auf einen Nachbarn u ∈ Γ(v) mit pred[u] 6= nil stösst. Dann bilden pred[v], pred[ pred[v]], . . . , u
den Kreis. Die Laufzeit dieses letzten Schrittes ist maximal O(|V |).
Es ist auch möglich mit Breitensuche dasselbe Resultat zu erhalten: Sobald man einen Nachbarn
u ∈ Γ(v) mit pred[u] 6= nil findet, folgt man den beiden Pfaden (u, pred[u], pred[ pred[u]], . . . ) und
(v, pred[v], pred[ pred[v]], . . . ) (parallel!), um den ersten gemeinsamen Knoten w zu finden. Dann
ist (u, pred[u], . . . , w, . . . , pred[v], v) ein Kreis.
Lösungsvorschlag zu Aufgabe 2
(a) Die aufsteigend sortierte Liste (1, 2, . . . , n) hat keine Inversionen. Da die Anzahl Inversionen
nicht negativ sein kann, ist das minimal.
In der absteigend sortierten Liste (n, n − 1, . . . , 1) ist jedes Paar ( ai , a j ) mit i 6= j eine Inversion
n·(n−1)
Inversionen. Da es nicht mehr Inversionen als solche Paare geben
und es gibt somit
2
kann, ist das die maximal mögliche Anzahl.
1
n·(n−1)
Paare
(b) Der Algorithmus verwendet einen Zähler c, der anfangs 0 ist. Dann geht er alle
2
( ai , a j ) mit i 6= j durch und prüft für jedes ob es eine Inversion ist. Falls ja, setzt er c := c + 1
und sonst ändert er c nicht. Am Ende wird c ausgegeben. Die Korrektheit ist offensichtlich
n·(n−1)
und die Laufzeit ist O( 2 ) = O(n2 ).
(c) Seien L` := ( a1 , a2 , . . . , ad n e ) die linke und Lr := (b1 , b2 , . . . , bb n c ) die rechte Hälfte der Liste
2
2
L, und beide Hälften der Liste seien aufsteigend sortiert. Wir modifizieren den Merge-Schritt
von Mergesort, um eine aufsteigend sortierte Liste aller Elemente L0 zu erhalten und gleichzeitig die Anzahl der Inversionen in L zu zählen. Zur Erinnerung: Mergesort verwendet zwei
Pointer i für L` und j für Lr . Zu Beginn ist i := 1 und j := 1 und L0 die leere Liste. Falls nun
ai < b j ist, wird ai an L0 angehängt und i := i + 1 gesetzt. Andernfalls wird b j an die Liste
angehängt und j := j + 1 gesetzt. Dies wird wiederholt, bis alle Elemente in L0 eingeordnet
wurden.
Wir verwenden nun zusätzlich einen Zähler c, der die Inversionen zählt. Im Fall ai < b j
ändern wir c nicht, aber im Fall ai ≥ b j erhöhen wir c um die Anzahl der verbleibenden
Elemente in L` , d.h. c := c + ( n2 − i + 1).
Korrektheit: Wir argumentieren, dass jede Inversion genau einmal gezählt wird. Immer wenn
ein b j an L0 angehängt wird, stellt b j mit allen verbleibenden ak mit k ≥ i eine Inversion dar.
Für die ak mit k < i stellt b j keine Inversion dar. Somit werden alle Inversionen in denen b j
vorkommt gezählt. Das geschieht für jedes b j genau einmal, da es genau einmal an die Liste
L0 angehängt wird.
Laufzeit: Da das erhöhen von c jeweils nur einen Schritt benötigt, bleibt die Laufzeit des
Merge-Schritts O(n).
(d) Wir verwenden den Mergesort Algorithmus und modifizieren den Merge-Schritt wie in (c)
beschrieben. Daraus erhalten wir den Algorithmus M ERGE - AND -C OUNT, der für zwei sortierte Listen ( L` , Lr ) die Anzahl Inversionen c und die sortierte Liste L0 zurückgibt.
Algorithm 1 S ORT- AND -C OUNT ( L)
if | L| = 1 then
return (0, L)
end if
if L > 1 then
Teile die Liste in zwei Hälften L` and Lr mit | L` | = n2 und | Lr | = n2
(c` , L` ) = S ORT- AND -C OUNT ( L` )
(cr , Lr ) = S ORT- AND -C OUNT ( Lr )
(c, L0 ) = M ERGE - AND -C OUNT ( L` , Lr )
end if
return (c + c` + cr , L0 )
Korrektheit: Da der Algorithmus M ERGE - AND -C OUNT gemäss (c) in jedem Merge-Schritt die
Inversionen der sortierten Listen korrekt zählt, und man die Inversionen zählen kann indem
man zuerst die Inversionen der beiden Hälften zählt, diese sortiert und dann die Inversionen
der sortierten Liste addiert, folgt die Korrektheit.
Laufzeit: Da M ERGE - AND -C OUNT in Zeit O(n) läuft folgt aus der Laufzeitanalyse von Mergesort, dass die Laufzeit von S ORT- AND -C OUNT O(n log n) ist.
Lösungsvorschlag zu Aufgabe 3
Es bezeichne ZG REEDY und ZOPT den Wert der Greedy-Lösung bzw. der optimalen Lösung. Zu
2
zeigen ist, dass es für jedes (beliebig grosse) C ≥ 1 eine Instanz gibt, für die gilt
ZOPT
ZG REEDY
≥ C.
Dazu seien ein Rucksack der Kapazität B ≥ 2C und Objekte I = {1, 2} mit p1 = 2, w1 = 1
und p2 = w2 = B gegeben. Dann liefert der Greedy-Algorithmus die Lösung IG REEDY = {1} mit
ZG REEDY = 2. Die optimale Lösung dagegen ist IO PT = {2} mit ZO PT = B. Es gilt also
B
ZOPT
= ≥ C.
ZG REEDY
2
Der Greedy-Algorithmus kann also für das Rucksackproblem beliebig schlecht sein. Der Grund
dafür ist, dass die gierige Strategie zu kurzsichtig ist und es möglich ist, dass dadurch später viel
Platz im Rucksack ungenutzt bleibt.
3
Herunterladen