Longest increasing. subsequence Betingelser. Longest. common subsequence. Knapsack Grådig vs. DP Moro: 2D-Nim Spørsmål. Forside. Repetisjon.

Like dokumenter
Longest. increasing. subsequence. Betingelser. Matrise- common. Grådig vs. DP. Forside. Intro. Fibonacci-tall. Memoisering DP

Algdat - øvingsforelesning

INF Algoritmer og datastrukturer

Dynamisk programmering Undervises av Stein Krogdahl

Alle mot alle. Åttende forelesning. (eller eller Bellman-Ford, eller BFS, alt ettersom) fra alle noder.

Dagens stoff er hentet fra kapittel 9 i læreboka, samt kapittel 20.5 (som vi «hoppet over» sist)

Dynamisk programmering

Choices, choices. Tiende forelesning. Dynamisk programmering: En serie med valg der valgmulighetene er avhengige av hva vi har valgt før.

ALGORITMER OG DATASTRUKTURER

Dijkstras algoritme. Her finnes det også (minst) en riktig rekkefølge for Relax, men den må vi oppdage litt etter hvert.

Live life and be merry

ALGORITMER OG DATASTRUKTURER

Dynamisk programmering

Rekursiv programmering

Dagens plan. INF Algoritmer og datastrukturer. Koding av tegn. Huffman-koding

INF Algoritmer og datastrukturer

Grådige algoritmer. Lars Vidar Magnusson Kapittel 16. Aktivitetvelgingsproblemet Huffmankoder

Choices, choices. Tiende forelesning. Dynamisk programmering: En serie med valg der valgmulighetene er avhengige av hva vi har valgt før.

Algdat Eksamensforelesning. Nils Barlaug

Live life and be merry

Rekursiv programmering

ALGORITMER OG DATASTRUKTURER

IN Algoritmer og datastrukturer

ALGORITMER OG DATASTRUKTURER

Dijkstras algoritme. Her finnes det også (minst) en riktig rekkefølge for Relax, men den må vi oppdage litt etter hvert.

Eksamensoppgave i TDT4120 Algoritmer og datastrukturer

Løsnings forslag i java In115, Våren 1996

Live life and be merry

Norsk informatikkolympiade runde. Sponset av. Uke 46, 2017

LO118D Forelesning 2 (DM)

Norsk informatikkolympiade runde. Sponset av. Uke 46, 2016

Løsningsforslag for eksamen i fag SIF8010 Algoritmer og datastrukturer Lørdag 9. august 2003, kl

Norsk informatikkolympiade runde

Avsluttende eksamen i TDT4120 Algoritmer og datastrukturer

EKSAMEN. Dato: 18. mai 2017 Eksamenstid: 09:00 13:00

Eksamen i fag SIF8010 Algoritmer og datastrukturer Lørdag 9. august 2003, kl

Eksamensoppgave i TDT4120 Algoritmer og datastrukturer

Kjøretidsanalyse. Hogne Jørgensen

Kontinuasjonseksamen i fag SIF8010 Algoritmer og Datastrukturer Torsdag 9. August 2001, kl

Eksamensoppgave i TDT4120 Algoritmer og datastrukturer

Notater til INF2220 Eksamen

INF1020 Algoritmer og datastrukturer GRAFER

MAT1030 Forelesning 28

INF 4130 Oppgavesett 3, 20/ m/løsningsforslag

Et eksempel: Åtterspillet

Øvingsforelesning Korteste vei: Alle til alle

Norsk informatikkolympiade runde

Norsk informatikkolympiade runde

Algdat-ninja på 60 minutter: Et galskapsprosjekt. Magnus Lie Hetland

Forelesningsplan. Grådighet. LF Øving 9. Hva er grådighet? Aktivitetsvelger En grådig strategi Grådig eller dynamisk? Knapsack Huffmankoding

Norsk informatikkolympiade runde

Eksamensoppgave i TDT4120 Algoritmer og datastrukturer

Obligatorisk oppgave 2 i MAT1140, Høst Løsninger og kommentarer

Kapittel 12: Rekursjon

All good things. Fjortende forelesning

LO118D Forelesning 12 (DM)

4 Matriser TMA4110 høsten 2018

6. oktober Dagens program: Første time: Andre time, gjesteforelesning: Uavgjørbarhet. Stein Krogdahl. (Ikke pensum, egne foiler legges ut)

Algdat Oppsummering, eksamen-ting. Jim Frode Hoff

Norsk informatikkolympiade runde. Sponset av. Uke 46, 2015

MAT1030 Diskret Matematikk

