Muster Heim. 07

Transcription

Muster Heim. 07
SoSe 2015
C. Sohler
J. Flake, A. Krivo²ija
B. Rudak, V.Volz
DAP2 Heimübung 7
Ausgabedatum: 15.05.15 Abgabedatum: Fr. 22.05.15 12 Uhr
(Dynamische Programmierung)
Wir haben uns schon mit dem Problem der
kennengelernt. Diesmal wollen wir dieses Problem mittels dynamischer Programmierung
lösen. Wir wiederholen erst das Problem:
Aufgabe 7.1 (5 Punkte):
längsten ansteigenden, zusammenhängenden Teil-
folge
A[1..n] von ganzen Zahlen. Gesucht ist die Länge eines maximalen Teilar1 ≤ i ≤ j ≤ n und der Eigenschaft A[i] < A[i + 1] < . . . < A[j].
Gegeben ist ein Array
rays
A[i..j]
mit
a) Finden Sie eine rekursive Form für die Länge des maximalen zusammenhängenden ansteigenden Teilarrays, das in A[i] endet. Beschreiben Sie Ihre rekursive Form mit eigenen
Worten.
b) Geben Sie (in Pseudocode) einen auf dynamischer Programmierung beruhenden Algorithmus an, der die Länge des maximalen zusammenhängenden ansteigenden Teilarrays
berechnet und zurückgibt.
c) Zeigen Sie die Korrektheit der in Teilaufgabe a) angegebenen rekursiven Form.
d) Analysieren Sie die Laufzeit Ihres Algorithmus.
Lösung:
a) Sei B[i] die Länge des maximalen zusammenhängenden ansteigenden Teilarrays, das in
A[i] endet. Im trivialen Fall ist B[1] = 1 (ein Array von einem Element). Wenn i > 1 ist,
kann das Array, das in A[i − 1] endet, entweder fortgesetzt werden (wenn A[i − 1] < A[i])
oder ein neues Array angefangen wird. Deswegen gilt es folgende rekursive Beziehung:


falls i = 1
1
B [i] = B[i − 1] + 1 falls i > 1 und A[i − 1] < A[i] .


1
sonst
Die länge des gesuchten Teilarrays ist max B[i].
1≤i≤n
1
b) Auf der Basis der rekursiven Denition ergibt sich das folgende dynamische Programm
zur Berechnung von minimalen Kosten:
LaengsteTeilfolge(Array A):
1 n ← length(A)
2 B ← new Array [1..n]
3 B[1] ← 1
4 for i ← 2 to n do
5
if A[i − 1] < A[i] then
6
B[i] ← B[i − 1] + 1
7
else
8
B[i] ← 1
9 return
max1≤i≤n {B[i]}
c)
Beh. B[i] enthält die Länge der längsten ansteigenden, zusammenhängenden Teilarray,
das in A[i] endet.
I.A. Wenn i = 1 ist, enthält das Array A[1..1] nur ein Element und die Länge des
längsten Arrays ist 1. Somit gilt die Behauptung im I.A.
I.V. Für beliebiges aber festes i gelte die Behauptung.
I.S. Wenn A[i] ≥ A[i + 1] ist, kann ein Array, das in A[i + 1] endet, nicht A[i] enthalten,
somit kann es nicht länger als 1 sein. D.h. B[i + 1] ist korrekt. Wenn A[i] < A[i + 1]
ist, kann ein ansteigendes Array, das in A[i] endete, durch A[i+1] fortgesetzt werden.
Da nach der I.V. in B[i] die Länge des längsten solchen Arrays gespeichert wurde,
wird dieses Array durch A[i + 1] um ein Element gröÿer, und das ist auch das längste
ansteigende zusammenhängende Array, das in A[i+1] endet. Seine Länge ist B[i]+1,
was korrekt berechnet wurde.
Somit die Behauptung gilt für alle natürliche Zahlen i.
d) Ein Array der Länge n zu erzeugen braucht man O(n) Laufzeit. Die Schleife in den Zeilen
4-8 braucht auch O(n) Rechenschritte. Das Minimum eines Arrays der Länge n zu nden
braucht O(n) Rechenschritte. Restliche Anweisungen brauchen konstanten Laufzeit, was
bedeutet dass gesamte Laufzeit dieses Algorithmus O(n) ist.
(Dynamische Programmierung)
Daniela möchte gern das neue Pfanneset kaufen, das es im Supermarkt für 50 Bonuspunkte
günstig zu erwerben gibt. Leider hat sie aktuell keine Bonuspunkte. Im Supermarkt gibt es n
Produkte zu kaufen. Produkt i bringt b Bonuspunkte und kostet p Euro. Zusätzlich gibt es
eine Beschränkung, dass alle gekauften Produkte unterschiedlich sein müssen. Daniela möchte
jetzt herausnden, wie teuer es für sie wird, 50 Bonuspunkte zu sammeln.
Entwirf einen Algorithmus, der die billigste Auswahl von Produkten berechnet, für die Daniela
mindestens 50 Bonuspunkte erhält.
Aufgabe 7.2 (5 Punkte):
i
i
2
a) Wir bezeichnen mit A(i, j) die minimalen Kosten, die Daniela bezahlen muss um mit
einer Auswahl aus den ersten i Produkten mindestens j Bonuspunkte zu erhalten. Geben
Sie ein rekursive Beziehung für A(i, j) und alle Werte i = 0, . . . , n und j ≤ 50 an. Denken
Sie insbesondere an die Basisfälle.
b) Geben Sie einen Algorithmus in Pseudocode an, der das Problem basierend auf der rekursiven Beziehung mit dynamischer Programmierung löst.
c) Beweisen Sie die Korrektheit der rekursiven Formulierung in 1, d.h. dass A(i, j) nach Ihrer
Formel wirklich den optimalen Wert für das dort beschriebene Teilproblem enthält.
Lösung:
a) Wenn Daniela 0 Punkte sammeln muss, ist der Preis dazu 0, unabhängig davon, welche
Produkte zur Verfügung stehen. Wenn sie mehr als 0 Punkte sammeln muss, aber keine
Produkte zur Auswahl stehen, ist das unmöglich und der Preis bezeichnen wir mit ∞.
Da Daniela nicht genau j Punkte sammeln muss, sondern darf j Punkte überschreiten,
dürfen wir sagen, dass der Preis für A(i, j) wenn j < 0 ist (d.h. negative Punkteanzahl)
Null ist. Sonst betrachten wir zwei Fälle: entweder wählt Daniela das Produkt j oder
wählt sie es nicht. Deswegen gilt es folgende rekursive Beziehung:


