Negende college algoritmiek. 6/7 april Dynamisch Programmeren

Vergelijkbare documenten
Negende college algoritmiek. 15 april Dynamisch Programmeren

Tiende college algoritmiek. 14 april Dynamisch Programmeren, Gretige Algoritmen, Kortste Pad met BFS

Achtste college algoritmiek. 8 april Dynamisch Programmeren

Tiende college algoritmiek. 3 mei Dynamisch programmeren Gretige Algoritmen Algoritme van Dijkstra

Tiende college algoritmiek. 13/21 april Gretige Algoritmen Algoritme van Dijkstra

Tiende college algoritmiek. 14 april Gretige algoritmen

Tiende college algoritmiek. 4 mei Gretige Algoritmen Algoritme van Dijkstra

Tiende college algoritmiek. 26 april Gretige algoritmen

Elfde college algoritmiek. 18 mei Algoritme van Dijkstra, Heap, Heapify & Heapsort

Achtste college algoritmiek. 12 april Verdeel en Heers. Dynamisch Programmeren

Vijfde college algoritmiek. 2/3 maart Exhaustive search

Tiende college algoritmiek. 2 mei Gretige algoritmen, Dijkstra

Vijfde college algoritmiek. 9 maart Brute Force. Exhaustive search

Twaalfde college algoritmiek. 23 mei Branch & Bound, Heapsort

Zevende college Algoritmiek. 6 april Verdeel en Heers

Elfde college algoritmiek. 16 mei Dijkstra, Gretige algoritmen en Branch & Bound

Zevende college algoritmiek. 24 maart Verdeel en Heers

Zevende college algoritmiek. 23/24 maart Verdeel en Heers

Twaalfde college algoritmiek. 13 mei Branch & Bound Heap, Heapsort & Heapify

Vierde college algoritmiek. 23/24 februari Complexiteit en Brute Force

ALGORITMIEK: antwoorden werkcollege 5

Elfde college algoritmiek. 21 april Dijkstra en Branch & Bound

Vierde college algoritmiek. 2 maart Toestand-actie-ruimte Exhaustive Search

Elfde college algoritmiek. 10 mei Algoritme van Dijkstra, Gretige Algoritmen

Zesde college algoritmiek. 22 maart Backtracking

Vierde college algoritmiek. 1 maart Toestand-actie-ruimte Brute Force

Vijfde college algoritmiek. 17 maart Exhaustive search Graafwandelingen Backtracking

Derde college algoritmiek. 23 februari Complexiteit Toestand-actie-ruimte

Elfde college algoritmiek. 29 april Algoritme van Dijkstra, Branch & Bound

Derde college algoritmiek. 22 februari Complexiteit Toestand-actie-ruimte

Derde college complexiteit. 7 februari Zoeken

Zevende college complexiteit. 7 maart Mergesort, Ondergrens sorteren (Quicksort)

ALGORITMIEK: antwoorden werkcollege 5

ALGORITMIEK: antwoorden werkcollege 5

Tweede college algoritmiek. 12 februari Grafen en bomen

Algoritmiek 2015 / Algoritmiek 1

Zesde college algoritmiek. 23 maart Backtracking. Verdeel en Heers

Uitwerking tentamen Analyse van Algoritmen, 29 januari

Programmeermethoden. Recursie. week 11: november kosterswa/pm/

Twaalfde college algoritmiek. 12 mei Branch & Bound

Zevende college complexiteit. 17 maart Ondergrens sorteren, Quicksort

Dynamisch Programmeren III. Algoritmiek

Uitgebreide uitwerking tentamen Algoritmiek Dinsdag 3 juni 2008, uur

Uitgebreide uitwerking Tentamen Complexiteit, mei 2007

Zesde college algoritmiek. 9/10 maart Backtracking. Verdeel en Heers

Algoritmiek 2016 / Algoritmiek 1

Vierde college complexiteit. 14 februari Beslissingsbomen

Uitwerking tentamen Algoritmiek 10 juni :00 13:00

Algoritmiek. 15 februari Grafen en bomen

Vierde college complexiteit. 16 februari Beslissingsbomen en selectie

Uitgebreide uitwerking Tentamen Complexiteit, juni 2017

Zesde college complexiteit. 19 maart Mergesort, Ondergrens sorteren Quicksort, Shellsort

Algoritmiek. 2 februari Introductie

Twaalfde college algoritmiek. 11/12 mei Branch & Bound