INF oktober Stein Krogdahl. Kap 23.5: Trær og strategier for spill med to spillere

Grafalgoritmer: Korteste vei

KONTINUASJONSEKSAMEN I FAG ALGORITMER OG DATASTRUKTURER

Studentnummer: Side 1 av 1. Løsningsforslag, Eksamen i TDT4120 Algoritmer og datastrukturer August 2005

Forelesning 30. Kompleksitetsteori. Dag Normann mai Informasjon. Oppsummering

MAT1030 Diskret matematikk

Løsnings forslag i java In115, Våren 1998

INF2220: Time 4 - Heap, Huffmann

Grunnleggende Grafteori

Algoritmer og datastrukturer Kapittel 1 - Delkapittel 1.8

Vi skal se på grafalgoritmer for:

Pensum: fra boken (H-03)+ forelesninger

Først litt praktisk info. Sorteringsmetoder. Nordisk mesterskap i programmering (NCPC) Agenda

INF2220: Time 8 og 9 - Kompleksitet, beregnbarhet og kombinatorisk søk

Hvorfor sortering og søking? Søking og sortering. Binære søketrær. Ordnet innsetting forbereder for mer effektiv søking og sortering INF1010 INF1010

Pensum: fra boken (H-03)+ forelesninger

Definisjon. I et binært tre har hver node enten 0, 1 eller 2 barn

Algoritmer og datastrukturer Løsningsforslag

Pensum: 3. utg av Cormen et al. Øvingstime: I morgen, 14:15

Norsk informatikkolympiade runde

SIF8010 ALGORITMER OG DATASTRUKTURER

Et eksempel: Åtterspillet

Definisjon av binært søketre

TDT4105 Informasjonsteknologi, grunnkurs. Mer om funksjoner: - rekursive funksjoner

Norsk informatikkolympiade runde. Sponset av. Uke 46, 2014

INF2220: Forelesning 7. Kombinatorisk søking

Avsluttende eksamen i TDT4120 Algoritmer og datastrukturer

NIO Runde 2

Agenda. 1 Sortering, heap og select. 2 Binære trær. 3 Grafer, BFS og DFS. 4 Spenntrær og Korteste vei. 5 Maks flyt. 6 Dynamisk programmering

INF1010 notat: Binærsøking og quicksort

Teoriøving 7 + litt om Ford-Fulkerson. Magnus Lie Hetland

Oppgave 1. Sekvenser (20%)

Dijkstras algoritme Spørsmål

Eksamen i tdt4120 Algoritmer og datastrukturer

Alg. Dat. Øvingsforelesning 3. Grafer, BFS, DFS og hashing. Børge Rødsjø

Innhold. Innledning 1

MAT1030 Diskret Matematikk

Anbefalte forkunnskaper Studentene forutsettes å kunne programmere, for eksempel ved å ha tatt TDT4100 Objektorientert programmering.

Øvingsforelesning 2 - TDT4120. Grafer og hashing. Benjamin Bjørnseth

Transkript:

:: :: Dynamisk programmering Eksamenskurs Åsmund Eldhuset asmunde *at* stud.ntnu.no folk.ntnu.no/asmunde/algdat/dp.ppt Svært rask repetisjon Noen ganger (f.eks. ved utregning av Fibonaccitall) vil en rekursiv funksjon få eksponentiell kjøretid fordi den regner ut de samme delsvarene gang på gang Memoisering: få den rekursive funksjonen til å mellomlagre svarene i et dictionary eller et array (går ovenfra og ned) Dynamisk programmering: droppe rekursjonen og fylle ut tabellen direkte (går nedenfra og opp) :: Rekursjonstre Fibonacci-tall :: Rekursiv problemformulering f() f() f() f() f(2) f(1) f(1) f(0) f(2) f(1) f(0) f() f(2) f(1) f(1) f(0) f() f() f(2) f(1) f(1) f(0) Det gjelder å formulere løsningen av et problem som en kombinasjon av løsninger av mindre utgaver av samme problem Eksempel: Fibonacci-tall nummer n er summen av Fibonacci-tall nummer n -1og Fibonacci-tall nummer n -2 De mindre utgavene kalles delproblemer f(2) f(1) f(0) :: :: :: (LIS) :: :: :: LIS optimal substruktur Problem: Gitt en rekke med n reelle tall a 1, a 2, a,..., a n, finn den største delrekken slik at tallene står i stigende rekkefølge Eksempel: [1, 2, 9,, 8,, 7] Fungerer en grådig algoritme? Nei, fordi delproblemene ikke er uavhengige. Velger man å ta med et bestemt tall, har man lagt begrensninger på hvilke tall man kan få med seg senere Vi observerer at en LIS for en bestemt liste består av en LIS for en mindre del av listen Eksempel: [1, 2, 9,, 8,, 7] LIS'en er [1, 2,,, 7] [1, 2,, ] er en LIS for [1, 2, 9,, 8, ] [1, 2, ] er en LIS for [1, 2, 9, ] [1, 2] er en LIS for [1, 2] [1] er en LIS for [1] Konklusjon: en optimal løsning av problemet består av optimale løsninger av delproblemer 1