0
falls i = 0, j = 0





falls i = 0, j > 0
∞
A (i, j) = 0
falls i > 0, j ≤ 0



min{A(i − 1, j), A(i − 1, j − b(i)) + p(i)} falls i ≥ 1, j ≥ b(i)



min{A(i − 1, j), p(i)}
falls i ≥ 1, j < b(i)
Der letzte Fall ist in vorletzten enhalten, aber wegen Einfachkeit wurde nochmals betrachtet. Die minimale Kosten für 50 Punkte werden durch A(n, 50) berechnet.
b) Auf der Basis der rekursiven Denition ergibt sich das folgende dynamische Programm
zur Berechnung von minimalen Kosten:
Punktesammlung(Array B, Array P ):
1 n ← length(B )
2 A ← new Array [0..n, 0..50]
3 for i ← 0 to n do
4
A[i, 0] ← 0
5 for j ← 1 to 50 do
6
A[0, j] ← ∞
7 for i ← 1 to n do
8
for j ← 1 to 50 do
9
if j ≥ B[i] then
10
A[i, j] ← min{A[i − 1, j], A[i − 1, j
11
else
12
A[i, j] ← min{A[i − 1, j], P [i]}
13 return
A[n, 50]
3
− B[i]] + P [i]}
c) Wir geben zwei möglichen Beweisansätze an.
Beweis 1.
enthält die minimale Kosten um mindestens j Punkte zu sammeln, wenn nur
die Produkte 1..i zum Auswahl stehen, für alle i ∈ N und alle j ∈ Z.
Wir führen ein Beweis per vollständiger Induktion nach i.
I.A. Wenn i = 0 ist, haben wir keine Produkte zur Auswahl. Dann wenn j ≤ 0 Punkte
zu sammeln sind, müssen wir nichts bezahlen, und minimale Preis ist gleich 0. Wenn
wir j > 0 Punkte brauchen, können wir das nicht tun. Die minimale Kosten sind
dann unendlich groÿ, d.h. A[i, j] = ∞. Die Behauptung gilt somit für i = 0.
I.V. Für beliebiges aber festes i gelte es dass A[i, j] der minimale Preis um j Punkte zu
sammeln mit ersten i Produkte berechnet, für alle j ∈ Z.
I.S. Wenn j ≤ 0, gilt es wieder dass A[i + 1, j] = 0 der minimale Preis ist. Sei jetzt
j > 0. Wir nehmen an, dass A[i + 1, j] nicht die minimale Kosten sind, um j Punkte
zu sammeln, wenn die Produkte 1..i + 1 zur Verfügung stehen. Das bedeutet dass
es ein kleinere Wert v < A[i + 1, j] gibt, den die Kosten um mindestens j Punkte
zu sammeln entspricht, wenn die Produkte 1..i + 1 zur Auswahl stehen. Es kann
entweder sein, dass wir das Produkt i + 1 auswählen oder nicht.
Wenn wir das Produkt i + 1 in v nicht auswählen würden, hätten wir dass v <
A[i + 1, j] = A[i, j] ist. Das widerspricht der Optimalität von A[i, j], was in I.V.
angenommen wurde.
Wenn wir das Produkt i + 1 in v auswählen würden, erhalten wir dazu B[i + 1]
Punkte und bezahlen den Preis P [i + 1] dafür. Aber dann wäre v − P [i + 1] <
A[i + 1, j] − P [i + 1] ≤ A[i, j − B[i + 1]] + P [i + 1] − P [i + 1] = A[i, j − B[i + 1].
Nach der I.V. ist A[i, j − B[i + 1] die minimale Kosten für alle Punktesummen (somit
auch für j − B[i + 1], was 0 ist, wenn j < B[i + 1]). Wir haben eine kleinere Preis
v − P [i + 1] als Kosten um j − B[i + 1] zu sammeln gekriegt, wenn die Produkte 1..i
zur Auswahl stehen. Das ist aber ein Widerspruch zur I.V. Somit ist auch A[i + 1, j]
optimal für alle j ∈ Z.
Die Behauptung gilt für alle natürliche Zahlen i und für alle j ∈ Z.
Beh. A[i, j]
0
Beweis 2.
berechnet für alle i ∈ N und alle j ∈ Z die minimalen Kosten, um mit einer
Auswahl aus den ersten i Produkten mindestens j Bonuspunkte zu erhalten.
Wir führen den Beweis durch vollständige Induktion über i.
Beh. A(i, j)
0
Es stehen keine Produkte zum Kauf zur Verfügung, zwei Fälle sind dann zu unterscheiden:
j ≤ 0: Es werden keine Bonuspunkte mehr benötigt, daher müssen auch keine Produkte
mehr gekauft werden. Der Preis dafür ist 0 = A(0, 0) = A(i, j).
4
I.A. i = 0:
Es werden noch Bonuspunkte benötigt, aber es stehen keine Produkte mehr zur
Verfügung, j Bonuspunkte können also nicht erzielt werden. Daher sind die minimalen Kosten dann unendlich groÿ: ∞ = A(0, j) = A(i, j)
I.V. A(i, j) berechnet für beliebiges aber festes i und alle j ∈ Z den minimalen Preis, um mit
einer Auswahl aus den ersten i Produkten mindestens j Bonuspunkte zu erhalten.
I.S. i → i + 1: Es stehen i + 1 > 0 Produkte zur Verfügung, es sind wieder zwei Fälle zu
unterscheiden:
j ≤ 0: Es werden keine Bonuspunkte mehr benötigt, daher müssen auch keine Produkte
mehr gekauft werden. Der minimale Preis dafür ist 0 = A(i + 1, j) für 1 ≤ i + 1 ≤ n
und j ≤ 0.
j > 0: Es werden noch Bonuspunkte benötigt. Dann ist zu entscheiden, ob das Produkt
i + 1 gekauft werden soll oder nicht. Wird es gekauft, gilt A(i + 1, j) = p + A(i, j −
b ). Wird es nicht gekauft, gilt A(i + 1, j) = A(i, j). A(i, j − b ) und A(i, j)
berechnen nach I.V. die minimalen Kosten, um mit den ersten i Produkten j − b
bzw. j Bonuspunkte zu erzielen. Mit A(i + 1, j) = min{p + A(i, j − b ), A(i, j)}
wird diejenige der beiden Möglichkeiten mit den minimalen Kosten ausgewählt, um
j Bonuspunkte mit den ersten i + 1 Produkten zu erzielen.
j > 0:
def.
i+1
i+1
i+1
i+1
def.
i+1
i+1
Wir haben gezeigt, dass die Behauptung für alle i ∈ N und alle j ∈ Z gilt.
0
5