Zesde college algoritmiek. 18 maart Backtracking. Verdeel en Heers

Programmeermethoden. Recursie. Walter Kosters. week 11: november kosterswa/pm/

Twaalfde college algoritmiek. 17 mei Branch & Bound

Vijfde college complexiteit. 21 februari Selectie Toernooimethode Adversary argument

Eerste college algoritmiek. 5 februari Introductie

Twaalfde college complexiteit. 11 mei Overzicht, MST

Uitgebreide uitwerking tentamen Algoritmiek Dinsdag 2 juni 2009, uur

Kortste Paden. Algoritmiek

Recursion. Introductie 37. Leerkern 37. Terugkoppeling 40. Uitwerking van de opgaven 40

Derde college algoritmiek. 16/17 februari Toestand-actie-ruimte

Recursie: definitie. De som van de kwadraten van de getallen tussen m en n kan als volgt gedefinieerd worden:

Heuristieken en benaderingsalgoritmen. Algoritmiek

Uitgebreide uitwerking Tentamen Complexiteit, juni 2018

Vierde college complexiteit. 26 februari Beslissingsbomen en selectie Toernooimethode Adversary argument

7 Omzetten van Recursieve naar Iteratieve Algoritmen

Derde college algoritmiek. 18 februari Toestand-actie-ruimte

Uitgebreide uitwerking tentamen Algoritmiek Dinsdag 5 juni 2007, uur

Algoritmen, Datastructuren en Complexiteit ( en ) Uitwerkingen

Programmeermethoden. Arrays (vervolg 2) Walter Kosters. week 9: 5 9 november kosterswa/pm/

Discrete Wiskunde, College 12. Han Hoogeveen, Utrecht University

Achtste college complexiteit. 2 april Polynoomevaluatie Matrixvermenigvuldiging Euler- en Hamiltonkringen

10 Meer over functies

Programmeermethoden NA. Week 5: Functies (vervolg)

Divide & Conquer: Verdeel en Heers. Algoritmiek

Tentamen Programmeren in C (EE1400)

Programmeren A. Genetisch Programma voor het Partitie Probleem. begeleiding:

Examen Datastructuren en Algoritmen II

Programmeermethoden. Arrays (vervolg 2) Walter Kosters. week 9: 6 10 november kosterswa/pm/

Divide & Conquer: Verdeel en Heers. Algoritmiek

HOOFDSTUK 3. Imperatief programmeren. 3.1 Stapsgewijs programmeren. 3.2 If Then Else. Module 4 Programmeren

Derde college algoritmiek. 23 februari Toestand-actie-ruimte

Uitwerking vierde serie inleveropgaven

ALGORITMIEK: answers exercise class 7

Uitwerking puzzel 91-7: Je kunt het schudden

Oefeningen voor de oefeningenles. Oefening 1

Algoritmiek 2017 / Algoritmiek 1

Als een PSD selecties bevat, deelt de lijn van het programma zich op met de verschillende antwoorden op het vraagstuk.

Onafhankelijke verzamelingen en Gewogen Oplossingen, door Donald E. Knuth, The Art of Computer Programming, Volume 4, Combinatorial Algorithms

Examen Datastructuren en Algoritmen II

Divide & Conquer: Verdeel en Heers vervolg. Algoritmiek

Greedy algoritmes. Algoritmiek

Uitwerking tentamen Algoritmiek 9 juni :00 17:00

recursie Hoofdstuk 5 Studeeraanwijzingen De studielast van deze leereenheid bedraagt circa 6 uur. Terminologie

Netwerkstroming. Algoritmiek

Datastructuren college 10

Transcriptie:

Negende college algoritmiek 6/7 april 2017 Dynamisch Programmeren 1

algemeen Uit college 8: DP: - nuttig bij problemen met overlappende deelproblemen - druk een oplossing van het probleem uit in oplossingen van deelproblemen (recursieve formulering) - deeloplossingen worden opgeslagen in een tabel zodra ze berekend zijn, waardoor elk deelprobleem maar één keer hoeft te worden opgelost - na afloop bevat (of is) de tabel de oplossing van het oorspronkelijke probleem - DP is van oorsprong een bottom up methode: start met de kleine gevallen en combineer hun oplossingen tot oplossingen van steeds grotere gevallen - er is ook een top down variant (memory function) 2