:: :: :: LIS rekursiv definisjon :: :: :: LIS rekursiv definisjon La oss se på problemet med å finne en LIS som slutter med tall nummer i, og la oss kalle lengden av dette for L(i) Da vil hovedproblemet vårt være å finne det beste av L(1), L(2), L(),..., L(n) Hvordan regner vi ut L(i)? Vi finner lengste delsekvensen som ikke inneholder tall større enn tall nummer i Altså: vi må finne den j som er slik at j < i, a j a i, og L(j) er størst mulig L(i) er da lik den største L(j) pluss 1 L(i) = max(l(j) : 0 j < i a j a i ) + 1 L(0) = 0 :: :: :: LIS tabellutfylling :: :: :: LIS sporing [1, 2, 9,, 8,, 7] [0, -, -, -, -, -, -, -] [0, 1, -, -, -, -, -, -] [0, 1, 2, -, -, -, -, -] [0, 1, 2,, -, -, -, -] [0, 1, 2,,, -, -, -] [0, 1, 2,,,, -, -] [0, 1, 2,,,,, -] [0, 1, 2,,,,, ] Nå har vi funnet lengden på LIS'en, men det hadde jo vært kjekt å finne selve LIS'en også... I et array P registrerer vi hvilket delproblem hvert delproblem benyttet a: [1, 2, 9,, 8,, 7] L: [0, 1, 2,,,,, ] P: [-, 0, 1, 2, 2,,, ] :: :: :: LIS implementasjon :: :: :: LIS implementasjon def LIS(a): n = len(a) L = [0] * (n + 1) P = [-1] * (n + 1) for i in range(1, n + 1): bestindex = 0 for j in range(1, i): if a[j - 1] <= a[i - 1] and \ L[j] > L[bestIndex]: bestindex = j L[i] = L[bestIndex] + 1 P[i] = bestindex return L[n], P def makelis(a, P, i): if i == 0: return [] b = makelis(a, P, P[i]) b.append(a[i - 1]) return b def makelis(a, P): i = len(a) b = [] while i!= 0: b.append(a[i - 1]) i = P[i] b.reverse() return b 2

Betingelse 1: Optimal substruktur Betingelse 1.: Uavhengige delproblemer :: :: Ofte har vi en situasjon hvor vi ønsker å finne den best mulige løsningen av et problem Skal vi kunne bruke DP, må det være slik at problemet har en optimal substruktur en optimal løsning av hele problemet består av optimale løsninger av delproblemer Når vi løser et delproblem, må vi som regel se gjennom alle de mindre delproblemene og velge det beste Løsningen av ett delproblem må ikke legge begrensninger på hvordan andre delproblemer kan løses Delproblemer må ikke ha felles ressurser som kan spises opp (Anti)eksempel: simple path En LSP fra a til b må bestå av en LSP fra a til x og fra x til b (vi har optimal substruktur) Men når vi finner en LSP fra a til x, risikerer vi å bruke opp noder som LSP fra x til b kunne ha brukt (vi har ikke uavhengige delproblemer) Betingelse 2: Overlappende delproblemer (Betingelse : Antall delproblemer) :: :: Det burde heller hete "gjentatte delproblemer" Løsningen av to forskjellige delproblemer kan involvere løsning av ett eller flere felles delproblemer Derfor blir rekursjon uten memoisering ekstremt ineffektivt fordi det samme arbeidet gjøres gang på gang Dersom delproblemene ikke overlapper, kan en splitt-og-hersk-algoritme brukes Det er bare vits i DP hvis antallet delproblemer er "lite" nok til at vi kan lagre alle svarene i minnet og får løst alle delproblemene raskt nok Ting å være oppmerksom på :: DP fungerer som regel bare på problemer der ting må komme i en bestemt rekkefølge, eller hvor du står fritt til å plukke en rekkefølge selv (slik som Floyd- Warshall gjør) Selv om DP tilsynelatende gir polynomisk kjøretid, kan det fremdeles være eksponentielt i inputstørrelsen! (f.eks. myntutdeling eller 0/1 knapsack) :: :: Eksempel: Regne ut A 1 A 2 A A A Dimensjonene må passe (a b, b c, c d, d e, e f) er ikke kommutativt (du kan ikke bytte om på rekkefølgen) Men det er assosiativt (du kan velge i hvilken rekkefølge du utfører multiplikasjonene) Vi kan kontrollere multiplikasjonsrekkefølgen ved å sette på parenteser: A 1 A 2 A A A = A 1 ((A 2 A )(A A )) = ((A 1 A 2 )A )( A A ) = A 1 (A 2 (A (A A ))) =...

