Musterlösung - Aufgabenblatt 2 Aufgabe 1 Um den Algorithmus von Bellman-Ford anzuwenden, modellieren wir das Problem zunächst als ein Kürzeste-Wege-Problem in einem Graphen. Dazu nummerieren wir die Gegenstände: 1 = Schlafsack, 2 = Taschenmesser, . . . , 5 = Isomatte und bezeichnen das Volumen des i-ten Gegenstands mit ai und seinen Nutzen mit ci . Wie in der Vorlesung beschrieben hat der Graph dann Knoten der Form (i, x) mit i ∈ {0, 1, . . . , 6} und x ∈ {0, 21 , 1, 32 , 2, 25 }. Es gibt drei Sorten von Kanten: • Kanten der Form ((i − 1, x), (i, x)) bekommen die Länge 0, • Kanten der Form ((i − 1, x), (i, y)) mit y − x = ai haben Länge −ci , • Kanten der Form ((5, x), (6, 52 )) haben Länge 0. Wir erhalten dann folgenden Graphen. (Kanten der Länge 0 sind grau gezeichnet, alle anderen Kanten tragen ihr Gewicht als Label.) 5/2 -4 2 -3 -4 -4 3/2 -3 -4 -4 1 -3 -4 -4 1/2 -3 -5 -4 -5 -4 -5 -4 -4 -4 0 0 1 2 3 4 5 6 Kürzeste (0, 0)-(6, 52 )-Wege in diesem Graphen entsprechen optimalen Rucksackpackungen. Da wir uns nur für (0, 0)-(6, 25 )-Wege interessieren, können wir alle Kanten ignorieren, die nicht auf solchen Wegen liegen. Das heißt, wir können den Algorithmus von Bellman-Ford (mit s = (0, 0)) auf folgenden reduzierten Graphen anwenden: 5/2 -3 2 -4 -5 -4 3/2 -3 -5 -3 -5 -4 1 -4 -4 1/2 -4 -4 0 0 1 2 3 4 5 6 Der Algorithmus setzt zunächst die Werte der Funktion d0 wie folgt: d0 ((0, 0)) = 0, d0 ((i, x)) = ∞ für i, x 6= 0. Dann beginnt die for-Schleife, in der jeweils für den wachsenden Parameter k die Funktion dk+1 bestimmt wird und dabei auch die Funktion g: k = 0: Nachdem zunächst d1 = d0 gesetzt wird, wird dann für jede Kante ((i, x), (j, y)) getestet, ob d1 ((j, y)) > d0 ((i, x)) + l((i, x), (j, y)). Ist dies der Fall, wird d1 ((j, y)) = d0 ((i, x)) + l((i, x), (j, y)) und g((j, y)) = (i, x) gesetzt. Da ∞ = d1 ((1, 0)) > d0 ((0, 0))+l((0, 0), (1, 0)) = 0, erhalten wir d1 ((1, 0)) = 0 und g((1, 0)) = (0, 0). Ebenso bekommen wir d1 ((1, 32 )) = −4 und g((1, 23 )) = (0, 0). Alle anderen Kanten haben als Startknoten einen Knoten (i, x) mit d0 ((i, x)) = ∞, die if-Bedingung wird also für keine andere Kante erfüllt. Wir erhalten: d1 ((0, 0)) = 0, d1 ((1, 0)) = 0, d1 ((1, 32 )) = −4, d1 ((i, x)) = ∞ sonst. Zudem haben wir g((1, 0)) = (0, 0) und g((1, 23 )) = (0, 0). Bevor wir die folgenden Schritte der for-Schleife betrachten, überlegen wir uns, dass sich die Funktionen dk und dk+1 nur auf Knoten der Form (k + 1, x) unterscheiden können und ansonsten übereinstimmen. Dies folgt aus der Struktur des Graphen: Nach Vorlesung ist dl ((i, x)) die minimale Länge einer (0, 0)-(i, x)-Kantenfolge die ≤ l Kanten enthält. In unserem Graphen enthält jede (0, 0)-(i, x)-Kantenfolge, wenn denn eine existiert, genau i Kanten. Damit gilt: ( ∞ für l < i, dl ((i, x)) = di ((i, x)) für l ≥ i, was obige Behauptung zum Vergleich der Funktionen dk und dk+1 beweist. Im k-ten Durchlauf der for-Schleife werden also nur Werte von Knoten der Form (k + 1, x) geändert. Wir schränken unsere Beschreibung des Algorithmus auf diese Knoten ein. k = 1: Wie auch im ersten Schritt (k = 0) werden in diesem Schritt alle zu betrachtenden Knoten von genau einer Kante erreicht, die den neuen Wert des Knotens bestimmt. Es ergibt sich: d2 ((0, 0)) = 0, d2 ((1, 0)) = 0, d2 ((1, 32 )) = −4, d2 ((2, 0)) = 0, d2 ((2, 32 )) = −4, d2 ((2, 21 )) = −4, d2 ((2, 2)) = −8, d2 ((i, x)) = ∞ sonst. Zudem bekommen wir g((2, 0)) = g((2, 12 )) = (1, 0) und g((2, 32 )) = g((2, 2)) = (1, 32 ). k = 2: Bis auf den Knoten (3, 32 ) werden auch hier alle Knoten von genau einer Kante erreicht. Für Knoten (3, 23 ) werden beide Kanten ((2, 12 ), (3, 23 )) und ((2, 32 ), (3, 32 )) getestet. Da d2 ((2, 21 )) + l((2, 12 ), (3, 23 )) = −4 + (−3) = −7 den kleineren Wert liefert als d2 ((2, 23 )) + l((2, 32 ), (3, 32 )) = −4 + 0 = −4, bestimmt die erste der beiden Kanten den Wert von (3, 32 ). Wir bekommen: d3 ((0, 0)) = 0, d3 ((1, 0)) = 0, d3 ((1, 32 )) = −4, d3 ((2, 0)) = 0, d3 ((2, 32 )) = −4, d3 ((2, 21 )) = −4, d3 ((2, 2)) = −8, d3 ((3, 32 )) = −7, d3 ((3, 0)) = 0, d3 ((3, 21 )) = −4, d3 ((3, 2)) = −8, d3 ((3, 1)) = −3, d3 ((3, 52 ) = −7, d3 ((i, x)) = ∞ sonst. Zudem haben wir g((3, 0)) = g((3, 1)) = (2, 0), g((3, 21 )) = g((3, 32 )) = (2, 12 ), g((3, 52 )) = (2, 32 ) und g((3, 2)) = (2, 2). Wir halten das Ergebnis bildlich fest. Der Wert von d3 eines Knotens steht neben dem Knoten, wenn er nicht ∞ ist. Die durch die Funktion g bestimmten Kanten sind schwarz. -7 5/2 -8 2 -4 3/2 -4 -3 -4 -7 -3 1 -4 -4 1/2 0 0 0 0 1 -4 -8 -3 0 -3 -4 -5 -4 -5 -4 -5 -4 0 2 -4 3 4 5 6 k = 4: Die unteren drei Knoten (4, 0), (4, 12 ) und (4, 1) werden wieder nur von einer Kante erreicht. Die anderen drei Knoten werden von je zwei Kanten erreicht. Für diese werden beide Möglichkeiten getestet und die bessere festgehalten. Diesmal beschreiben wir das Ergebnis nur bildlich: 5/2 -8 2 -4 3/2 -4 -3 -4 -3 -4 -4 0 0 0 0 1 -4 0 2 -8 -8 -9 -7 1 1/2 -7 -3 -3 -4 0 3 -5 -5 -5 -7 -4 -3 -4 -4 -4 0 -4 4 5 6 k = 5: Die unteren zwei Knoten (5, 0) und (5, 21 ) werden wieder nur von einer Kante erreicht. Die anderen vier Knoten werden von je zwei Kanten erreicht. Für diese werden beide Möglichkeiten getestet und die bessere festgehalten. Wir beschreiben das Ergebnis wieder nur bildlich: 5/2 -8 2 -4 3/2 -4 -3 -4 -3 -4 -4 0 0 0 0 1 -4 -8 -11 -8 -9 -9 -7 -4 -8 -3 -4 -4 -4 -4 -4 0 -4 0 -7 1 1/2 -7 -3 0 -3 -4 -5 -5 -5 0 2 3 4 5 6 k = 5: Hier betrachten wir nur den Knoten (6, 52 ), der von sechs Kanten erreicht wird, die je Länge 0 haben. Den kürzesten Weg liefert also die Kante, deren Startknoten den kleinsten Wert hat. Das ist der Knoten (5, 52 ). Das Ergebnis bildlich: 5/2 -8 2 -4 3/2 -4 -3 -4 -3 -4 1/2 0 0 0 0 1 -4 0 2 -8 -11 -8 -9 -9 -7 -4 -8 -3 -4 -4 -4 -4 -4 0 -4 0 -7 1 -4 -7 -3 -3 -4 0 3 -5 -5 -5 4 5 -11 6 Die for-Schleife läuft noch bis k = 34. Nach unserer anfänglichen Beobachtung verändern sich die Werte der Funktionen dk jedoch nicht mehr. Dies ist also das Endergebnis. Die optimale Auswahl von Gegenständen für unseren Rucksack erhalten wir, indem wir den (schwarzen) Pfad, der zum Knoten (6, 52 ) führt zurück verfolgen und für jede nicht-horizontale Kante den Gegenstand, der dem Endknoten entspricht einpacken: Isomatte, Kekse und Taschenmesser. Zusammen ergeben diese Gegenstände einen Nutzen von 11 und haben ein Volumen von 2, 5`. Aufgabe 2 Für einen gerichteten Graphen D = (V, A) und Knoten s, t ∈ V , so dass es einen s-t-Weg gibt, wollen wir zeigen, dass die minimale Anzahl von Kanten in einem s-t-Weg gleich dem folgenden Maximum ist: max φ(t) − φ(s) φ:V →Z (1) φ(w) − φ(v) ≤ 1 für alle (v, w) ∈ A. Beweis. min ≥ max: Sei φ : V → Z eine Funktion, die das Maximum in (1) annimmt und sei P = (v0 , a1 , v1 , . . . , al , vl ), v0 = s, vl = t, ein minimaler s-t-Weg. Dann gilt: max = φ(t) − φ(s) = l X φ(vi ) − φ(vi−1 ) ≤ l = min, i=1 wobei die Ungleichung gilt, da nach Wahl von φ jeder Summand höchstens den Wert 1 hat. min ≤ max: Die grundlegende Idee in diesem Teil des Beweises ist, eine Funktion φ0 : V → Z anzugeben, die φ0 (w) − φ0 (v) ≤ 1 für alle (v, w) ∈ A erfüllt und für die φ0 (t) − φ0 (s) = min gilt. Falls eine solche Funktion φ0 existiert, gilt nämlich: min = φ0 (t) − φ0 (s) ≤ max, da φ0 eine der Funktionen ist, über die wir maximieren. Es bleibt die Existenz einer solchen Funktion zu zeigen. Sei a = |A| die Anzahl der Kanten in D. Wir definieren dann die Funktion φ0 : V → Z wie folgt: ( min. Anzahl Kanten in einem s-v-Weg, falls so ein Weg existiert, φ0 (v) = a sonst. Sei (v, w) ∈ A eine Kante. Jeder s-v-Weg kann durch (v, w) zu einem s-w-Weg verlängert werden (s. Bild). Gibt es also einen s-v-Weg, so ist der s-w-Weg mit minimaler Kantenanzahl um höchstens eine Kante länger als der entsprechende s-v-Weg. Es gilt also φ0 (w) − φ0 (v) ≤ 1. Gibt es keinen s-v-Weg, dann gilt φ0 (v) = a. Also ist φ0 (w) − φ0 (v) ≤ a − a = 0 ≤ 1. Die Funktion φ0 erfüllt also die erste der gewünschten Bedingungen. Zudem gilt nach Definition von φ0 : φ0 (t) − φ0 (s) = min −0 = min v s w