Om grådighet og først litt mer DP. Live life and be merry Ellevte forelesning for tomorrow you may catch some disgusting skin disease. [Edmund Blackadder] 1
Litt repetisjon 2
Eksempel Longest Common Subsequence. Finner en felles subsekvens hos to sekvenser. Lengden kan brukes som et likhetsmål. Denne type algoritmer er vanlig i bioinformatikk og informasjonsg jenfinning. LCS 3
X i = [x1,, xi], Yi = [y1,, yi] X = X m, Y = Yn Z = [z 1,, zk] er en LCS av X og Y 4
Hvis de ikke deler siste element kan LCS-en utvides en selvmotsigelse. Hvis x m = yn: z k = xm = yn og Z k 1 er en LCS av Xm 1 og Yn 1 Det samme gjelder her hvis Xm-1 og Yn-1 har en lenger felles subsekvens så kan vi finne en lenger total felles subsekvens enn Z igjen en selvmotsigelse. 5
Hvis xm yn og zk xm: I begge tilfeller må Z være en felles subsekvens. Hvis det eksisterte en som var lenger vil den også være lenger totalt en selvmotsigelse. Z er en LCS av X m 1 og Y Hvis xm yn og zk yn: Z er en LCS av X og Y n 1 6
c[i,j] er lengden på en LCS av Xi og Yj., =, = =,, > =,, =, + (,,, ), > =. 7 Enten er xi og yj like eller ikke. Hvis de er det skal xi=yj=zk være med. Ellers vil Z være en LCS enten av Xi-1 og Y eller av X og Yj-1. Vi vet ikke hvilken, men prøver begge og velger den største.
(,,, ),, =,, +,,,,,,,,, I b-tabellen lagrer vi en referanse til hvor vi «kom fra». 8
9
X nedover til venstre, Y bortover på toppen. Nedoverpil: Dropp en bokstav fra X vekt 0. Bortoverpil: Dropp en bokstav fra Y vekt 0. Skråpil: Ta med bokstav fra X/Y: Vekt 1. Finn lengste vei fra øverst t.v. til nederst t.h. Dette er rett og slett DAG Shortest Path (eller Longest Path, da som jo blir like lett for DAG-er). 10
(,,, ) = =, = (,,, ), = (,,, ) (,,, ) 11
Egenskaper bak DP Optimal substruktur: En optimal løsning bygger på optimale løsninger på delproblemer Overlappende delproblemer: Fordi flere problemer deler delproblemer lønner det seg å lagre dem 12 Korteste vei? Har begge deler. Lengste vei (uten sykler)? Har ikke optimal substruktur Hvis vi ikke har overlappende delproblemer *kan* vi bruke DP, men det er egentlig ingen vits det blir bare splitt-og-hersk med unødvendig lagring av delproblemer.
2 1 2 2 ) @ < 2 Korteste vei oppdeling i delproblemer som må optimaliseres. Korteste veier består av korteste del-veier. 13
A * Lengste vei. Betrakt q-r-t, en maksimal sti fra q til t. Består den av lengste vei fra q til r og fra r til t? *Nei*! Vi kan ikke bruke DP (og har ingen annen god løsning heller). - ( 14
Kort om Matrisekjedemultiplikasjon 15
Vi vil løse ABC (AB)C kan ha en annen kostnad enn A(BC) Hvordan finner vi optimal parentes-setting? For hver splitt må hver halvdel løses optimalt Parametrisering: Start- og slutt-indeks 16
For hver start-indeks og hver slutt-indeks, prøv alle splitt-indekser og velg den som gir lavest kostnad. Vi bevarer beregningene for alle delproblemer, som før. Dette forklares ganske omstendelig i boka, men både problemet og løsningen er egentlig svært enkle. 17
K g i t k i orts Grådighet All form for optimalisering kan jo ses som «grådig», men med grådighet mener vi hær en nærsynt, kortsiktig, «hedonistisk» form for grådighet. Vi velger det som virker bra her og nå, uten å tenke på fremtiden. Noen kjente algoritmer som er grådige? (Spenntrær, Dijkstras algoritme og løsningen på fractional knapsack, f.eks.) Det er en veldig enkel strategi, så det som er interessant er: Når kan dette *også* være optimalt globalt/på lang sikt? 18
Minner om dynamisk programmering Brukes til optimalisering Når vi kan velge, velg det som er best lokalt Vis at løsningen også blir globalt optimal 19
I DAG-SP må vi prøve alle mulige veier tilbake fra slutt-noden til start-noden for å finne den beste. Dette vil fort ta eksponensiell tid. Heldigvis består hver optimale løsning av optimale del-løsninger og disse overlapper. Ved å gjenbruke dem (mellomlagring) får vi polynomisk (lineær) kjøretid. 3 1 4 1 2 1 2 3 3 Men hva om vi vet noe mer enn at vi har en DAG? Hva om vi kunne «nøste oss bakover» og velge riktig hele veien? For eksempel ved å velge den korteste kanten i hvert trinn 2 20
Her ble det jammen riktig! Dette er et eksempel på en grådig strategi og et tilfelle der den fungerte. Den fungerer naturligvis ikke for DAG-SP generelt men det viser at grådighet er beslektet med DP på et eller annet vis. 3 1 4 1 2 1 2 3 3 2 21
splitt-og-hersk dyn. prog. Del i uavhengige delproblemer og løs alle. Del i (potensielt overlappende) delproblemer og løs alle. grådighet Velg «nærsynt» hvilke delproblemer vi bryr oss om. Også her må vi ha optimal substruktur! 22 Dette er ingen «hardand-fast» taksonomi. Hva med binærsøk, f.eks.? Eller Dijkstras algoritme?
Grei metafor: Fyller ut puslespill rad for rad, med brikker av ulik pris. En grådig algoritme vil starte med den dyreste brikken, og alltid kaste dem som ikke passer. Spenntrær godt eksempel. $20 $10 $5 23
Eksempel Aktivitetsplukking 24
Vi har et sett med intervaller f.eks. tidsintervaller for aktiviteter som trenger en ekslusiv ressurs (f.eks. møter/ møterom). 1 5 1 4 1 2 1 7 1 9 1 1 1 3 1 6 1 8 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Vi vil velge et størst mulig subsett der ingen overlapper. 25
Optimal substruktur Aktiviteter i Sij er kompatible med alle hendelser som er avsluttet innen fi og alle som starter etter sj. Vi legger på a_0 = [-inf, 0) og a_n+1 = [inf, inf+1 ) Vi har da: S = S_0,n+1 Anta aktiviteter sortert etter slutt-tid. Hvis i j så S_ij = {} < := = {1 > < :. : - > <. > - = } = =. : - >. > - =...... 1 : 1 > 1 = Trenger bare bry oss om S_ij der 0 i < j n+1. Hvis S_ij inneholder a_k har vi to delproblemer: S_ik og S_kj 26 La A_ij være optimal løsning for S_ij. Vi har da: A_ij = A_ik + {a_k} + A_kj hvis vi antar at S_ij ikke er tom og at vi kjenner a_k.
Med andre ord: For et mulig subsett kan vi «splitte» på ulike objekter. Rekursiv definisjon av optimal løsning: Dette *kunne* vi ha løst med dynamisk programmering, *men* vi kan *forenkle* =,?, A = {?, A +?, A + } =. < < Vi må altså velge en k og vi må «kvitte» oss med ett delproblem. Finnes det et gyldig «nærsynt» valg? 27
Det at den første «halvdelen» forsvinner er ganske opplagt; ellers måtte et element der ha startet *før* elementet (for å være til venstre) og sluttet *etter* (for ikke å bli valgt) og vi ville da ha overlapp. Elementet som slutter først kan tas med «Halvdelen» før dette forsvinner Vi sitter altså igjen med ett delproblem men hvordan kan vi være sikker på at det elementet som slutter først er trygt å ta med? 28
La de grå være et optimalt ut valg. Det vil alltid være trygt å bytte den første av dem med det objektet som slutter først, siden det ikke kan «overlappe lenger» enn det grå objektet som slutter først. 29
30
(,,, ) + <,+ + { } (,,, ) (,,, ) While-løkken leter etter det første lovlige elementet. Altså det elementet som starter etter f og som har tidligst slutt-tid. (Antar sortering etter slutt-tid her.) Denne er jo rekursiv, da Vi kan godt gjøre den iterativ. 31
(,, ) { } { } Vi har altså bevist at det er trygt å alltid velge det første (etter slutt-tid) lovlige elementet og det er jo det vi gjør her. 32
Eksempel 1 5 1 4 1 2 1 7 1 9 1 1 1 3 1 6 1 8 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 33
Grådige strategier 34
1. Finn optimal substruktur Vi lager gjerne substrukturen med tanke nettopp på å kunne velge grådig og på å eliminere delproblemer. 2. Lag en rekursiv løsning 3. Vis at grådig valg er trygt 4. Vis vi sitter igjen med bare ett delproblem 5. Lag rekursiv grådig løsning 6. Konverter den til en iterativ løsning 35
Strømlinjeformet Såkalte «set systems» er en veldig generell problemstruktur for denne typen ting (se kapitlet om matroider i boka; ikke pensum). 1. Formuler som problem der vi kan velge grådig og sitte igjen med ett delproblem 2. Vis at det alltid er trygt å velge grådig 3. Vis at grådig valg + optimal del-løsning gir optimal løsning De siste to punktene gjelder for generelle strukturer som matroider og greedoider. En helt eksakt karakterisering av slike strukturer er gitt ved såkalte matroid embeddings. (Ikke pensum! :-)) 36
Vi har altså to hovedingredienser: Greedy-choice-egenskapen Optimal substruktur (Det finnes andre måter å bevise korrekthet for grådighet på, altså ) Det står om matroider i boka. Dere kan jo evt. også google greedoids eller hvis dere er eventyrlystne, matroid embeddings. 37
Eksempel Huffmankoder 38
e = a = q = Morsekode. Vi er ute etter noe litt lignende. En effektiv, variabel kode. z = 39
Prefikskoder (eller prefiksfrie koder): Koder der ingen koder er prefiks av andre koder. Mao. er det aldri tvil om dekodingen. Ulike tegn får koder med ulik lengde Vi kan bruke prefiks-koder Total tekst-lengde skal minimeres Vi har kun informasjon om tegnfrekvenser 40
Kodene blir prefiksfrie fordi vi ikke har tegn i de interne nodene. Venstre = 0, høyre = 1. a = 0 0 c b = 0 1 a b c = 1 Vi ønsker å minimere tegnfrekvens * tegndybde (implisitt også tekstlengde). Minner om de optimale søketrærne våre, men vi har ikke noe krav om rekkefølge. 41
Huffmans algoritme: Lag et tre for hvert tegn med frekvens-vekt Gjenta: Slå sammen de to letteste trærne 42
Prøv å tegne opp hvordan dette treet bygges helst trinn for trinn A : 8 B : 3 C : 1 D : 1 E : 1 F : 1 G : 1 H : 1 43
A : 8 B : 3 C : 1 D : 1 E : 1 F : 1 2 G : 1 H : 1 44
A : 8 B : 3 C : 1 D : 1 2 2 E : 1 F : 1 G : 1 H : 1 45
A : 8 B : 3 2 2 2 C : 1 D : 1 E : 1 F : 1 G : 1 H : 1 46
A : 8 B : 3 2 4 C : 1 D : 1 2 2 E : 1 F : 1 G : 1 H : 1 47
A : 8 5 4 B : 3 2 2 2 C : 1 D : 1 E : 1 F : 1 G : 1 H : 1 48
A : 8 9 5 4 B : 3 2 2 2 C : 1 D : 1 E : 1 F : 1 G : 1 H : 1 49
Merk: Dette minimerer forventet sti-lengde hvis vi «søker» etter en bokstav. Med andre ord er dette en mer effektiv variant av de optimale søketrærne fra forrige gang bortsett fra at søketre-egenskapen ikke er oppfylt. A : 8 17 Hvis man kan konstruere «ja/nei»- spørsmålene selv (som f.eks. ved en prosedyre for medisinsk diagnose), i stedet for å bruke søkenøkler, så kan Huffmans algoritme også brukes til denslags. 5 4 B : 3 2 2 2 9 Dette er jo klart en grådig fremgangsmåte men hvorfor blir det optimalt? C : 1 D : 1 E : 1 F : 1 G : 1 H : 1 50
Bevis-skisse: Hvis treet ikke er fullt kan vi kollapse stier der noder bare har ett (internt) barn. Bortkastet å ikke ha et fullt tre Det er OK for de to billigste å være søsken, nederst i treet Hvis de to billigste behandles som ett symbol må det resterende treet være optimalt Hvis vi bytter ut ett av dem med et dyrere vil det dyrere ikke komme lenger opp og det billige vil ikke komme lenger ned så det vil ikke bli billigere totalt. 51
Min. forv. koding Kombiner minste O(n lg n) Huffmans algoritme 52