:: :: Multiplikasjon av to matriser med dimensjoner a b og b c gir abc skalarmultiplikasjoner (multiplikasjoner av tall) Forskjellige parentessettinger fører som regel til forskjellig totalt antall skalarmultiplikasjoner Hvilken parentessetting er best? :: :: Fullt parentessatt uttrykk: enten en enkelt matrise eller et produkt av to utrykk som er fullt parentessatt Alle måter å multiplisere sammen matriser på kan skrives fullt parentessatt Den beste måten må derfor være et fullt parentessatt uttrykk altså et produkt av to andre FPU, som selv må være optimale (LCS) (LCS) Finne lengste tegnsekvens som er felles for to strenger Eksempel: A = "abqaeehgpcydkpklz" B = "rwazxbaertctdz" Vi definerer LCS(i, j) til å være LCS'en til A[0:i] og B[0:j] :: :: :: :: :: :: Dersom siste tegn i A[0:i] og B[0:j] er like, er disse en del av LCS(i, j); da trenger vi bare å finne LCS(i 1, j 1) og legge til 1 Hvis ikke, kan ikke begge de siste tegnene være med i LCS(i, j) Da er LCS(i, j) enten lik LCS(i 1, j) eller LCS(i, j 1) Vi får da en tabell over LCS(i, j) på m x n, hvor m er lengden til A og n er lengden til B Fractional knapsack Kan ikke løses med DP, siden antallet forskjellige delproblemer blir uendelig! DP krever som regel løsning av alle delproblemer for å kunne velge det best egnede, mens en grådig algoritme gjør et grådig valg og produserer ett delproblem :: :: Begge utnytter optimal substruktur Grådig Lokalt optimale valg er globalt optimale; optimal løsning avgjøres ut fra hva som virker best der og da Løses som regel ovenfra og ned; man tar et valg og ender opp med et mindre delproblem DP Optimal løsning avgjøres ved å se på optimale løsninger av delproblemer Løses nedenfra og opp; man løser større og større delproblemer ut i fra de mindre delløsningene

Sammendrag: krav for DP Rekursiv struktur Optimal substruktur Overlappende delproblemer (hvis ikke: splitt og hersk-algoritme) Løsning av ett delproblem avhenger av løsningene av andre delproblemer (hvis ikke: grådig algoritme) :: :: Nim er et fyrstikkspill der man har en haug fyrstikker og trekker 1- fyrstikker annenhver gang (antallet kan variere) og den som tar den siste fyrstikken vinner Vi vil nå spille : vi har et ruteark, og man skal hver gang klippe bort en remse på 1- ruters bredde fra en av kantene. Den som får servert en 1x1- rute til slutt har tapt Er det mulig for den som begynner å følge en strategi slik at han garantert vinner? En tilstand i spillet er beskrevet av størrelsen til det gjenværende rutearket En posisjon er vinnende hvis det er mulig å gjøre et trekk slik at motstanderen får servert en tapende posisjon En tapende posisjon er enten en posisjon hvor man taper i følge reglene, eller en posisjon hvor man ikke kan sette motstanderen i en annen tapende posisjon La oss sette opp dette i en tabell :: :: 1 2 7 8 9 1 L 2 7 8 9 1 2 7 8 9 1 L W W W L W W W L 2 7 8 9 :: :: 1 2 7 8 9 1 L W W W L W W W L 2 W L W W W L W W W 7 8 9

1 2 7 8 9 1 L W W W L W W W L 2 W L W W W L W W W W W L W W W L W W W W W L W W W L W L W W W L W W W L W L W W W L W W W 7 W W L W W W L W W 8 W W W L W W W L W 9 L W W W L W W W L :: :: Dermed kan man gjøre optimale trekk slik: mod = (height - width) % (maxcut + 1) if mod == 0: if width < height: height -= 1 width -= 1 if mod < height: height -= mod width -= maxcut + 1 mod return width, height? ::