bottom up top down Uit college 8: DP: - de bottom up methode is iteratief, de top down variant is recursief - bottom up lost alle deelproblemen op, top down alleen degene die echt nodig zijn voor het oplossen van het oorspronkelijke probleem - bij beide varianten wordt eenzelfde soort tabel gebruikt - bij bottom up wordt de tabel in een bepaalde volgorde gevuld, bij top down gebeurt dat meer willekeurig - bij de bottom up manier is vaak een qua geheugengebruik efficiënter algoritme af te leiden 3

Getallen rapen Tentamen, juni 2013 Gegeven een driehoek bestaande uit n rijen met positieve getallen, waarbij de bovenste rij 1 getal bevat, de rij daaronder 2 getallen, tot en met n getallen op de onderste rij, als in het plaatje hieronder, met n = 4: 2 5 4 3 4 7 1 6 9 6 Wat is de grootste som die je kunt krijgen door vanuit de top naar beneden te lopen, waarbij je vanaf een positie in de driehoek alleen naar de twee posities er schuin onder kunt stappen? 4

Getallen rapen De driehoek kan worden gerepresenteerd als een n n array D[1...n][1...n], waarvan alleen de linkeronderdriehoek gevuld is, als in het plaatje hieronder. 2 5 4 3 4 7 1 6 9 6 Vanuit D[i][j] kun je in één stap D[i+1][j] en D[i+1][j +1] bereiken. Brute force / Exhaustive search... Complexiteit... 5

Getallen rapen 2 5 4 3 4 7 1 6 9 6 Recursieve formulering met S(i, j). Twee mogelijkheden: S(i,j) is maximale som die je kunt bereiken door vanuit positie (i,j) naar beneden te lopen S(i,j) is maximale som die je kunt bereiken door vanuit positie (1,1) naar positie (i,j) te lopen Voorkeur... 6

Getallen rapen 2 5 4 3 4 7 1 6 9 6 S(i,j) is maximale som die je kunt bereiken door vanuit positie (i,j) naar beneden te lopen S(i,j) =... 7

Getallen rapen 2 5 4 3 4 7 1 6 9 6 S(i,j) is maximale som die je kunt bereiken door vanuit positie (i,j) naar beneden te lopen S(i,j) = { D[i][j] als i = n en 1 j i D[i][j]+max{S(i+1,j),S(i+1,j +1)} als i < n en 1 j i Gevraagd: S(1, 1) 8

Getallen rapen Recursief: int S (int n, int i, int j) { if (i==n) return D[i][j]; else return D[i][j] + max (S(n,i+1,j), S(n,i+1,j+1)); } Complexiteit... 9

Getallen rapen Bottom up DP: for (j=1;j<=n;j++) S[n][j] = D[n][j]; for (i=n-1;i>=1;i--) for (j=1;j<=i;j++) S[i][j] = D[i][j] + max (S[i+1][j], S[i+1][j+1]); return S[1][1]; Ons voorbeeld... 2 5 4 3 4 7 1 6 9 6 10

Getallen rapen Bottom up DP: for (j=1;j<=n;j++) S[n][j] = D[n][j]; for (i=n-1;i>=1;i--) for (j=1;j<=i;j++) S[i][j] = D[i][j] + max (S[i+1][j], S[i+1][j+1]); return S[1][1]; Ons voorbeeld 2 5 4 3 4 7 1 6 9 6 22 18 20 9 13 16 1 6 9 6 Pad terugvinden... 11

Getallen rapen Bottom up DP: for (j=1;j<=n;j++) S[n][j] = D[n][j]; for (i=n-1;i>=1;i--) for (j=1;j<=i;j++) S[i][j] = D[i][j] + max (S[i+1][j], S[i+1][j+1]); return S[1][1]; Tijdcomplexiteit... Ruimtecomplexiteit... 12

Getallen rapen Ten slotte: Negatieve getallen Minimale som i.p.v. maximale som Geen probleem 13

Binomiaalcoëfficiënten Gegeven een pot met n verschillende objecten. Doe in één keer een greep van k objecten uit de pot. Hoeveel mogelijkheden? 14

Binomiaalcoëfficiënten Driehoek van Pascal C(n,k) = ( n) =... k 15

Binomiaalcoëfficiënten Driehoek van Pascal C(n,k) = ( n k) = ( ) ( n 1 k 1 + n 1 k ) 0 < k < n 1 k = 0,n 16

Recursief Een recursief algoritme ligt voor de hand: int bin1(int n,int k) { if ( ( k == 0 ) ( k == n ) ) return 1; else return ( bin1(n-1,k-1) + bin1(n-1,k) ); } Veel van de bin1(i,j) s worden echter herhaald berekend. Aanroep: bin1(n,k). Complexiteit: O( ( n k ) ) 17

Recursief met array Recursief algoritme met een array C voor het opslaan van tussenresultaten (dus C[i][j] = ( ) i j ): int bin2(int n,int k) { // C is globaal (foei) en op nul geinitialiseerd if ( C[n][k]!= 0 ) // reeds eerder berekend return C[n][k]; else { if ( ( k == 0 ) ( k == n ) ) { C[n][k] = 1; else C[n][k] = bin2(n-1,k-1) + bin2(n-1,k); return C[n][k]; } } Complexiteit: O(n k); extra geheugen: Θ(n k) 18

Binomiaalcoëfficiënten Driehoek van Pascal C(n,k) = ( n k) = ( ) ( n 1 k 1 + n 1 k ) 0 < k < n 1 k = 0,n 19

DP: tabel We gebruiken een globaal (op nul geïnitialiseerd) array C voor het opslaan van tussenresultaten, dus C[i][j] = ( ) i j. Bottom up: Het array wordt rij voor rij gevuld, te beginnen bij rij 0, en per rij van links naar rechts, gebruikmakend van de recurrente betrekking (recursieve formulering). 20

DP: algoritme int bin3(int n,int k) { for ( i = 0; i <= n; i++ ) for ( j = 0; j <= min(i,k); j++ ) if ( ( j == 0 ) ( j == i ) ) C[i][j] = 1; else C[i][j] = C[i-1][j-1] + C[i-1][j]; return C[n][k]; } Aanroep: bin3(n,k). Complexiteit: Θ(n k); extra geheugen: Θ(n k). We kunnen hier echter volstaan met een een-dimensionaal array ter lengte k. Er is dus maar O(k) extra geheugen nodig. (Zie ook exercise 8.1.9) 21

Knapzakprobleem Knapzakprobleem Gegeven n objecten, met gewicht w 1,...,w n en waarde v 1,...,v n, en een knapzak met capaciteit W. Gevraagd: de meest waardevolle deelverzameling der objecten die in de knapzak past (dus met totaalgewicht W). Aanname: gewichten zijn integers > 0. Voorbeeld: object gewicht waarde 1 8 42 2 3 14 3 4 40 4 5 27 knapzakcapaciteit 12 22

KZP met DP Laat F[i][j] de waarde zijn van de meest waardevolle deelverzameling van de eerste i (1 i n) objecten, die in een knapzak met capaciteit j (1 j W) past. We zoeken dus F[n][W]. We nemen hier impliciet aan dat W een positief geheel getal is. F[i][j] =... 23

KZP met DP Laat F[i][j] de waarde zijn van de meest waardevolle deelverzameling van de eerste i (1 i n) objecten, die in een knapzak met capaciteit j (1 j W) past. We zoeken dus F[n][W]. We nemen hier impliciet aan dat W een positief geheel getal is. Dan geldt (want object i zit er wel of niet in): F[i][j] = En we definiëren: max{f[i 1][j],v i +F[i 1][j w i ]} als j w i F[i 1][j] F[0][j] = 0 voor j 0 en F[i][0] = 0 voor i 0 als j < w i 24

KZP met DP vervolg We kunnen het array bijvoorbeeld rij voor rij (en per rij v.l.n.r.) vullen. for i := 0 to n do for j := 0 to W do if i = 0 or j = 0 then else F[i][j] := 0; if j < w i then else fi fi od od F[i][j] := F[i 1][j]; F[i][j] := max (F[i 1][j],v i +F[i 1][j w i ]); 0 j w i j W 0 0 0 0 0 i 1 0 F[i 1][j w i ] F[i 1][j] w i,v i i 0 F[i][j] Complexiteit: Θ(n W); extra geheugen: Θ(n W) n 0 goal 25

KZP met DP tabel vullen Voor het voorbeeld wordt de tabel als volgt gevuld: j 0 1 2 3 4 5 6 7 8 9 10 11 12 i 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 42 42 42 42 42 2 0 0 0 14 14 14 14 14 42 42 42 56 56 3 0 0 0 14 40 40 40 54 54 54 54? 4 Ter herinnering: i w i v i 1 8 42 2 3 14 3 4 40 4 5 27 26

KZP met DP tabel vullen Voor het voorbeeld wordt de tabel als volgt gevuld: j 0 1 2 3 4 5 6 7 8 9 10 11 12 i 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 42 42 42 42 42 2 0 0 0 14 14 14 14 14 42 42 42 56 56 3 0 0 0 14 40 40 40 54 54 54 54? 4 j 0 1 2 3 4 5 6 7 8 9 10 11 12 i 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 42 42 42 42 42 2 0 0 0 14 14 14 14 14 42 42 42 56 56 3 0 0 0 14 40 40 40 54 54 54 54 56 82 4 0 0 0 14 40 40 40 54 54? Ter herinnering: i w i v i 1 8 42 2 3 14 3 4 40 4 5 27 27

KZP met DP tabel gevuld j 0 1 2 3 4 5 6 7 8 9 10 11 12 i 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 42 42 42 42 42 2 0 0 0 14 14 14 14 14 42 42 42 56 56 3 0 0 0 14 40 40 40 54 54 54 54 56 82 4 0 0 0 14 40 40 40 54 54 67 67 67 82 Dus de gevraagde optimale waarde is 82. Opmerkingen: 1. Je kunt volstaan met een eendimensionaal hulparray; deze moet dan wel v.r.n.l. worden gevuld. 2. Uit de tweedimensionale tabel kun je de/een optimale deelverzameling zelf ook terugvinden. 28

deelverzameling Optimale De (maar in het algemeen: een) meest waardevolle deelverzameling vinden we terug door te beginnen bij F[n][W] en van daaruit terug te redeneren. j 0 1 2 3 4 5 6 7 8 9 10 11 12 i 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 42 42 42 42 42 2 0 0 0 14 14 14 14 14 42 42 42 56 56 3 0 0 0 14 40 40 40 54 54 54 54 56 82 4 0 0 0 14 40 40 40 54 54 67 67 67 82 4 niet, 3 wel, 2 niet, 1 wel, dus {1,3} is de optimale deelverzameling. Ter herinnering: object gewicht waarde 1 8 42 2 3 14 3 4 40 4 5 27 29

Top down met array RecKnapzak(i, j) :: // F[i][j] == -1: nog niet berekend if ( F[i][j] >= 0 ) then return F[i][j]; else if ( i = 0 or j = 0 ) then F[i][j] := 0; else if ( j < w_i ) then F[i][j] := RecKnapzak(i-1, j); else F[i][j] := max { RecKnapzak(i-1, j), v_i + RecKnapzak(i-1, j-w_i) }; fi fi return F[i][j]; fi Vraag: welke van de twee methodes verdient de voorkeur? 30

Nodig voor top down j 0 1 2 3 4 5 6 7 8 9 10 11 12 i 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 42 42 42 42 42 2 0 0 0 14 14 14 14 14 42 42 42 56 56 3 0 0 0 14 40 40 40 54 54 54 54 56 82 4 0 0 0 14 40 40 40 54 54 67 67 67 82 Ter herinnering: object gewicht waarde 1 8 42 2 3 14 3 4 40 4 5 27 31

opmerkingen Werkwijze en 1. Druk de (waarde van de) oplossing van het probleem uit in (de waarde van) oplossingen van deelproblemen 2. Stel een recurrente betrekking op (recursieve formulering) 3. Gebruik alleen dynamisch programmeren bij overlappende deelproblemen 4. Definieer een geschikte tabel en ga na wat de berekeningsvolgorde moet zijn 5. Vul aldus bottom up de tabel in (algoritme) 6. Let op geheugenbesparing 7. Pas je algoritme zo aan dat je uit de tabel niet alleen een waarde maar ook de (optimale) oplossing zelf kunt halen 8. Dynamisch programmeren wordt vaak gebruikt voor optimalisatieproblemen 32

Muntenprobleem Gegeven onbeperkt veel munten van d 1,d 2,...d m eurocent, en een te betalen bedrag van n (n 0) eurocent. Alle d i zijn > 0 en verschillend. Gevraagd: het minimale aantal munten dat nodig is om het bedrag van n eurocent te betalen. Voorbeeld: type munt waarde 1 1 2 4 3 6 te betalen bedrag: 8 Vier manieren om te betalen: 6 + 1 + 1; 4 + 4; 4 + 1 + 1 + 1 + 1; 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1. Dus het gevraagde minimale aantal is: 2 (twee munten van 4 cent). 33

KZP vs. MP KZP MP n objecten m munten gewicht w i waarde d i totaal gewicht capaciteit W totale waarde = bedrag n waarde v i kosten 1 max. totale waarde min. totale kosten elk object 1 keer munt mag meer keer 34

MP met 2-d DP Laat munt[i][j] het minimale aantal munten zijn dat nodig is om een bedrag van j eurocent te betalen, wanneer alleen munten van d 1,d 2,...,d i (i 1) worden gebruikt. We zoeken dus munt[m][n]. Dan geldt (want d i wordt wel of niet gebruikt):... als i > 1,j d i munt[i][j] =... als i > 1,0 < j < d i... als i = 1,0 < j < d 1... als i = 1,j d 1... als i 1,j = 0 35

MP met 2-d DP Laat munt[i][j] het minimale aantal munten zijn dat nodig is om een bedrag van j eurocent te betalen, wanneer alleen munten van d 1,d 2,...,d i (i 1) worden gebruikt. We zoeken dus munt[m][n]. Dan geldt (want d i wordt wel of niet gebruikt): min {munt[i 1][j],1+munt[i][j d i ]} als i > 1,j d i munt[i][j] = munt[i 1][j] als i > 1,0 < j < d i als i = 1,0 < j < d 1 1+munt[1][j d 1 ] als i = 1,j d 1 0 als i 1,j = 0 36

KZP vs. MP Iets andere formulering recurrente betrekkingen: max{f[i 1][j],v i +F[i 1][j w i ]} als i 1,j w i F[i][j] = F[i 1][j] als i 1,0 < j < w i 0 als i = 0,j > 0 0 als i 0,j = 0 min {munt[i 1][j],1+munt[i][j d i ]} als i 1,j d i munt[i][j] = munt[i 1][j] als i 1,0 < j < d i als i = 0,j > 0 0 als i 0,j = 0 Complexiteit MP met 2-d DP (vgl. KZP): tijd Θ(m n); extra geheugen: Θ(m n) Of met eendimensionaal hulparray (v.l.n.r. vullen): Θ(n) 37

MP met 1-d DP Het kan eenvoudiger, want KZP MP n objecten m munten gewicht w i waarde d i totaal gewicht capaciteit W totale waarde = bedrag n waarde v i kosten 1 max. totale waarde min. totale kosten elk object 1 keer munt mag meer keer Bij muntenprobleem dus geen noodzaak om bij te houden welke munten we al gebruikt hebben. 38

MP met 1-d DP Laat munt[j] het minimale aantal munten zijn dat nodig is om een bedrag van j eurocent te betalen. We zoeken dus munt[n]. Neem voor het gemak even aan dat de muntsoorten oplopend zijn gesorteerd (d 1 < d 2 <... < d m ). Dan geldt: munt[j] = min di j {1+munt[j d i ]} als j d 1 als 0 < j < d 1 0 als j = 0 39

MP met 1-d DP Vul array munt van links naar rechts. munt[0] = 0; for j := 1 to n do od tmp := ; i := 1; while i m and d i j do od if 1+munt[j d i ] < tmp then fi tmp := 1+munt[j d i ]; munt[j] := tmp; Complexiteit MP met 1-d DP: tijd Θ(m n); extra geheugen: Θ(n) Net als MP met 2-d DP (met eendimensionaal array) 40

MP met 1-d DP Voorbeeld: type munt waarde 1 1 2 4 3 6 te betalen bedrag: 8 j 0 1 2 3 4 5 6 7 8 munt[j] 0 1 2 3 1 2 1 2? 41

MP met 1-d DP Voorbeeld: type munt waarde 1 1 2 4 3 6 te betalen bedrag: 8 j 0 1 2 3 4 5 6 7 8 munt[j] 0 1 2 3 1 2 1 2? j 0 1 2 3 4 5 6 7 8 munt[j] 0 1 2 3 1 2 1 2 2 Vind benodigde munten terug in tabel: j 0 1 2 3 4 5 6 7 8 munt[j] 0 1 2 3 1 2 1 2 2 42

Afsluiting MP 1. Een (eenvoudige) variatie is: gegeven een bedrag van n euro, is dat te betalen met muntsoorten d 1,...d m? Dit kan geheel analoog aan het optimalisatieprobleem worden opgelost met DP. Gebruik een array munt, waarbij munt[j] = True als het bedrag j gemaakt kan worden, en anders False. 43

MP met 1-d DP Vul array munt van links naar rechts. munt[0] = 0; for j := 1 to n do od tmp := ; i := 1; while i m and d i j do od if 1+munt[j d i ] < tmp then fi tmp := 1+munt[j d i ]; munt[j] := tmp; Complexiteit MP met 1-d DP: tijd Θ(m n); extra geheugen: Θ(n) Net als MP met 2-d DP (met eendimensionaal array) 44

Variatie MP met 1-d DP Vul array munt van links naar rechts. munt[0] = 0; for j := 1 to n do od tmp := false; i := 1; while i m and d i j and not tmp do od if munt[j d i ] then fi tmp := true; munt[j] := tmp; Complexiteit MP met 1-d DP: tijd Θ(m n); extra geheugen: Θ(n) Net als MP met 2-d DP (met eendimensionaal array) 45

Afsluiting MP 1. Een (eenvoudige) variatie is: gegeven een bedrag van n euro, is dat te betalen met muntsoorten d 1,...d m? Dit kan geheel analoog aan het optimalisatieprobleem worden opgelost met DP. Gebruik een array munt, waarbij munt[j] = True als het bedrag j gemaakt kan worden, en anders False. 2. Een ander algoritme voor het muntenprobleem: betaal n met d 1,...d m :: geef de grootste munt d i n; betaal n d i met d 1,...d i Dit is een zogenaamd gretig algoritme. Bovenstaand algoritme is erg snel, maar het levert niet altijd een optimale oplossing (soms ook geen oplossing, terwijl er wel een oplossing is). 46

Houtzaagmolen Een houtzaagmolen rekent voor het in twee stukken zagen van een stam van lengte l precies l euro, ongeacht de plek waar dit moet gebeuren. Na bestudering van de knoesten op een boomstam van lengte l wordt besloten dat deze in achtereenvolgens (v.l.n.r. gezien) stukken van lengtes l 1,l 2,...,l n gezaagd moet worden. (De hele boomstam heeft dus lengte ni=1 l i.) De plekken waar gezaagd gaat worden zijn dus van tevoren bekend. Er zijn hier n 1 zaagplekken. 1 2 3 n 1 l 1 l 2 l 3... l n... Merk op dat de volgorde van zagen van invloed is op de prijs. 47

Zaagvolgorde Voorbeeld Laat n = 4 en l 1 = 6,l 2 = 8,l 3 = 7,l 4 = 2. De boomstam heeft dus lengte 23. - Stel we zagen achtereenvolgens op plek 1, dan plek 2 en dan plek 3. De kosten zijn dan 23+17+9 = 49 euro. - Stel we zagen achtereenvolgens op plek 3, dan plek 2 en dan plek 1. De kosten zijn dan 23+21+14 = 58 euro. Probleem Bepaal de minimale kosten om de gegeven boomstam in stukken met de opgegeven lengtes l i te zagen (zaagplekken dus bekend). 48

Deelproblemen Deelproblemen Het probleem brengen we terug tot het bepalen van de minimale kosten Z[i][j] die moeten worden gemaakt om de (deel)stam (van zaagplek i 1 tot zaagplek j) ter lengte L(i,j) = l i + l i+1 + + l j te verzagen tot achtereenvolgens stukken van lengte l i,l i+1,...,l j. Alle l i, en dus ook alle L(i, j) en alle zaagplekken, zijn gegeven. Het oorspronkelijke probleem is dan het bepalen van Z[1][n]. Merk op dat altijd 1 i j n. Recurrente betrekking Z[i][j] =... 49

Deelproblemen Deelproblemen Het probleem brengen we terug tot het bepalen van de minimale kosten Z[i][j] die moeten worden gemaakt om de (deel)stam (van zaagplek i 1 tot zaagplek j) ter lengte L(i,j) = l i + l i+1 + + l j te verzagen tot achtereenvolgens stukken van lengte l i,l i+1,...,l j. Alle l i, en dus ook alle L(i, j) en alle zaagplekken, zijn gegeven. Het oorspronkelijke probleem is dan het bepalen van Z[1][n]. Merk op dat altijd 1 i j n. Recurrente betrekking Z[i][j] = L(i,j)+min i k j 1 {Z[i][k]+Z[k +1][j]} als i < j Z[i][i] = 0 50

Tabel vullen De Z[i][j] op plek # wordt berekend uit Z-waarden op de plekken met een *; dus uit dezelfde rij en dezelfde kolom. j i 0........... 0.......... * * * * * * * #.. 0..... *.. 0.... *.. 0... *.. 0.. *.. Invulvolgorde... 51

Tabel vullen De Z[i][j] op plek # wordt berekend uit Z-waarden op de plekken met een *; dus uit dezelfde rij en dezelfde kolom. j i 0........... 0.......... * * * * * * * #.. 0..... *.. 0.... *.. 0... *.. 0.. *.. Invulvolgorde De tabel kan bottom up gevuld worden door alle diagonalen j = i+d af te lopen en per diagonaal bijvoorbeeld van linksboven tot rechtsonder te gaan. Een andere mogelijkheid is de tabel rij voor rij te vullen (van onder naar boven) en per rij (verplicht) van links naar rechts. 52

Zagen met DP void vulkosten ( int n ) { // L en Z globaal int i, j; for (i = 1; i <= n; i++) Z[i][i] = 0; for (i = n-1; i > 0; i--) { for (j = i+1; j <= n; j++ ) { min = Z[i][i] + Z[i+1][j]; for (k=i+1; k<j; k++) { if ( Z[i][k] + Z[k+1][j] < min ) min = Z[i][k] + Z[k+1][j]; } // min bevat nu het minimum Z[i][j] = L[i][j] + min; } // for j } for i } // vulkosten 53

Handen schudden The Bavarian Beer Party (BAPC 2006) We hebben een kring van n studenten (n even), waarvan de studierichting bekend is. Iedereen moet precies één andere student de hand schudden. Dit handen schudden moet zodanig gebeuren dat geen enkel tweetal armen elkaar kruist. Voorbeeld met acht personen: Geen kruisende armen: toegestaan Kruisende armen: niet toegestaan De bedoeling is om het aantal paren studenten met dezelfde studierichting dat elkaar een hand geeft te maximaliseren. 54

Handen schudden Oplossing: vouw de tafel open op een willekeurige plaats, zodat je een rij van n studenten krijgt, en nummer die 1,2,...,n. Een toegestane koppeling van studenten die elkaar de hand schudden komt nu overeen met een rijtje van n corresponderende haakjes: n 2 openingshaakjes en n 2 sluithaakjes. Student 1 moet de hand schudden met student 2, student 4, student 6,..., of student n. Of in termen van haakjes: op positie 1 staat een openingshaakje; het corresponderende sluithaakje staat op positie 2, positie 4, positie 6,..., of positie n. 55

Handen schudden Laat Z[i][j] = 1 als studenten i en j de Zelfde studierichting volgen, en Z[i][j] = 0 anders. Laat M[i][j] het Maximale aantal koppels studenten zijn dat elkaar de hand schudt, én dezelfde studierichting volgt, als we studenten i,...,j op een toegestane manier aan elkaar koppelen. We zoeken dus M[1][n]. Dan geldt: M[i][j] =... 56

Handen schudden Laat Z[i][j] = 1 als studenten i en j de Zelfde studierichting volgen, en Z[i][j] = 0 anders. Laat M[i][j] het Maximale aantal koppels studenten zijn dat elkaar de hand schudt, én dezelfde studierichting volgt, als we studenten i,...,j op een toegestane manier aan elkaar koppelen. We zoeken dus M[1][n]. Dan geldt: M[i][j] = max k=i+1,i+3,...,j {Z[i][k]+M[i+1][k 1]+M[k +1][j]} als i j en j i is oneven (i schudt hand met k) 0 als i j en j i is even 0 als i > j Vraag: waarom proberen we in de bovenste regel alleen k = i+1,i+3,i+5,...,j? 57

schudden Zagen vs. handen Iets andere formulering recurrente betrekking zagen: Z[i][j] = min i k j 1 {L(i,j)+Z[i][k]+Z[k +1][j]} als i < j Z[i][i] = 0 Handen schudden: M[i][j] = max k=i+1,i+3,...,j {Z[i][k]+M[i+1][k 1]+M[k +1][j]} als i j en j i is oneven (i schudt hand met k) 0 als i j en j i is even 0 als i > j 58

(Werk)college Lezen/leren bij dit college: slides; paragraaf 8.2; voorbeeld 2 in paragraaf 8.1 Werkcollege: vanmiddag, 13:45 15:30, in deze zaal daarna: assistentie opdracht 2, in computerzaal Opgaven: zie http://www.liacs.leidenuniv.nl/~vlietrvan1/algoritmiek/ Volgend college: 13/21 april 2017 59