36
Algoritmer og datastrukturer Pensumhefte, 2020 Magnus Lie Hetland

Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Algoritmer og datastrukturer

Pensumhefte 2020

Magnu

sLieHetland

2020-08-13 091253

Innledning

Hoslashsten 2020 vil det ikke avholdes ordinaeligre forelesninger I stedet brukes opptakfra 2019 med tilhoslashrende lysark (se nettsidene) Laeligringsmaringlene i pensumheftet eroppdaterte og teksten vil derfor ikke alltid stemme noslashyaktig overens med dem dufinner i lysarkene selv om de er ment aring dekke noslashyaktig det samme laeligringsutbyttetog pensumet Om du er i tvil saring er det pensumheftet som gjelder

Dette pensumheftet er en kombinasjon av tre ting

(i) En forelesningsplan

(ii) En pensumliste og

(iii) Et mini-kompendium

For hver forelesning er det listet opp hva som er hovedtema og hvilken del avpensum forelesningen bygger paring I tillegg har jeg laget en detaljert opplisting avlaeligringsmaringlene i faget for aring tydeliggjoslashre hva det er meningen at dere skal kunneBakerst i heftet er det noen appendiks med ekstra materiale og det utgjoslashr mini-kompendie-delen Sammen med pensumboka forelesningene og oslashvingene haringper jegat dette gir dere det dere trenger for aring sette dere inn i stoffet ndash men det er viktig aringhuske paring at det er dere som maring gjoslashre jobben med aring laeligre det

Her er det ikke bare faktakunnskap man skal tilegne seg det er ideer somkrever modning over litt tid og det er derfor viktig at dere begynner aring jobbetidlig og at dere jobber jevnt

Det er ikke saring taktisk aring utsette pensumlesningen til eksamensperioden og haringpe atet skippertak skal ordne biffen

Det er ogsaring viktig aring merke seg at laeligreboka [1] er viktig i dette faget Det er fleremaringter aring fremstille algoritmestoff paring og man kan selvfoslashlgelig bruke de ressurseneman vil for aring laeligre seg det Det finnes mange videoforelesninger og animasjoner oglignende paring nett og mye er forklart ganske rett frem i Wikipedia og ellers Mentil syvende og sist saring skal det jo vaeligre en eksamen i faget og der maring vi ha en ellerannen form for standardisering av rent praktiske hensyn

Derfor baserer vi oss paring antagelsen om at dere faktisk leser laeligreboka og atdere leser jevnt gjennom semesteret

i

Forelesningene skal gi deg et foslashrste moslashte med stoffet slik at det forharingpentligvisblir lettere aring forstaring boka naringr du setter deg ned for aring lese selv Det er ingen grunntil panikk om du ikke skjoslashnner absolutt alt i en forelesning eller om du ikke huskeralt etterparing Sannsynligvis er du bedre rustet til aring jobbe med stoffet uansett

Et hovedtips til studeringen kan vaeligre

Test deg selv

Det er et velkjent fenomen fra feks forskning paring hukommelse at om man leser entekst flere ganger saring kan man lures til aring tro at man husker den og kanskje til ogmed forstaringr den bare fordi den virker kjent Dette er en skummel felle aring garing i deter lett aring tro at man har skjoslashnt mer enn man har Oslashvingene gir deg en god mulighettil aring teste hva du faktisk har faringtt med deg men det garingr jo an aring finne andre maringter aringgjoslashre det paring ogsaring

Ikke bare er det aring gjoslashre oppgaver en viktig maringte aring teste deg selv paring men det erogsaring en maringte aring styrke hukommelsen paring ndash saringkalt recall training Det er mulig stoffetligger godt lagret men om du ikke trener paring aring hente det frem saring kan det vaeligre duikke husker det likevel Dessuten er oppgaver en god trening i aring anvende ferdighetenedu tilegner deg i faget Om du er interessert saring finnes det ogsaring store mengder medalgoritmeloslashsnings-oppgaver paring nett baringde knyttet til programmeringskonkurranserog til jobbintervjuer

En siste kanskje litt pussig gevinst ved aring loslashse oppgaver er at det kan bidra tilaring bygge opp mentale strukturer som er mottakelige for relaterte ideer Dette erdet saringkalte pretesting-fenomenet Om du proslashver deg paring en oppgave fra en del avpensum du ikke har laeligrt noe om ennaring selv om du vet at du ikke kommer til aringfaring den til saring kan det bidra til at du laeligrer stoffet bedre naringr du begynner aring jobbemed det Du trenger ikke se paring loslashsningen til oppgaven engang Her er det mangemuligheter ndash det er for eksempel fullt av oppgaver i laeligreboka og dem kan det vaeligrelurt aring kikke igjennom foslashr du begynner aring lese kanskje til og med foslashr forelesningen

Dette gjelder gamle eksamensoppgaver ogsaring naturligvis Vi proslashver aring variereform og innhold litt saring man ikke skal kunne laquopugge eksamenraquo men det kan likevelvaeligre lurt aring oslashve seg paring gamle eksamener De nyeste vil trolig vaeligre mest relevanteHer ogsaring kan pretesting vaeligre en tanke

Hva med aring proslashve deg paring et par eksamenssett allerede den foslashrste uka

Og skulle det vaeligre noe du ikke forstaringr noe du trenger hjelp til eller noe du vil slaringav en prat om saring gjoslashr gjerne det Om det er sposlashrsmaringl du tror flere kan ha nytteav aring se svaret paring saring sposlashr gjerne i fagets forum paring nett Ellers garingr det fint an aringsende e-post (for eksempel til algdatidintnuno) eller ta personlig kontakt medoslashvingsstaben eller meg

Om det er uvant aring skulle laeligre seg relativt teoretiske ting med hoslashy grad av

ii

presisjon saring finnes det generelle raringd og tips rundt dette En bok jeg har anbefaltflere og faringtt gode tilbakemeldinger paring er denne

Bokanbefaling

A mind for numbers av Barbara Oakley [2] Naeligrt knyttet til boka er Coursera-kurset Learning how to learn Powerful tools to help you master tough subjects

I de foslashlgende lister med laeligringsmaringl er noen merket med utropstegn Dette er enganske uformell greie men er ment aring indikere temaer som kanskje er viktigere ennman skulle tro Av og til betyr det de merkede maringlene er viktigere enn de andremen iblant ndash for mer marginale ting ndash saring er det mer av typen laquoObs Dette boslashr duikke nedprioritereraquo Men som sagt det er ganske uformelt og ikke noe du boslashr leggealtfor stor vekt paring

Overordnede laeligringsmaringl

De overordnede laeligringsmaringlene for faget er som foslashlgerlowast

Dere skal ha kunnskap om

[X1] Et bredt spekter av etablerte algoritmer og datastrukturer[X2] Klassiske algoritmiske problemer med kjente effektive loslashsninger[X3] Komplekse problemer uten kjente effektive loslashsninger

Dere skal kunne

[X4] Analysere algoritmers korrekthet og effektivitet[X5] Formulere problemer saring de kan loslashses av algoritmer

[X6] Konstruere nye effektive algoritmer

Dere skal vaeligre i stand til

[X7] Aring bruke eksisterende algoritmer og programvare paring nye problemer[X8] Aring utvikle nye loslashsninger paring praktiske algoritmiske problemstillinger

Mer spesifikke laeligringsmaringl er oppgitt for hver forelesning

Punkter nedenfor merket med er pensum Kapittelreferanser er til pensumbokaIntroduction to Algorithms [1]

lowast Se emnebeskrivelsenhttpsntnunostudieremnerTDT4120

iii

ForkunnskaperEn viss bakgrunn er noslashdvendig for aring faring fullt utbytte av faget som beskrevet i fagetsanbefalte forkunnskaperlowast Mye av dette kan man tilegne seg paring egen haringnd om manikke har hatt relevante fag men det kan da vaeligre lurt aring gjoslashre det saring tidlig som muligi semesteretDere boslashr

[Y1] Kjenne til begreper rundt monotone funksjoner[Y2] Kjenne til notasjonene dxe bxc n og a mod n

[Y3] Vite hva polynomer er[Y4] Kjenne grunnleggende potensregning[Y5] Ha noe kunnskap om grenseverdier

[Y6] Vaeligre godt kjent med logaritmer med ulike grunntall[Y7] Kjenne enkel sannsynlighetsregning indikatorvariable og forventning[Y8] Ha noe kjennskap til rekkesummer (se ogsaring side 15 i dette heftet)[Y9] Beherske helt grunnleggende mengdelaeligre[Y10] Kjenne grunnleggende terminologi for relasjoner ordninger og funksjoner[Y11] Kjenne grunnleggende terminologi for og egenskaper ved grafer og traeligr[Y12] Kjenne til enkel kombinatorikk som permutasjoner og kombinasjoner

De foslashlgende punktene er ment aring dekke de anbefalte forkunnskapene De er pensummen antas i hovedsak kjent (bortsett fra bruken av asymptotisk notasjon) Devil derfor i liten grad dekkes av forelesningene De er ogsaring i hovedsak ment sombakgrunnsstoff til hjelp for aring tilegne seg resten av stoffet og vil dermed i mindregrad bli spurt om direkte paring eksamen

Kap 3 Growth of functions 32

Kap 5 Probabilistic analysis s 118ndash120

App A Summations s 1145ndash1146 og ligning (A5)

App B Sets etc

App C Counting and probability s 1183ndash1185 C2 og s 1196ndash1198

Vi vil generelt proslashve aring friske opp relevant kunnskap men om dette stoffet er ukjentsaring regnes det altsaring stort sett som selvstudium Dersom det er noe dere finner spesieltvanskelig saring ta kontakt

Vi forventer ogsaring at dere behersker grunnleggende programmering at dere har noeerfaring med rekursjon og grunnleggende strukturer som tabeller (arrays) og lenkedelister Dere vil faring noe repetisjon av dettelowast Se emnebeskrivelsen

httpsntnunostudieremnerTDT4120

iv

Gjennom semesteretDet foslashlgende er pensum knyttet til flere forelesninger gjennom semesteret

Lysark fra ordinaeligre forelesninger

Appendiks til dette dokumentet

Laeligringsmaringl for hver algoritme

[Z1] Kjenne den formelle definisjonen av det generelle problemet den loslashser[Z2] Kjenne til eventuelle tilleggskrav den stiller for aring vaeligre korrekt[Z3] Vite hvordan den oppfoslashrer seg kunne utfoslashre algoritmen trinn for trinn

[Z4] Forstaring korrekthetsbeviset hvordan og hvorfor virker algoritmen egentlig[Z5] Kjenne til eventuelle styrker eller svakheter sammenlignet med andre[Z6] Kjenne kjoslashretidene under ulike omstendigheter og forstaring utregningen

Laeligringsmaringl for hver datastruktur

[Z7] Forstaring algoritmene (jf maringl Z01ndashZ06) for de ulike operasjonene paring strukturen[Z8] Forstaring hvordan strukturen representeres i minnet

Laeligringsmaringl for hvert problem

[Z9] Kunne angi presist hva input er[Z10] Kunne angi presist hva output er og hvilke egenskaper det maring ha

Hva betyr laquoforstaringraquo

Gode laeligringsmaringl og laeligringsutbyttebeskrivelser formuleres gjerne som hva manskal vaeligre i stand til om man oppnaringr maringlet For enkhelhets skyld har jeg fleresteder brukt begrepet forstaring Dette kan du i praksis oversette til kunne forklare

I pensumheftet brukes en del norske begreper mens laeligreboka er paring engelskEn oversikt over oversettelser som brukes finner du paring nettsidenealgdatidintnunoordhtml

v

PensumoversiktDelkapitler er ogsaring listet opp under tilhoslashrende forelesning sammen med laeligringsmaringlKapittel- og oppgavereferanser er til Introduction to Algorithms av Cormen mfl [1]

Kap 1 The role of algorithms in computing

Kap 2 Getting started

Kap 3 Growth of functions Innledning og 31

Kap 4 Divide-and-conquer Innledning 41 og 43ndash45

Kap 6 Heapsort

Kap 7 Quicksort

Kap 8 Sorting in linear time

Kap 9 Medians and order statistics

Kap 10 Elementary data structures

Kap 11 Hash tables s 253ndash264

Kap 12 Binary search trees Innledning og 121ndash123

Kap 15 Dynamic programming Innledning og 151 153ndash154

Kap 16 Greedy algorithms Innledning og 161ndash163

Kap 17 Amortized analysis Innledning og s 463ndash465 (tom laquoat most 3raquo)

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Kap 23 Minimum spanning trees

Kap 24 Single-source shortest paths Innledning og 241ndash243

Kap 25 All-pairs shortest paths Innledning 252 og 253

Kap 26 Maximum flow Innledning og 261ndash263

Kap 34 NP-completeness

Oppgaver 23-5 45-3 162-2 og 341-4 med loslashsning

Appendiks AndashF i dette heftet

1

Forelesning 1

Problemer og algoritmer

Vi starter med fagfeltets grunnleggende byggesteiner og skisserer et rammeverk foraring tilegne seg resten av stoffet Spesielt viktig er ideen bak induksjon og rekursjonVi trenger bare se paring siste trinn og kan anta at resten er paring plass

Pensum

Kap 1 The role of algorithms in computing

Kap 2 Getting started Innledning 21ndash22

Kap 3 Growth of functions Innledning og 31

Laeligringsmaringl

[A1] Forstaring bokas pseudokode-konvensjoner[A2] Kjenne egenskapene til random-access machine-modellen (RAM)[A3] Kunne definere problem instans og problemstoslashrrelse

[A4] Kunne definere asymptotisk notasjon O Ω Θ o og ω [A5] Kunne definere best-case average-case og worst-case [A6] Forstaring loslashkkeinvarianter og induksjon [A7] Forstaring rekursiv dekomponering og induksjon over delinstanser

[A8] Forstaring Insertion-Sort

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

2

Forelesning 2

Datastrukturer

For aring unngaring grunnleggende kjoslashretidsfeller er det viktig aring kunne organisere og struk-turere data fornuftig Her skal vi se paring hvordan enkle strukturer kan implementeresi praksis og hva vi vinner paring aring bruke dem i algoritmene varingre

Pensum

Kap 10 Elementary data structures Innledning og 101ndash103

Kap 11 Hash tables s 253ndash264

Kap 17 Amortized analysis Innledning og s 463ndash465 (tom laquoat most 3raquo)

Laeligringsmaringl

[B1] Forstaring hvordan stakker og koslasher fungerer(Stack-Empty Push Pop Enqueue Dequeue)

[B2] Forstaring hvordan lenkede lister fungerer(List-Search List-Insert List-Delete List-Deleteprime List-Searchprime List-Insertprime)

[B3] Forstaring hvordan pekere og objekter kan implementeres [B4] Forstaring hvordan direkte adressering og hashtabeller fungerer

(Hash-Insert Hash-Search)

[B5] Forstaring konfliktloslashsing ved kjeding (chaining)(Chained-Hash-Insert Chained-Hash-Search Chained-Hash-Delete)

[B6] Kjenne til grunnleggende hashfunksjoner[B7] Vite at man for statiske datasett kan ha worst-case O(1) for soslashk[B8] Kunne definere amortisert analyse[B9] Forstaring hvordan dynamiske tabeller fungerer

(Table-Insert)

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

3

Forelesning 3

Splitt og hersk

Rekursiv dekomponering er kanskje den viktigste ideen i hele faget og designmeto-den splitt og hersk er en grunnleggende utgave av det Del instansen i mindre biterloslashs problemet rekursivt for disse og kombineacuter loslashsningene

Pensum

Kap 2 Getting started 23

Kap 4 Divide-and-conquer Innledning 41 og 43ndash45

Kap 7 Quicksort

Oppgaver 23-5 og 45-3 med loslashsning (binaeligrsoslashk)

Appendiks B og C i dette heftet

Laeligringsmaringl

[C1] Forstaring designmetoden divide-and-conquer (splitt og hersk)[C2] Forstaring maximum-subarray-problemet med loslashsninger[C3] Forstaring Bisect og Bisectprime (se appendiks C i dette heftet)[C4] Forstaring Merge-Sort[C5] Forstaring Quicksort og Randomized-Quicksort

[C6] Kunne loslashse rekurrenser med substitusjon rekursjonstraeligr og masterteoremet [C7] Kunne loslashse rekurrenser med iterasjonsmetoden (se appendiks B i dette heftet)

[C8] Forstaring hvordan variabelskifte fungerer

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

4

Forelesning 4

Rangering i lineaeligr tid

Vi kan ofte faring bedre loslashsninger ved aring styrke kravene til input eller ved aring svekkekravene til output Sortering basert paring sammenligninger (x 6 y) er et klassiskeksempel I verste tilfelle maring vi bruke lg n sammenligningermen om vi antar merom elementene eller bare sorterer noen av dem saring kan vi gjoslashre det bedre

Pensum

Kap 8 Sorting in linear time

Kap 9 Medians and order statistics

Laeligringsmaringl

[D1] Forstaring hvorfor sammenligningsbasert sortering har en worst-case paring Ω(n lg n)[D2] Vite hva en stabil sorteringsalgoritme er[D3] Forstaring Counting-Sort og hvorfor den er stabil

[D4] Forstaring Radix-Sort og hvorfor den trenger en stabil subrutine[D5] Forstaring Bucket-Sort[D6] Forstaring Randomized-Select[D7] Kjenne til Select

Merk Det kreves ikke grundig forstaringelse av virkemaringten til Select

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

5

Forelesning 5

Rotfaste trestrukturer

Rotfaste traeligr gjenspeiler rekursiv dekomponering I binaeligre soslashketraeligr er alt i venst-re deltre mindre enn rota mens alt i hoslashyre deltre er stoslashrre og det gjelder rekursivtfor alle deltraeligr Hauger er enklere Alt er mindre enn rota Det begrenser funksjo-naliteten men gjoslashr dem billigere aring bygge og balansere

Pensum

Kap 6 Heapsort

Kap 10 Elementary data structures 104

Kap 12 Binary search trees Innledning og 121ndash123

Laeligringsmaringl

[E1] Forstaring hvordan heaps fungerer og hvordan de kan brukes som prioritetskoslasher(Parent Left Right Max-Heapify Build-Max-Heap Heapsort Max-Heap-InsertHeap-Extract-Max Heap-Increase-Key Heap-Maximum Ogsaring tilsvarende for min-heaps feks Build-Min-Heap og Heap-Extract-Min)

[E2] Forstaring Heapsort[E3] Forstaring hvordan rotfaste traeligr kan implementeres

[E4] Forstaring hvordan binaeligre soslashketraeligr fungerer(Inorder-Tree-Walk Tree-Search Iterative-Tree-Search Tree-Minimum Tree-Maximum Tree-Successor Tree-Predecessor Tree-Insert Transplant Tree-Delete)

[E5] Vite at forventet hoslashyde for et tilfeldig binaeligrt soslashketre er Θ(lg n)[E6] Vite at det finnes soslashketraeligr med garantert hoslashyde paring Θ(lg n)

Merk Det kreves ikke grundig forstaringelse av Transplant og Tree-Delete

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

6

Forelesning 6

Dynamisk programmering

Paring sett og vis en generalisering av splitt og hersk der delprobler kan overlappe Istedet for et tre av delinstans-avhengigheter har vi en rettet asyklisk graf Vi finnerog lagrer del-loslashsninger i en rekkefoslashlge som stemmer med avhengighetene

Pensum

Kap 15 Dynamic programming Innledning og 151 153ndash154

Oppgave 162-2 med loslashsning (0-1 knapsack)

Appendiks D i dette heftet

Delkapitler 152 og 155 kan vaeligre nyttige som stoslashttelitteratur

Laeligringsmaringl

[F1] Forstaring ideen om en delinstansgraf [F2] Forstaring designmetoden dynamisk programmering [F3] Forstaring loslashsning ved memoisering (top-down)

[F4] Forstaring loslashsning ved iterasjon (bottom-up)[F5] Forstaring hvordan man rekonstruerer en loslashsning fra lagrede beslutninger[F6] Forstaring hva optimal delstruktur er[F7] Forstaring hva overlappende delinstanser er[F8] Forstaring eksemplene stavkutting og LCS[F9] Forstaring loslashsningen paring det binaeligre ryggsekkproblemet (se appendiks D i dette

heftet)(Knapsack Knapsackprime)

Merk Noe av stoffet vil kanskje forskyves til forelesning 7

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

7

Forelesning 7

Graringdige algoritmer

Graringdige algoritmer bestaringr av en serie med valg og hvert valg tas lokalt Algorit-men gjoslashr alltid det som ser best ut her og naring uten noe stoslashrre perspektiv Slikealgoritmer er ofte enkle utfordringen ligger i aring finne ut om de gir rett svar

Pensum

Kap 16 Greedy algorithms Innledning og 161ndash163

Laeligringsmaringl

[G1] Forstaring designmetoden graringdighet [G2] Forstaring graringdighetsegenskapen (the greedy-choice property)

[G3] Forstaring eksemplene aktivitet-utvelgelse og det kontinuerlige ryggsekkproblemet[G4] Forstaring Huffman og Huffman-koder

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

8

Forelesning 8

Traversering av grafer

Vi traverserer en graf ved aring besoslashke noder vi vet om Vi vet i utgangspunktet bareom startnoden men oppdager naboene til dem vi besoslashker Traversering er viktig iseg selv men danner ogsaring ryggraden til flere mer avanserte algoritmer

Pensum

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Appendiks E i dette heftet

Laeligringsmaringl

[H1] Forstaring hvordan grafer kan implementeres[H2] Forstaring BFS ogsaring for aring finne korteste vei uten vekter[H3] Forstaring DFS og parentesteoremet[H4] Forstaring hvordan DFS klassifiserer kanter[H5] Forstaring Topological-Sort[H6] Forstaring hvordan DFS kan implementeres med en stakk[H7] Forstaring hva traverseringstraeligr (som bredde-foslashrst- og dybde-foslashrst-traeligr) er

[H8] Forstaring traversering med vilkaringrlig prioritetskoslash

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

9

Forelesning 9

Minimale spenntraeligr

Her har vi en graf med vekter paring kantene og oslashnsker aring bare beholde akkurat dekantene vi maring for aring koble sammen alle nodene med en saring lav vektsum som muligErke-eksempel paring graringdighet Velg eacuten og eacuten kant alltid den billigste lovlige

Pensum

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 23 Minimum spanning trees

Laeligringsmaringl

[I1] Forstaring skog-implementasjonen av disjunkte mengder(Connected-Components Same-Component Make-Set Union Link Find-Set)

[I2] Vite hva spenntraeligr og minimale spenntraeligr er [I3] Forstaring Generic-MST

[I4] Forstaring hvorfor lette kanter er trygge kanter[I5] Forstaring MST-Kruskal[I6] Forstaring MST-Prim

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

10

Forelesning 10

Korteste vei fra eacuten til alle

Bredde-foslashrst-soslashk kan finne stier med faeligrrest mulig kanter men hva om kantenehar ulik lengde Det generelle problemet er uloslashst men vi kan loslashse problemet medgradvis bedre kjoslashretid for grafer (1) uten negative sykler (2) uten negative kanterog (3) uten sykler Og vi bruker samme prinsipp for alle tre

Pensum

Kap 24 Single-source shortest paths Innledning og 241ndash243

Laeligringsmaringl

[J1] Forstaring ulike varianter av korteste-vei- eller korteste-sti-problemet(Single-source single-destination single-pair all-pairs)

[J2] Forstaring strukturen til korteste-vei-problemet[J3] Forstaring at negative sykler gir mening for korteste enkle vei (simple path)[J4] Forstaring at korteste enkle vei kan loslashses vha lengste enkle vei og omvendt[J5] Forstaring hvordan man kan representere et korteste-vei-tre

[J6] Forstaring kant-slakking (edge relaxation) og Relax[J7] Forstaring ulike egenskaper ved korteste veier og slakking

(Triangle inequality upper-bound property no-path property convergence property path-relaxation property predecessor-subgraph property)

[J8] Forstaring Bellman-Ford[J9] Forstaring DAG-Shortest-Path

[J10] Forstaring kobling mellom DAG-Shortest-Path og dynamisk programmering[J11] Forstaring Dijkstra

Merk Noe av stoffet vil kanskje forskyves til forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

11

Forelesning 11

Korteste vei fra alle til alle

Vi kan finne de korteste veiene fra hver node etter tur men mange av delinstanse-ne vil overlappe ndash om vi har mange nok kanter loslashnner det seg aring bruke dynamiskprogrammering med dekomponeringen laquoSkal vi innom k eller ikkeraquo

Pensum

Kap 25 All-pairs shortest paths Innledning 252 og 253

Laeligringsmaringl

[K1] Forstaring forgjengerstrukturen for alle-til-alle-varianten av korteste vei-problemet(Print-All-Pairs-Shortest-Path)

[K2] Forstaring Floyd-Warshall[K3] Forstaring Transitive-Closure[K4] Forstaring Johnson

Merk Noe stoff fra forelesning 12 vil kanskje dekkes her

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

12

Forelesning 12

Maksimal flyt

Et stort skritt i retning av generell lineaeligr optimering (saringkalt lineaeligr programme-ring) Her ser vi paring to tilsynelatende forskjellige problemer som viser seg aring vaeligreduale av hverandre noe som hjelper oss med aring finne en loslashsning

Pensum

Kap 26 Maximum flow Innledning og 261ndash263

Laeligringsmaringl

[L1] Kunne definere flytnett flyt og maks-flyt-problemet[L2] Kunne haringndtere antiparallelle kanter og flere kilder og sluk

[L3] Kunne definere restnettet til et flytnett med en gitt flyt[L4] Forstaring hvordan man kan oppheve (cancel) flyt[L5] Forstaring hva en foroslashkende sti (augmenting path) er[L6] Forstaring hva snitt snitt-kapasitet og minimalt snitt er

[L7] Forstaring maks-flytmin-snitt-teoremet[L8] Forstaring Ford-Fulkerson-Method og Ford-Fulkerson[L9] Vite at Ford-Fulkerson med BFS kalles Edmonds-Karp-algoritmen[L10] Forstaring hvordan maks-flyt kan finne en maksimum bipartitt matching

[L11] Forstaring heltallsteoremet (integrality theorem)

Merk Noe av stoffet vil kanskje dekkes i forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

13

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 2: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

2020-08-13 091253

Innledning

Hoslashsten 2020 vil det ikke avholdes ordinaeligre forelesninger I stedet brukes opptakfra 2019 med tilhoslashrende lysark (se nettsidene) Laeligringsmaringlene i pensumheftet eroppdaterte og teksten vil derfor ikke alltid stemme noslashyaktig overens med dem dufinner i lysarkene selv om de er ment aring dekke noslashyaktig det samme laeligringsutbyttetog pensumet Om du er i tvil saring er det pensumheftet som gjelder

Dette pensumheftet er en kombinasjon av tre ting

(i) En forelesningsplan

(ii) En pensumliste og

(iii) Et mini-kompendium

For hver forelesning er det listet opp hva som er hovedtema og hvilken del avpensum forelesningen bygger paring I tillegg har jeg laget en detaljert opplisting avlaeligringsmaringlene i faget for aring tydeliggjoslashre hva det er meningen at dere skal kunneBakerst i heftet er det noen appendiks med ekstra materiale og det utgjoslashr mini-kompendie-delen Sammen med pensumboka forelesningene og oslashvingene haringper jegat dette gir dere det dere trenger for aring sette dere inn i stoffet ndash men det er viktig aringhuske paring at det er dere som maring gjoslashre jobben med aring laeligre det

Her er det ikke bare faktakunnskap man skal tilegne seg det er ideer somkrever modning over litt tid og det er derfor viktig at dere begynner aring jobbetidlig og at dere jobber jevnt

Det er ikke saring taktisk aring utsette pensumlesningen til eksamensperioden og haringpe atet skippertak skal ordne biffen

Det er ogsaring viktig aring merke seg at laeligreboka [1] er viktig i dette faget Det er fleremaringter aring fremstille algoritmestoff paring og man kan selvfoslashlgelig bruke de ressurseneman vil for aring laeligre seg det Det finnes mange videoforelesninger og animasjoner oglignende paring nett og mye er forklart ganske rett frem i Wikipedia og ellers Mentil syvende og sist saring skal det jo vaeligre en eksamen i faget og der maring vi ha en ellerannen form for standardisering av rent praktiske hensyn

Derfor baserer vi oss paring antagelsen om at dere faktisk leser laeligreboka og atdere leser jevnt gjennom semesteret

i

Forelesningene skal gi deg et foslashrste moslashte med stoffet slik at det forharingpentligvisblir lettere aring forstaring boka naringr du setter deg ned for aring lese selv Det er ingen grunntil panikk om du ikke skjoslashnner absolutt alt i en forelesning eller om du ikke huskeralt etterparing Sannsynligvis er du bedre rustet til aring jobbe med stoffet uansett

Et hovedtips til studeringen kan vaeligre

Test deg selv

Det er et velkjent fenomen fra feks forskning paring hukommelse at om man leser entekst flere ganger saring kan man lures til aring tro at man husker den og kanskje til ogmed forstaringr den bare fordi den virker kjent Dette er en skummel felle aring garing i deter lett aring tro at man har skjoslashnt mer enn man har Oslashvingene gir deg en god mulighettil aring teste hva du faktisk har faringtt med deg men det garingr jo an aring finne andre maringter aringgjoslashre det paring ogsaring

Ikke bare er det aring gjoslashre oppgaver en viktig maringte aring teste deg selv paring men det erogsaring en maringte aring styrke hukommelsen paring ndash saringkalt recall training Det er mulig stoffetligger godt lagret men om du ikke trener paring aring hente det frem saring kan det vaeligre duikke husker det likevel Dessuten er oppgaver en god trening i aring anvende ferdighetenedu tilegner deg i faget Om du er interessert saring finnes det ogsaring store mengder medalgoritmeloslashsnings-oppgaver paring nett baringde knyttet til programmeringskonkurranserog til jobbintervjuer

En siste kanskje litt pussig gevinst ved aring loslashse oppgaver er at det kan bidra tilaring bygge opp mentale strukturer som er mottakelige for relaterte ideer Dette erdet saringkalte pretesting-fenomenet Om du proslashver deg paring en oppgave fra en del avpensum du ikke har laeligrt noe om ennaring selv om du vet at du ikke kommer til aringfaring den til saring kan det bidra til at du laeligrer stoffet bedre naringr du begynner aring jobbemed det Du trenger ikke se paring loslashsningen til oppgaven engang Her er det mangemuligheter ndash det er for eksempel fullt av oppgaver i laeligreboka og dem kan det vaeligrelurt aring kikke igjennom foslashr du begynner aring lese kanskje til og med foslashr forelesningen

Dette gjelder gamle eksamensoppgaver ogsaring naturligvis Vi proslashver aring variereform og innhold litt saring man ikke skal kunne laquopugge eksamenraquo men det kan likevelvaeligre lurt aring oslashve seg paring gamle eksamener De nyeste vil trolig vaeligre mest relevanteHer ogsaring kan pretesting vaeligre en tanke

Hva med aring proslashve deg paring et par eksamenssett allerede den foslashrste uka

Og skulle det vaeligre noe du ikke forstaringr noe du trenger hjelp til eller noe du vil slaringav en prat om saring gjoslashr gjerne det Om det er sposlashrsmaringl du tror flere kan ha nytteav aring se svaret paring saring sposlashr gjerne i fagets forum paring nett Ellers garingr det fint an aringsende e-post (for eksempel til algdatidintnuno) eller ta personlig kontakt medoslashvingsstaben eller meg

Om det er uvant aring skulle laeligre seg relativt teoretiske ting med hoslashy grad av

ii

presisjon saring finnes det generelle raringd og tips rundt dette En bok jeg har anbefaltflere og faringtt gode tilbakemeldinger paring er denne

Bokanbefaling

A mind for numbers av Barbara Oakley [2] Naeligrt knyttet til boka er Coursera-kurset Learning how to learn Powerful tools to help you master tough subjects

I de foslashlgende lister med laeligringsmaringl er noen merket med utropstegn Dette er enganske uformell greie men er ment aring indikere temaer som kanskje er viktigere ennman skulle tro Av og til betyr det de merkede maringlene er viktigere enn de andremen iblant ndash for mer marginale ting ndash saring er det mer av typen laquoObs Dette boslashr duikke nedprioritereraquo Men som sagt det er ganske uformelt og ikke noe du boslashr leggealtfor stor vekt paring

Overordnede laeligringsmaringl

De overordnede laeligringsmaringlene for faget er som foslashlgerlowast

Dere skal ha kunnskap om

[X1] Et bredt spekter av etablerte algoritmer og datastrukturer[X2] Klassiske algoritmiske problemer med kjente effektive loslashsninger[X3] Komplekse problemer uten kjente effektive loslashsninger

Dere skal kunne

[X4] Analysere algoritmers korrekthet og effektivitet[X5] Formulere problemer saring de kan loslashses av algoritmer

[X6] Konstruere nye effektive algoritmer

Dere skal vaeligre i stand til

[X7] Aring bruke eksisterende algoritmer og programvare paring nye problemer[X8] Aring utvikle nye loslashsninger paring praktiske algoritmiske problemstillinger

Mer spesifikke laeligringsmaringl er oppgitt for hver forelesning

Punkter nedenfor merket med er pensum Kapittelreferanser er til pensumbokaIntroduction to Algorithms [1]

lowast Se emnebeskrivelsenhttpsntnunostudieremnerTDT4120

iii

ForkunnskaperEn viss bakgrunn er noslashdvendig for aring faring fullt utbytte av faget som beskrevet i fagetsanbefalte forkunnskaperlowast Mye av dette kan man tilegne seg paring egen haringnd om manikke har hatt relevante fag men det kan da vaeligre lurt aring gjoslashre det saring tidlig som muligi semesteretDere boslashr

[Y1] Kjenne til begreper rundt monotone funksjoner[Y2] Kjenne til notasjonene dxe bxc n og a mod n

[Y3] Vite hva polynomer er[Y4] Kjenne grunnleggende potensregning[Y5] Ha noe kunnskap om grenseverdier

[Y6] Vaeligre godt kjent med logaritmer med ulike grunntall[Y7] Kjenne enkel sannsynlighetsregning indikatorvariable og forventning[Y8] Ha noe kjennskap til rekkesummer (se ogsaring side 15 i dette heftet)[Y9] Beherske helt grunnleggende mengdelaeligre[Y10] Kjenne grunnleggende terminologi for relasjoner ordninger og funksjoner[Y11] Kjenne grunnleggende terminologi for og egenskaper ved grafer og traeligr[Y12] Kjenne til enkel kombinatorikk som permutasjoner og kombinasjoner

De foslashlgende punktene er ment aring dekke de anbefalte forkunnskapene De er pensummen antas i hovedsak kjent (bortsett fra bruken av asymptotisk notasjon) Devil derfor i liten grad dekkes av forelesningene De er ogsaring i hovedsak ment sombakgrunnsstoff til hjelp for aring tilegne seg resten av stoffet og vil dermed i mindregrad bli spurt om direkte paring eksamen

Kap 3 Growth of functions 32

Kap 5 Probabilistic analysis s 118ndash120

App A Summations s 1145ndash1146 og ligning (A5)

App B Sets etc

App C Counting and probability s 1183ndash1185 C2 og s 1196ndash1198

Vi vil generelt proslashve aring friske opp relevant kunnskap men om dette stoffet er ukjentsaring regnes det altsaring stort sett som selvstudium Dersom det er noe dere finner spesieltvanskelig saring ta kontakt

Vi forventer ogsaring at dere behersker grunnleggende programmering at dere har noeerfaring med rekursjon og grunnleggende strukturer som tabeller (arrays) og lenkedelister Dere vil faring noe repetisjon av dettelowast Se emnebeskrivelsen

httpsntnunostudieremnerTDT4120

iv

Gjennom semesteretDet foslashlgende er pensum knyttet til flere forelesninger gjennom semesteret

Lysark fra ordinaeligre forelesninger

Appendiks til dette dokumentet

Laeligringsmaringl for hver algoritme

[Z1] Kjenne den formelle definisjonen av det generelle problemet den loslashser[Z2] Kjenne til eventuelle tilleggskrav den stiller for aring vaeligre korrekt[Z3] Vite hvordan den oppfoslashrer seg kunne utfoslashre algoritmen trinn for trinn

[Z4] Forstaring korrekthetsbeviset hvordan og hvorfor virker algoritmen egentlig[Z5] Kjenne til eventuelle styrker eller svakheter sammenlignet med andre[Z6] Kjenne kjoslashretidene under ulike omstendigheter og forstaring utregningen

Laeligringsmaringl for hver datastruktur

[Z7] Forstaring algoritmene (jf maringl Z01ndashZ06) for de ulike operasjonene paring strukturen[Z8] Forstaring hvordan strukturen representeres i minnet

Laeligringsmaringl for hvert problem

[Z9] Kunne angi presist hva input er[Z10] Kunne angi presist hva output er og hvilke egenskaper det maring ha

Hva betyr laquoforstaringraquo

Gode laeligringsmaringl og laeligringsutbyttebeskrivelser formuleres gjerne som hva manskal vaeligre i stand til om man oppnaringr maringlet For enkhelhets skyld har jeg fleresteder brukt begrepet forstaring Dette kan du i praksis oversette til kunne forklare

I pensumheftet brukes en del norske begreper mens laeligreboka er paring engelskEn oversikt over oversettelser som brukes finner du paring nettsidenealgdatidintnunoordhtml

v

PensumoversiktDelkapitler er ogsaring listet opp under tilhoslashrende forelesning sammen med laeligringsmaringlKapittel- og oppgavereferanser er til Introduction to Algorithms av Cormen mfl [1]

Kap 1 The role of algorithms in computing

Kap 2 Getting started

Kap 3 Growth of functions Innledning og 31

Kap 4 Divide-and-conquer Innledning 41 og 43ndash45

Kap 6 Heapsort

Kap 7 Quicksort

Kap 8 Sorting in linear time

Kap 9 Medians and order statistics

Kap 10 Elementary data structures

Kap 11 Hash tables s 253ndash264

Kap 12 Binary search trees Innledning og 121ndash123

Kap 15 Dynamic programming Innledning og 151 153ndash154

Kap 16 Greedy algorithms Innledning og 161ndash163

Kap 17 Amortized analysis Innledning og s 463ndash465 (tom laquoat most 3raquo)

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Kap 23 Minimum spanning trees

Kap 24 Single-source shortest paths Innledning og 241ndash243

Kap 25 All-pairs shortest paths Innledning 252 og 253

Kap 26 Maximum flow Innledning og 261ndash263

Kap 34 NP-completeness

Oppgaver 23-5 45-3 162-2 og 341-4 med loslashsning

Appendiks AndashF i dette heftet

1

Forelesning 1

Problemer og algoritmer

Vi starter med fagfeltets grunnleggende byggesteiner og skisserer et rammeverk foraring tilegne seg resten av stoffet Spesielt viktig er ideen bak induksjon og rekursjonVi trenger bare se paring siste trinn og kan anta at resten er paring plass

Pensum

Kap 1 The role of algorithms in computing

Kap 2 Getting started Innledning 21ndash22

Kap 3 Growth of functions Innledning og 31

Laeligringsmaringl

[A1] Forstaring bokas pseudokode-konvensjoner[A2] Kjenne egenskapene til random-access machine-modellen (RAM)[A3] Kunne definere problem instans og problemstoslashrrelse

[A4] Kunne definere asymptotisk notasjon O Ω Θ o og ω [A5] Kunne definere best-case average-case og worst-case [A6] Forstaring loslashkkeinvarianter og induksjon [A7] Forstaring rekursiv dekomponering og induksjon over delinstanser

[A8] Forstaring Insertion-Sort

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

2

Forelesning 2

Datastrukturer

For aring unngaring grunnleggende kjoslashretidsfeller er det viktig aring kunne organisere og struk-turere data fornuftig Her skal vi se paring hvordan enkle strukturer kan implementeresi praksis og hva vi vinner paring aring bruke dem i algoritmene varingre

Pensum

Kap 10 Elementary data structures Innledning og 101ndash103

Kap 11 Hash tables s 253ndash264

Kap 17 Amortized analysis Innledning og s 463ndash465 (tom laquoat most 3raquo)

Laeligringsmaringl

[B1] Forstaring hvordan stakker og koslasher fungerer(Stack-Empty Push Pop Enqueue Dequeue)

[B2] Forstaring hvordan lenkede lister fungerer(List-Search List-Insert List-Delete List-Deleteprime List-Searchprime List-Insertprime)

[B3] Forstaring hvordan pekere og objekter kan implementeres [B4] Forstaring hvordan direkte adressering og hashtabeller fungerer

(Hash-Insert Hash-Search)

[B5] Forstaring konfliktloslashsing ved kjeding (chaining)(Chained-Hash-Insert Chained-Hash-Search Chained-Hash-Delete)

[B6] Kjenne til grunnleggende hashfunksjoner[B7] Vite at man for statiske datasett kan ha worst-case O(1) for soslashk[B8] Kunne definere amortisert analyse[B9] Forstaring hvordan dynamiske tabeller fungerer

(Table-Insert)

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

3

Forelesning 3

Splitt og hersk

Rekursiv dekomponering er kanskje den viktigste ideen i hele faget og designmeto-den splitt og hersk er en grunnleggende utgave av det Del instansen i mindre biterloslashs problemet rekursivt for disse og kombineacuter loslashsningene

Pensum

Kap 2 Getting started 23

Kap 4 Divide-and-conquer Innledning 41 og 43ndash45

Kap 7 Quicksort

Oppgaver 23-5 og 45-3 med loslashsning (binaeligrsoslashk)

Appendiks B og C i dette heftet

Laeligringsmaringl

[C1] Forstaring designmetoden divide-and-conquer (splitt og hersk)[C2] Forstaring maximum-subarray-problemet med loslashsninger[C3] Forstaring Bisect og Bisectprime (se appendiks C i dette heftet)[C4] Forstaring Merge-Sort[C5] Forstaring Quicksort og Randomized-Quicksort

[C6] Kunne loslashse rekurrenser med substitusjon rekursjonstraeligr og masterteoremet [C7] Kunne loslashse rekurrenser med iterasjonsmetoden (se appendiks B i dette heftet)

[C8] Forstaring hvordan variabelskifte fungerer

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

4

Forelesning 4

Rangering i lineaeligr tid

Vi kan ofte faring bedre loslashsninger ved aring styrke kravene til input eller ved aring svekkekravene til output Sortering basert paring sammenligninger (x 6 y) er et klassiskeksempel I verste tilfelle maring vi bruke lg n sammenligningermen om vi antar merom elementene eller bare sorterer noen av dem saring kan vi gjoslashre det bedre

Pensum

Kap 8 Sorting in linear time

Kap 9 Medians and order statistics

Laeligringsmaringl

[D1] Forstaring hvorfor sammenligningsbasert sortering har en worst-case paring Ω(n lg n)[D2] Vite hva en stabil sorteringsalgoritme er[D3] Forstaring Counting-Sort og hvorfor den er stabil

[D4] Forstaring Radix-Sort og hvorfor den trenger en stabil subrutine[D5] Forstaring Bucket-Sort[D6] Forstaring Randomized-Select[D7] Kjenne til Select

Merk Det kreves ikke grundig forstaringelse av virkemaringten til Select

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

5

Forelesning 5

Rotfaste trestrukturer

Rotfaste traeligr gjenspeiler rekursiv dekomponering I binaeligre soslashketraeligr er alt i venst-re deltre mindre enn rota mens alt i hoslashyre deltre er stoslashrre og det gjelder rekursivtfor alle deltraeligr Hauger er enklere Alt er mindre enn rota Det begrenser funksjo-naliteten men gjoslashr dem billigere aring bygge og balansere

Pensum

Kap 6 Heapsort

Kap 10 Elementary data structures 104

Kap 12 Binary search trees Innledning og 121ndash123

Laeligringsmaringl

[E1] Forstaring hvordan heaps fungerer og hvordan de kan brukes som prioritetskoslasher(Parent Left Right Max-Heapify Build-Max-Heap Heapsort Max-Heap-InsertHeap-Extract-Max Heap-Increase-Key Heap-Maximum Ogsaring tilsvarende for min-heaps feks Build-Min-Heap og Heap-Extract-Min)

[E2] Forstaring Heapsort[E3] Forstaring hvordan rotfaste traeligr kan implementeres

[E4] Forstaring hvordan binaeligre soslashketraeligr fungerer(Inorder-Tree-Walk Tree-Search Iterative-Tree-Search Tree-Minimum Tree-Maximum Tree-Successor Tree-Predecessor Tree-Insert Transplant Tree-Delete)

[E5] Vite at forventet hoslashyde for et tilfeldig binaeligrt soslashketre er Θ(lg n)[E6] Vite at det finnes soslashketraeligr med garantert hoslashyde paring Θ(lg n)

Merk Det kreves ikke grundig forstaringelse av Transplant og Tree-Delete

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

6

Forelesning 6

Dynamisk programmering

Paring sett og vis en generalisering av splitt og hersk der delprobler kan overlappe Istedet for et tre av delinstans-avhengigheter har vi en rettet asyklisk graf Vi finnerog lagrer del-loslashsninger i en rekkefoslashlge som stemmer med avhengighetene

Pensum

Kap 15 Dynamic programming Innledning og 151 153ndash154

Oppgave 162-2 med loslashsning (0-1 knapsack)

Appendiks D i dette heftet

Delkapitler 152 og 155 kan vaeligre nyttige som stoslashttelitteratur

Laeligringsmaringl

[F1] Forstaring ideen om en delinstansgraf [F2] Forstaring designmetoden dynamisk programmering [F3] Forstaring loslashsning ved memoisering (top-down)

[F4] Forstaring loslashsning ved iterasjon (bottom-up)[F5] Forstaring hvordan man rekonstruerer en loslashsning fra lagrede beslutninger[F6] Forstaring hva optimal delstruktur er[F7] Forstaring hva overlappende delinstanser er[F8] Forstaring eksemplene stavkutting og LCS[F9] Forstaring loslashsningen paring det binaeligre ryggsekkproblemet (se appendiks D i dette

heftet)(Knapsack Knapsackprime)

Merk Noe av stoffet vil kanskje forskyves til forelesning 7

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

7

Forelesning 7

Graringdige algoritmer

Graringdige algoritmer bestaringr av en serie med valg og hvert valg tas lokalt Algorit-men gjoslashr alltid det som ser best ut her og naring uten noe stoslashrre perspektiv Slikealgoritmer er ofte enkle utfordringen ligger i aring finne ut om de gir rett svar

Pensum

Kap 16 Greedy algorithms Innledning og 161ndash163

Laeligringsmaringl

[G1] Forstaring designmetoden graringdighet [G2] Forstaring graringdighetsegenskapen (the greedy-choice property)

[G3] Forstaring eksemplene aktivitet-utvelgelse og det kontinuerlige ryggsekkproblemet[G4] Forstaring Huffman og Huffman-koder

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

8

Forelesning 8

Traversering av grafer

Vi traverserer en graf ved aring besoslashke noder vi vet om Vi vet i utgangspunktet bareom startnoden men oppdager naboene til dem vi besoslashker Traversering er viktig iseg selv men danner ogsaring ryggraden til flere mer avanserte algoritmer

Pensum

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Appendiks E i dette heftet

Laeligringsmaringl

[H1] Forstaring hvordan grafer kan implementeres[H2] Forstaring BFS ogsaring for aring finne korteste vei uten vekter[H3] Forstaring DFS og parentesteoremet[H4] Forstaring hvordan DFS klassifiserer kanter[H5] Forstaring Topological-Sort[H6] Forstaring hvordan DFS kan implementeres med en stakk[H7] Forstaring hva traverseringstraeligr (som bredde-foslashrst- og dybde-foslashrst-traeligr) er

[H8] Forstaring traversering med vilkaringrlig prioritetskoslash

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

9

Forelesning 9

Minimale spenntraeligr

Her har vi en graf med vekter paring kantene og oslashnsker aring bare beholde akkurat dekantene vi maring for aring koble sammen alle nodene med en saring lav vektsum som muligErke-eksempel paring graringdighet Velg eacuten og eacuten kant alltid den billigste lovlige

Pensum

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 23 Minimum spanning trees

Laeligringsmaringl

[I1] Forstaring skog-implementasjonen av disjunkte mengder(Connected-Components Same-Component Make-Set Union Link Find-Set)

[I2] Vite hva spenntraeligr og minimale spenntraeligr er [I3] Forstaring Generic-MST

[I4] Forstaring hvorfor lette kanter er trygge kanter[I5] Forstaring MST-Kruskal[I6] Forstaring MST-Prim

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

10

Forelesning 10

Korteste vei fra eacuten til alle

Bredde-foslashrst-soslashk kan finne stier med faeligrrest mulig kanter men hva om kantenehar ulik lengde Det generelle problemet er uloslashst men vi kan loslashse problemet medgradvis bedre kjoslashretid for grafer (1) uten negative sykler (2) uten negative kanterog (3) uten sykler Og vi bruker samme prinsipp for alle tre

Pensum

Kap 24 Single-source shortest paths Innledning og 241ndash243

Laeligringsmaringl

[J1] Forstaring ulike varianter av korteste-vei- eller korteste-sti-problemet(Single-source single-destination single-pair all-pairs)

[J2] Forstaring strukturen til korteste-vei-problemet[J3] Forstaring at negative sykler gir mening for korteste enkle vei (simple path)[J4] Forstaring at korteste enkle vei kan loslashses vha lengste enkle vei og omvendt[J5] Forstaring hvordan man kan representere et korteste-vei-tre

[J6] Forstaring kant-slakking (edge relaxation) og Relax[J7] Forstaring ulike egenskaper ved korteste veier og slakking

(Triangle inequality upper-bound property no-path property convergence property path-relaxation property predecessor-subgraph property)

[J8] Forstaring Bellman-Ford[J9] Forstaring DAG-Shortest-Path

[J10] Forstaring kobling mellom DAG-Shortest-Path og dynamisk programmering[J11] Forstaring Dijkstra

Merk Noe av stoffet vil kanskje forskyves til forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

11

Forelesning 11

Korteste vei fra alle til alle

Vi kan finne de korteste veiene fra hver node etter tur men mange av delinstanse-ne vil overlappe ndash om vi har mange nok kanter loslashnner det seg aring bruke dynamiskprogrammering med dekomponeringen laquoSkal vi innom k eller ikkeraquo

Pensum

Kap 25 All-pairs shortest paths Innledning 252 og 253

Laeligringsmaringl

[K1] Forstaring forgjengerstrukturen for alle-til-alle-varianten av korteste vei-problemet(Print-All-Pairs-Shortest-Path)

[K2] Forstaring Floyd-Warshall[K3] Forstaring Transitive-Closure[K4] Forstaring Johnson

Merk Noe stoff fra forelesning 12 vil kanskje dekkes her

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

12

Forelesning 12

Maksimal flyt

Et stort skritt i retning av generell lineaeligr optimering (saringkalt lineaeligr programme-ring) Her ser vi paring to tilsynelatende forskjellige problemer som viser seg aring vaeligreduale av hverandre noe som hjelper oss med aring finne en loslashsning

Pensum

Kap 26 Maximum flow Innledning og 261ndash263

Laeligringsmaringl

[L1] Kunne definere flytnett flyt og maks-flyt-problemet[L2] Kunne haringndtere antiparallelle kanter og flere kilder og sluk

[L3] Kunne definere restnettet til et flytnett med en gitt flyt[L4] Forstaring hvordan man kan oppheve (cancel) flyt[L5] Forstaring hva en foroslashkende sti (augmenting path) er[L6] Forstaring hva snitt snitt-kapasitet og minimalt snitt er

[L7] Forstaring maks-flytmin-snitt-teoremet[L8] Forstaring Ford-Fulkerson-Method og Ford-Fulkerson[L9] Vite at Ford-Fulkerson med BFS kalles Edmonds-Karp-algoritmen[L10] Forstaring hvordan maks-flyt kan finne en maksimum bipartitt matching

[L11] Forstaring heltallsteoremet (integrality theorem)

Merk Noe av stoffet vil kanskje dekkes i forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

13

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 3: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Innledning

Hoslashsten 2020 vil det ikke avholdes ordinaeligre forelesninger I stedet brukes opptakfra 2019 med tilhoslashrende lysark (se nettsidene) Laeligringsmaringlene i pensumheftet eroppdaterte og teksten vil derfor ikke alltid stemme noslashyaktig overens med dem dufinner i lysarkene selv om de er ment aring dekke noslashyaktig det samme laeligringsutbyttetog pensumet Om du er i tvil saring er det pensumheftet som gjelder

Dette pensumheftet er en kombinasjon av tre ting

(i) En forelesningsplan

(ii) En pensumliste og

(iii) Et mini-kompendium

For hver forelesning er det listet opp hva som er hovedtema og hvilken del avpensum forelesningen bygger paring I tillegg har jeg laget en detaljert opplisting avlaeligringsmaringlene i faget for aring tydeliggjoslashre hva det er meningen at dere skal kunneBakerst i heftet er det noen appendiks med ekstra materiale og det utgjoslashr mini-kompendie-delen Sammen med pensumboka forelesningene og oslashvingene haringper jegat dette gir dere det dere trenger for aring sette dere inn i stoffet ndash men det er viktig aringhuske paring at det er dere som maring gjoslashre jobben med aring laeligre det

Her er det ikke bare faktakunnskap man skal tilegne seg det er ideer somkrever modning over litt tid og det er derfor viktig at dere begynner aring jobbetidlig og at dere jobber jevnt

Det er ikke saring taktisk aring utsette pensumlesningen til eksamensperioden og haringpe atet skippertak skal ordne biffen

Det er ogsaring viktig aring merke seg at laeligreboka [1] er viktig i dette faget Det er fleremaringter aring fremstille algoritmestoff paring og man kan selvfoslashlgelig bruke de ressurseneman vil for aring laeligre seg det Det finnes mange videoforelesninger og animasjoner oglignende paring nett og mye er forklart ganske rett frem i Wikipedia og ellers Mentil syvende og sist saring skal det jo vaeligre en eksamen i faget og der maring vi ha en ellerannen form for standardisering av rent praktiske hensyn

Derfor baserer vi oss paring antagelsen om at dere faktisk leser laeligreboka og atdere leser jevnt gjennom semesteret

i

Forelesningene skal gi deg et foslashrste moslashte med stoffet slik at det forharingpentligvisblir lettere aring forstaring boka naringr du setter deg ned for aring lese selv Det er ingen grunntil panikk om du ikke skjoslashnner absolutt alt i en forelesning eller om du ikke huskeralt etterparing Sannsynligvis er du bedre rustet til aring jobbe med stoffet uansett

Et hovedtips til studeringen kan vaeligre

Test deg selv

Det er et velkjent fenomen fra feks forskning paring hukommelse at om man leser entekst flere ganger saring kan man lures til aring tro at man husker den og kanskje til ogmed forstaringr den bare fordi den virker kjent Dette er en skummel felle aring garing i deter lett aring tro at man har skjoslashnt mer enn man har Oslashvingene gir deg en god mulighettil aring teste hva du faktisk har faringtt med deg men det garingr jo an aring finne andre maringter aringgjoslashre det paring ogsaring

Ikke bare er det aring gjoslashre oppgaver en viktig maringte aring teste deg selv paring men det erogsaring en maringte aring styrke hukommelsen paring ndash saringkalt recall training Det er mulig stoffetligger godt lagret men om du ikke trener paring aring hente det frem saring kan det vaeligre duikke husker det likevel Dessuten er oppgaver en god trening i aring anvende ferdighetenedu tilegner deg i faget Om du er interessert saring finnes det ogsaring store mengder medalgoritmeloslashsnings-oppgaver paring nett baringde knyttet til programmeringskonkurranserog til jobbintervjuer

En siste kanskje litt pussig gevinst ved aring loslashse oppgaver er at det kan bidra tilaring bygge opp mentale strukturer som er mottakelige for relaterte ideer Dette erdet saringkalte pretesting-fenomenet Om du proslashver deg paring en oppgave fra en del avpensum du ikke har laeligrt noe om ennaring selv om du vet at du ikke kommer til aringfaring den til saring kan det bidra til at du laeligrer stoffet bedre naringr du begynner aring jobbemed det Du trenger ikke se paring loslashsningen til oppgaven engang Her er det mangemuligheter ndash det er for eksempel fullt av oppgaver i laeligreboka og dem kan det vaeligrelurt aring kikke igjennom foslashr du begynner aring lese kanskje til og med foslashr forelesningen

Dette gjelder gamle eksamensoppgaver ogsaring naturligvis Vi proslashver aring variereform og innhold litt saring man ikke skal kunne laquopugge eksamenraquo men det kan likevelvaeligre lurt aring oslashve seg paring gamle eksamener De nyeste vil trolig vaeligre mest relevanteHer ogsaring kan pretesting vaeligre en tanke

Hva med aring proslashve deg paring et par eksamenssett allerede den foslashrste uka

Og skulle det vaeligre noe du ikke forstaringr noe du trenger hjelp til eller noe du vil slaringav en prat om saring gjoslashr gjerne det Om det er sposlashrsmaringl du tror flere kan ha nytteav aring se svaret paring saring sposlashr gjerne i fagets forum paring nett Ellers garingr det fint an aringsende e-post (for eksempel til algdatidintnuno) eller ta personlig kontakt medoslashvingsstaben eller meg

Om det er uvant aring skulle laeligre seg relativt teoretiske ting med hoslashy grad av

ii

presisjon saring finnes det generelle raringd og tips rundt dette En bok jeg har anbefaltflere og faringtt gode tilbakemeldinger paring er denne

Bokanbefaling

A mind for numbers av Barbara Oakley [2] Naeligrt knyttet til boka er Coursera-kurset Learning how to learn Powerful tools to help you master tough subjects

I de foslashlgende lister med laeligringsmaringl er noen merket med utropstegn Dette er enganske uformell greie men er ment aring indikere temaer som kanskje er viktigere ennman skulle tro Av og til betyr det de merkede maringlene er viktigere enn de andremen iblant ndash for mer marginale ting ndash saring er det mer av typen laquoObs Dette boslashr duikke nedprioritereraquo Men som sagt det er ganske uformelt og ikke noe du boslashr leggealtfor stor vekt paring

Overordnede laeligringsmaringl

De overordnede laeligringsmaringlene for faget er som foslashlgerlowast

Dere skal ha kunnskap om

[X1] Et bredt spekter av etablerte algoritmer og datastrukturer[X2] Klassiske algoritmiske problemer med kjente effektive loslashsninger[X3] Komplekse problemer uten kjente effektive loslashsninger

Dere skal kunne

[X4] Analysere algoritmers korrekthet og effektivitet[X5] Formulere problemer saring de kan loslashses av algoritmer

[X6] Konstruere nye effektive algoritmer

Dere skal vaeligre i stand til

[X7] Aring bruke eksisterende algoritmer og programvare paring nye problemer[X8] Aring utvikle nye loslashsninger paring praktiske algoritmiske problemstillinger

Mer spesifikke laeligringsmaringl er oppgitt for hver forelesning

Punkter nedenfor merket med er pensum Kapittelreferanser er til pensumbokaIntroduction to Algorithms [1]

lowast Se emnebeskrivelsenhttpsntnunostudieremnerTDT4120

iii

ForkunnskaperEn viss bakgrunn er noslashdvendig for aring faring fullt utbytte av faget som beskrevet i fagetsanbefalte forkunnskaperlowast Mye av dette kan man tilegne seg paring egen haringnd om manikke har hatt relevante fag men det kan da vaeligre lurt aring gjoslashre det saring tidlig som muligi semesteretDere boslashr

[Y1] Kjenne til begreper rundt monotone funksjoner[Y2] Kjenne til notasjonene dxe bxc n og a mod n

[Y3] Vite hva polynomer er[Y4] Kjenne grunnleggende potensregning[Y5] Ha noe kunnskap om grenseverdier

[Y6] Vaeligre godt kjent med logaritmer med ulike grunntall[Y7] Kjenne enkel sannsynlighetsregning indikatorvariable og forventning[Y8] Ha noe kjennskap til rekkesummer (se ogsaring side 15 i dette heftet)[Y9] Beherske helt grunnleggende mengdelaeligre[Y10] Kjenne grunnleggende terminologi for relasjoner ordninger og funksjoner[Y11] Kjenne grunnleggende terminologi for og egenskaper ved grafer og traeligr[Y12] Kjenne til enkel kombinatorikk som permutasjoner og kombinasjoner

De foslashlgende punktene er ment aring dekke de anbefalte forkunnskapene De er pensummen antas i hovedsak kjent (bortsett fra bruken av asymptotisk notasjon) Devil derfor i liten grad dekkes av forelesningene De er ogsaring i hovedsak ment sombakgrunnsstoff til hjelp for aring tilegne seg resten av stoffet og vil dermed i mindregrad bli spurt om direkte paring eksamen

Kap 3 Growth of functions 32

Kap 5 Probabilistic analysis s 118ndash120

App A Summations s 1145ndash1146 og ligning (A5)

App B Sets etc

App C Counting and probability s 1183ndash1185 C2 og s 1196ndash1198

Vi vil generelt proslashve aring friske opp relevant kunnskap men om dette stoffet er ukjentsaring regnes det altsaring stort sett som selvstudium Dersom det er noe dere finner spesieltvanskelig saring ta kontakt

Vi forventer ogsaring at dere behersker grunnleggende programmering at dere har noeerfaring med rekursjon og grunnleggende strukturer som tabeller (arrays) og lenkedelister Dere vil faring noe repetisjon av dettelowast Se emnebeskrivelsen

httpsntnunostudieremnerTDT4120

iv

Gjennom semesteretDet foslashlgende er pensum knyttet til flere forelesninger gjennom semesteret

Lysark fra ordinaeligre forelesninger

Appendiks til dette dokumentet

Laeligringsmaringl for hver algoritme

[Z1] Kjenne den formelle definisjonen av det generelle problemet den loslashser[Z2] Kjenne til eventuelle tilleggskrav den stiller for aring vaeligre korrekt[Z3] Vite hvordan den oppfoslashrer seg kunne utfoslashre algoritmen trinn for trinn

[Z4] Forstaring korrekthetsbeviset hvordan og hvorfor virker algoritmen egentlig[Z5] Kjenne til eventuelle styrker eller svakheter sammenlignet med andre[Z6] Kjenne kjoslashretidene under ulike omstendigheter og forstaring utregningen

Laeligringsmaringl for hver datastruktur

[Z7] Forstaring algoritmene (jf maringl Z01ndashZ06) for de ulike operasjonene paring strukturen[Z8] Forstaring hvordan strukturen representeres i minnet

Laeligringsmaringl for hvert problem

[Z9] Kunne angi presist hva input er[Z10] Kunne angi presist hva output er og hvilke egenskaper det maring ha

Hva betyr laquoforstaringraquo

Gode laeligringsmaringl og laeligringsutbyttebeskrivelser formuleres gjerne som hva manskal vaeligre i stand til om man oppnaringr maringlet For enkhelhets skyld har jeg fleresteder brukt begrepet forstaring Dette kan du i praksis oversette til kunne forklare

I pensumheftet brukes en del norske begreper mens laeligreboka er paring engelskEn oversikt over oversettelser som brukes finner du paring nettsidenealgdatidintnunoordhtml

v

PensumoversiktDelkapitler er ogsaring listet opp under tilhoslashrende forelesning sammen med laeligringsmaringlKapittel- og oppgavereferanser er til Introduction to Algorithms av Cormen mfl [1]

Kap 1 The role of algorithms in computing

Kap 2 Getting started

Kap 3 Growth of functions Innledning og 31

Kap 4 Divide-and-conquer Innledning 41 og 43ndash45

Kap 6 Heapsort

Kap 7 Quicksort

Kap 8 Sorting in linear time

Kap 9 Medians and order statistics

Kap 10 Elementary data structures

Kap 11 Hash tables s 253ndash264

Kap 12 Binary search trees Innledning og 121ndash123

Kap 15 Dynamic programming Innledning og 151 153ndash154

Kap 16 Greedy algorithms Innledning og 161ndash163

Kap 17 Amortized analysis Innledning og s 463ndash465 (tom laquoat most 3raquo)

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Kap 23 Minimum spanning trees

Kap 24 Single-source shortest paths Innledning og 241ndash243

Kap 25 All-pairs shortest paths Innledning 252 og 253

Kap 26 Maximum flow Innledning og 261ndash263

Kap 34 NP-completeness

Oppgaver 23-5 45-3 162-2 og 341-4 med loslashsning

Appendiks AndashF i dette heftet

1

Forelesning 1

Problemer og algoritmer

Vi starter med fagfeltets grunnleggende byggesteiner og skisserer et rammeverk foraring tilegne seg resten av stoffet Spesielt viktig er ideen bak induksjon og rekursjonVi trenger bare se paring siste trinn og kan anta at resten er paring plass

Pensum

Kap 1 The role of algorithms in computing

Kap 2 Getting started Innledning 21ndash22

Kap 3 Growth of functions Innledning og 31

Laeligringsmaringl

[A1] Forstaring bokas pseudokode-konvensjoner[A2] Kjenne egenskapene til random-access machine-modellen (RAM)[A3] Kunne definere problem instans og problemstoslashrrelse

[A4] Kunne definere asymptotisk notasjon O Ω Θ o og ω [A5] Kunne definere best-case average-case og worst-case [A6] Forstaring loslashkkeinvarianter og induksjon [A7] Forstaring rekursiv dekomponering og induksjon over delinstanser

[A8] Forstaring Insertion-Sort

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

2

Forelesning 2

Datastrukturer

For aring unngaring grunnleggende kjoslashretidsfeller er det viktig aring kunne organisere og struk-turere data fornuftig Her skal vi se paring hvordan enkle strukturer kan implementeresi praksis og hva vi vinner paring aring bruke dem i algoritmene varingre

Pensum

Kap 10 Elementary data structures Innledning og 101ndash103

Kap 11 Hash tables s 253ndash264

Kap 17 Amortized analysis Innledning og s 463ndash465 (tom laquoat most 3raquo)

Laeligringsmaringl

[B1] Forstaring hvordan stakker og koslasher fungerer(Stack-Empty Push Pop Enqueue Dequeue)

[B2] Forstaring hvordan lenkede lister fungerer(List-Search List-Insert List-Delete List-Deleteprime List-Searchprime List-Insertprime)

[B3] Forstaring hvordan pekere og objekter kan implementeres [B4] Forstaring hvordan direkte adressering og hashtabeller fungerer

(Hash-Insert Hash-Search)

[B5] Forstaring konfliktloslashsing ved kjeding (chaining)(Chained-Hash-Insert Chained-Hash-Search Chained-Hash-Delete)

[B6] Kjenne til grunnleggende hashfunksjoner[B7] Vite at man for statiske datasett kan ha worst-case O(1) for soslashk[B8] Kunne definere amortisert analyse[B9] Forstaring hvordan dynamiske tabeller fungerer

(Table-Insert)

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

3

Forelesning 3

Splitt og hersk

Rekursiv dekomponering er kanskje den viktigste ideen i hele faget og designmeto-den splitt og hersk er en grunnleggende utgave av det Del instansen i mindre biterloslashs problemet rekursivt for disse og kombineacuter loslashsningene

Pensum

Kap 2 Getting started 23

Kap 4 Divide-and-conquer Innledning 41 og 43ndash45

Kap 7 Quicksort

Oppgaver 23-5 og 45-3 med loslashsning (binaeligrsoslashk)

Appendiks B og C i dette heftet

Laeligringsmaringl

[C1] Forstaring designmetoden divide-and-conquer (splitt og hersk)[C2] Forstaring maximum-subarray-problemet med loslashsninger[C3] Forstaring Bisect og Bisectprime (se appendiks C i dette heftet)[C4] Forstaring Merge-Sort[C5] Forstaring Quicksort og Randomized-Quicksort

[C6] Kunne loslashse rekurrenser med substitusjon rekursjonstraeligr og masterteoremet [C7] Kunne loslashse rekurrenser med iterasjonsmetoden (se appendiks B i dette heftet)

[C8] Forstaring hvordan variabelskifte fungerer

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

4

Forelesning 4

Rangering i lineaeligr tid

Vi kan ofte faring bedre loslashsninger ved aring styrke kravene til input eller ved aring svekkekravene til output Sortering basert paring sammenligninger (x 6 y) er et klassiskeksempel I verste tilfelle maring vi bruke lg n sammenligningermen om vi antar merom elementene eller bare sorterer noen av dem saring kan vi gjoslashre det bedre

Pensum

Kap 8 Sorting in linear time

Kap 9 Medians and order statistics

Laeligringsmaringl

[D1] Forstaring hvorfor sammenligningsbasert sortering har en worst-case paring Ω(n lg n)[D2] Vite hva en stabil sorteringsalgoritme er[D3] Forstaring Counting-Sort og hvorfor den er stabil

[D4] Forstaring Radix-Sort og hvorfor den trenger en stabil subrutine[D5] Forstaring Bucket-Sort[D6] Forstaring Randomized-Select[D7] Kjenne til Select

Merk Det kreves ikke grundig forstaringelse av virkemaringten til Select

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

5

Forelesning 5

Rotfaste trestrukturer

Rotfaste traeligr gjenspeiler rekursiv dekomponering I binaeligre soslashketraeligr er alt i venst-re deltre mindre enn rota mens alt i hoslashyre deltre er stoslashrre og det gjelder rekursivtfor alle deltraeligr Hauger er enklere Alt er mindre enn rota Det begrenser funksjo-naliteten men gjoslashr dem billigere aring bygge og balansere

Pensum

Kap 6 Heapsort

Kap 10 Elementary data structures 104

Kap 12 Binary search trees Innledning og 121ndash123

Laeligringsmaringl

[E1] Forstaring hvordan heaps fungerer og hvordan de kan brukes som prioritetskoslasher(Parent Left Right Max-Heapify Build-Max-Heap Heapsort Max-Heap-InsertHeap-Extract-Max Heap-Increase-Key Heap-Maximum Ogsaring tilsvarende for min-heaps feks Build-Min-Heap og Heap-Extract-Min)

[E2] Forstaring Heapsort[E3] Forstaring hvordan rotfaste traeligr kan implementeres

[E4] Forstaring hvordan binaeligre soslashketraeligr fungerer(Inorder-Tree-Walk Tree-Search Iterative-Tree-Search Tree-Minimum Tree-Maximum Tree-Successor Tree-Predecessor Tree-Insert Transplant Tree-Delete)

[E5] Vite at forventet hoslashyde for et tilfeldig binaeligrt soslashketre er Θ(lg n)[E6] Vite at det finnes soslashketraeligr med garantert hoslashyde paring Θ(lg n)

Merk Det kreves ikke grundig forstaringelse av Transplant og Tree-Delete

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

6

Forelesning 6

Dynamisk programmering

Paring sett og vis en generalisering av splitt og hersk der delprobler kan overlappe Istedet for et tre av delinstans-avhengigheter har vi en rettet asyklisk graf Vi finnerog lagrer del-loslashsninger i en rekkefoslashlge som stemmer med avhengighetene

Pensum

Kap 15 Dynamic programming Innledning og 151 153ndash154

Oppgave 162-2 med loslashsning (0-1 knapsack)

Appendiks D i dette heftet

Delkapitler 152 og 155 kan vaeligre nyttige som stoslashttelitteratur

Laeligringsmaringl

[F1] Forstaring ideen om en delinstansgraf [F2] Forstaring designmetoden dynamisk programmering [F3] Forstaring loslashsning ved memoisering (top-down)

[F4] Forstaring loslashsning ved iterasjon (bottom-up)[F5] Forstaring hvordan man rekonstruerer en loslashsning fra lagrede beslutninger[F6] Forstaring hva optimal delstruktur er[F7] Forstaring hva overlappende delinstanser er[F8] Forstaring eksemplene stavkutting og LCS[F9] Forstaring loslashsningen paring det binaeligre ryggsekkproblemet (se appendiks D i dette

heftet)(Knapsack Knapsackprime)

Merk Noe av stoffet vil kanskje forskyves til forelesning 7

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

7

Forelesning 7

Graringdige algoritmer

Graringdige algoritmer bestaringr av en serie med valg og hvert valg tas lokalt Algorit-men gjoslashr alltid det som ser best ut her og naring uten noe stoslashrre perspektiv Slikealgoritmer er ofte enkle utfordringen ligger i aring finne ut om de gir rett svar

Pensum

Kap 16 Greedy algorithms Innledning og 161ndash163

Laeligringsmaringl

[G1] Forstaring designmetoden graringdighet [G2] Forstaring graringdighetsegenskapen (the greedy-choice property)

[G3] Forstaring eksemplene aktivitet-utvelgelse og det kontinuerlige ryggsekkproblemet[G4] Forstaring Huffman og Huffman-koder

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

8

Forelesning 8

Traversering av grafer

Vi traverserer en graf ved aring besoslashke noder vi vet om Vi vet i utgangspunktet bareom startnoden men oppdager naboene til dem vi besoslashker Traversering er viktig iseg selv men danner ogsaring ryggraden til flere mer avanserte algoritmer

Pensum

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Appendiks E i dette heftet

Laeligringsmaringl

[H1] Forstaring hvordan grafer kan implementeres[H2] Forstaring BFS ogsaring for aring finne korteste vei uten vekter[H3] Forstaring DFS og parentesteoremet[H4] Forstaring hvordan DFS klassifiserer kanter[H5] Forstaring Topological-Sort[H6] Forstaring hvordan DFS kan implementeres med en stakk[H7] Forstaring hva traverseringstraeligr (som bredde-foslashrst- og dybde-foslashrst-traeligr) er

[H8] Forstaring traversering med vilkaringrlig prioritetskoslash

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

9

Forelesning 9

Minimale spenntraeligr

Her har vi en graf med vekter paring kantene og oslashnsker aring bare beholde akkurat dekantene vi maring for aring koble sammen alle nodene med en saring lav vektsum som muligErke-eksempel paring graringdighet Velg eacuten og eacuten kant alltid den billigste lovlige

Pensum

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 23 Minimum spanning trees

Laeligringsmaringl

[I1] Forstaring skog-implementasjonen av disjunkte mengder(Connected-Components Same-Component Make-Set Union Link Find-Set)

[I2] Vite hva spenntraeligr og minimale spenntraeligr er [I3] Forstaring Generic-MST

[I4] Forstaring hvorfor lette kanter er trygge kanter[I5] Forstaring MST-Kruskal[I6] Forstaring MST-Prim

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

10

Forelesning 10

Korteste vei fra eacuten til alle

Bredde-foslashrst-soslashk kan finne stier med faeligrrest mulig kanter men hva om kantenehar ulik lengde Det generelle problemet er uloslashst men vi kan loslashse problemet medgradvis bedre kjoslashretid for grafer (1) uten negative sykler (2) uten negative kanterog (3) uten sykler Og vi bruker samme prinsipp for alle tre

Pensum

Kap 24 Single-source shortest paths Innledning og 241ndash243

Laeligringsmaringl

[J1] Forstaring ulike varianter av korteste-vei- eller korteste-sti-problemet(Single-source single-destination single-pair all-pairs)

[J2] Forstaring strukturen til korteste-vei-problemet[J3] Forstaring at negative sykler gir mening for korteste enkle vei (simple path)[J4] Forstaring at korteste enkle vei kan loslashses vha lengste enkle vei og omvendt[J5] Forstaring hvordan man kan representere et korteste-vei-tre

[J6] Forstaring kant-slakking (edge relaxation) og Relax[J7] Forstaring ulike egenskaper ved korteste veier og slakking

(Triangle inequality upper-bound property no-path property convergence property path-relaxation property predecessor-subgraph property)

[J8] Forstaring Bellman-Ford[J9] Forstaring DAG-Shortest-Path

[J10] Forstaring kobling mellom DAG-Shortest-Path og dynamisk programmering[J11] Forstaring Dijkstra

Merk Noe av stoffet vil kanskje forskyves til forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

11

Forelesning 11

Korteste vei fra alle til alle

Vi kan finne de korteste veiene fra hver node etter tur men mange av delinstanse-ne vil overlappe ndash om vi har mange nok kanter loslashnner det seg aring bruke dynamiskprogrammering med dekomponeringen laquoSkal vi innom k eller ikkeraquo

Pensum

Kap 25 All-pairs shortest paths Innledning 252 og 253

Laeligringsmaringl

[K1] Forstaring forgjengerstrukturen for alle-til-alle-varianten av korteste vei-problemet(Print-All-Pairs-Shortest-Path)

[K2] Forstaring Floyd-Warshall[K3] Forstaring Transitive-Closure[K4] Forstaring Johnson

Merk Noe stoff fra forelesning 12 vil kanskje dekkes her

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

12

Forelesning 12

Maksimal flyt

Et stort skritt i retning av generell lineaeligr optimering (saringkalt lineaeligr programme-ring) Her ser vi paring to tilsynelatende forskjellige problemer som viser seg aring vaeligreduale av hverandre noe som hjelper oss med aring finne en loslashsning

Pensum

Kap 26 Maximum flow Innledning og 261ndash263

Laeligringsmaringl

[L1] Kunne definere flytnett flyt og maks-flyt-problemet[L2] Kunne haringndtere antiparallelle kanter og flere kilder og sluk

[L3] Kunne definere restnettet til et flytnett med en gitt flyt[L4] Forstaring hvordan man kan oppheve (cancel) flyt[L5] Forstaring hva en foroslashkende sti (augmenting path) er[L6] Forstaring hva snitt snitt-kapasitet og minimalt snitt er

[L7] Forstaring maks-flytmin-snitt-teoremet[L8] Forstaring Ford-Fulkerson-Method og Ford-Fulkerson[L9] Vite at Ford-Fulkerson med BFS kalles Edmonds-Karp-algoritmen[L10] Forstaring hvordan maks-flyt kan finne en maksimum bipartitt matching

[L11] Forstaring heltallsteoremet (integrality theorem)

Merk Noe av stoffet vil kanskje dekkes i forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

13

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 4: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Forelesningene skal gi deg et foslashrste moslashte med stoffet slik at det forharingpentligvisblir lettere aring forstaring boka naringr du setter deg ned for aring lese selv Det er ingen grunntil panikk om du ikke skjoslashnner absolutt alt i en forelesning eller om du ikke huskeralt etterparing Sannsynligvis er du bedre rustet til aring jobbe med stoffet uansett

Et hovedtips til studeringen kan vaeligre

Test deg selv

Det er et velkjent fenomen fra feks forskning paring hukommelse at om man leser entekst flere ganger saring kan man lures til aring tro at man husker den og kanskje til ogmed forstaringr den bare fordi den virker kjent Dette er en skummel felle aring garing i deter lett aring tro at man har skjoslashnt mer enn man har Oslashvingene gir deg en god mulighettil aring teste hva du faktisk har faringtt med deg men det garingr jo an aring finne andre maringter aringgjoslashre det paring ogsaring

Ikke bare er det aring gjoslashre oppgaver en viktig maringte aring teste deg selv paring men det erogsaring en maringte aring styrke hukommelsen paring ndash saringkalt recall training Det er mulig stoffetligger godt lagret men om du ikke trener paring aring hente det frem saring kan det vaeligre duikke husker det likevel Dessuten er oppgaver en god trening i aring anvende ferdighetenedu tilegner deg i faget Om du er interessert saring finnes det ogsaring store mengder medalgoritmeloslashsnings-oppgaver paring nett baringde knyttet til programmeringskonkurranserog til jobbintervjuer

En siste kanskje litt pussig gevinst ved aring loslashse oppgaver er at det kan bidra tilaring bygge opp mentale strukturer som er mottakelige for relaterte ideer Dette erdet saringkalte pretesting-fenomenet Om du proslashver deg paring en oppgave fra en del avpensum du ikke har laeligrt noe om ennaring selv om du vet at du ikke kommer til aringfaring den til saring kan det bidra til at du laeligrer stoffet bedre naringr du begynner aring jobbemed det Du trenger ikke se paring loslashsningen til oppgaven engang Her er det mangemuligheter ndash det er for eksempel fullt av oppgaver i laeligreboka og dem kan det vaeligrelurt aring kikke igjennom foslashr du begynner aring lese kanskje til og med foslashr forelesningen

Dette gjelder gamle eksamensoppgaver ogsaring naturligvis Vi proslashver aring variereform og innhold litt saring man ikke skal kunne laquopugge eksamenraquo men det kan likevelvaeligre lurt aring oslashve seg paring gamle eksamener De nyeste vil trolig vaeligre mest relevanteHer ogsaring kan pretesting vaeligre en tanke

Hva med aring proslashve deg paring et par eksamenssett allerede den foslashrste uka

Og skulle det vaeligre noe du ikke forstaringr noe du trenger hjelp til eller noe du vil slaringav en prat om saring gjoslashr gjerne det Om det er sposlashrsmaringl du tror flere kan ha nytteav aring se svaret paring saring sposlashr gjerne i fagets forum paring nett Ellers garingr det fint an aringsende e-post (for eksempel til algdatidintnuno) eller ta personlig kontakt medoslashvingsstaben eller meg

Om det er uvant aring skulle laeligre seg relativt teoretiske ting med hoslashy grad av

ii

presisjon saring finnes det generelle raringd og tips rundt dette En bok jeg har anbefaltflere og faringtt gode tilbakemeldinger paring er denne

Bokanbefaling

A mind for numbers av Barbara Oakley [2] Naeligrt knyttet til boka er Coursera-kurset Learning how to learn Powerful tools to help you master tough subjects

I de foslashlgende lister med laeligringsmaringl er noen merket med utropstegn Dette er enganske uformell greie men er ment aring indikere temaer som kanskje er viktigere ennman skulle tro Av og til betyr det de merkede maringlene er viktigere enn de andremen iblant ndash for mer marginale ting ndash saring er det mer av typen laquoObs Dette boslashr duikke nedprioritereraquo Men som sagt det er ganske uformelt og ikke noe du boslashr leggealtfor stor vekt paring

Overordnede laeligringsmaringl

De overordnede laeligringsmaringlene for faget er som foslashlgerlowast

Dere skal ha kunnskap om

[X1] Et bredt spekter av etablerte algoritmer og datastrukturer[X2] Klassiske algoritmiske problemer med kjente effektive loslashsninger[X3] Komplekse problemer uten kjente effektive loslashsninger

Dere skal kunne

[X4] Analysere algoritmers korrekthet og effektivitet[X5] Formulere problemer saring de kan loslashses av algoritmer

[X6] Konstruere nye effektive algoritmer

Dere skal vaeligre i stand til

[X7] Aring bruke eksisterende algoritmer og programvare paring nye problemer[X8] Aring utvikle nye loslashsninger paring praktiske algoritmiske problemstillinger

Mer spesifikke laeligringsmaringl er oppgitt for hver forelesning

Punkter nedenfor merket med er pensum Kapittelreferanser er til pensumbokaIntroduction to Algorithms [1]

lowast Se emnebeskrivelsenhttpsntnunostudieremnerTDT4120

iii

ForkunnskaperEn viss bakgrunn er noslashdvendig for aring faring fullt utbytte av faget som beskrevet i fagetsanbefalte forkunnskaperlowast Mye av dette kan man tilegne seg paring egen haringnd om manikke har hatt relevante fag men det kan da vaeligre lurt aring gjoslashre det saring tidlig som muligi semesteretDere boslashr

[Y1] Kjenne til begreper rundt monotone funksjoner[Y2] Kjenne til notasjonene dxe bxc n og a mod n

[Y3] Vite hva polynomer er[Y4] Kjenne grunnleggende potensregning[Y5] Ha noe kunnskap om grenseverdier

[Y6] Vaeligre godt kjent med logaritmer med ulike grunntall[Y7] Kjenne enkel sannsynlighetsregning indikatorvariable og forventning[Y8] Ha noe kjennskap til rekkesummer (se ogsaring side 15 i dette heftet)[Y9] Beherske helt grunnleggende mengdelaeligre[Y10] Kjenne grunnleggende terminologi for relasjoner ordninger og funksjoner[Y11] Kjenne grunnleggende terminologi for og egenskaper ved grafer og traeligr[Y12] Kjenne til enkel kombinatorikk som permutasjoner og kombinasjoner

De foslashlgende punktene er ment aring dekke de anbefalte forkunnskapene De er pensummen antas i hovedsak kjent (bortsett fra bruken av asymptotisk notasjon) Devil derfor i liten grad dekkes av forelesningene De er ogsaring i hovedsak ment sombakgrunnsstoff til hjelp for aring tilegne seg resten av stoffet og vil dermed i mindregrad bli spurt om direkte paring eksamen

Kap 3 Growth of functions 32

Kap 5 Probabilistic analysis s 118ndash120

App A Summations s 1145ndash1146 og ligning (A5)

App B Sets etc

App C Counting and probability s 1183ndash1185 C2 og s 1196ndash1198

Vi vil generelt proslashve aring friske opp relevant kunnskap men om dette stoffet er ukjentsaring regnes det altsaring stort sett som selvstudium Dersom det er noe dere finner spesieltvanskelig saring ta kontakt

Vi forventer ogsaring at dere behersker grunnleggende programmering at dere har noeerfaring med rekursjon og grunnleggende strukturer som tabeller (arrays) og lenkedelister Dere vil faring noe repetisjon av dettelowast Se emnebeskrivelsen

httpsntnunostudieremnerTDT4120

iv

Gjennom semesteretDet foslashlgende er pensum knyttet til flere forelesninger gjennom semesteret

Lysark fra ordinaeligre forelesninger

Appendiks til dette dokumentet

Laeligringsmaringl for hver algoritme

[Z1] Kjenne den formelle definisjonen av det generelle problemet den loslashser[Z2] Kjenne til eventuelle tilleggskrav den stiller for aring vaeligre korrekt[Z3] Vite hvordan den oppfoslashrer seg kunne utfoslashre algoritmen trinn for trinn

[Z4] Forstaring korrekthetsbeviset hvordan og hvorfor virker algoritmen egentlig[Z5] Kjenne til eventuelle styrker eller svakheter sammenlignet med andre[Z6] Kjenne kjoslashretidene under ulike omstendigheter og forstaring utregningen

Laeligringsmaringl for hver datastruktur

[Z7] Forstaring algoritmene (jf maringl Z01ndashZ06) for de ulike operasjonene paring strukturen[Z8] Forstaring hvordan strukturen representeres i minnet

Laeligringsmaringl for hvert problem

[Z9] Kunne angi presist hva input er[Z10] Kunne angi presist hva output er og hvilke egenskaper det maring ha

Hva betyr laquoforstaringraquo

Gode laeligringsmaringl og laeligringsutbyttebeskrivelser formuleres gjerne som hva manskal vaeligre i stand til om man oppnaringr maringlet For enkhelhets skyld har jeg fleresteder brukt begrepet forstaring Dette kan du i praksis oversette til kunne forklare

I pensumheftet brukes en del norske begreper mens laeligreboka er paring engelskEn oversikt over oversettelser som brukes finner du paring nettsidenealgdatidintnunoordhtml

v

PensumoversiktDelkapitler er ogsaring listet opp under tilhoslashrende forelesning sammen med laeligringsmaringlKapittel- og oppgavereferanser er til Introduction to Algorithms av Cormen mfl [1]

Kap 1 The role of algorithms in computing

Kap 2 Getting started

Kap 3 Growth of functions Innledning og 31

Kap 4 Divide-and-conquer Innledning 41 og 43ndash45

Kap 6 Heapsort

Kap 7 Quicksort

Kap 8 Sorting in linear time

Kap 9 Medians and order statistics

Kap 10 Elementary data structures

Kap 11 Hash tables s 253ndash264

Kap 12 Binary search trees Innledning og 121ndash123

Kap 15 Dynamic programming Innledning og 151 153ndash154

Kap 16 Greedy algorithms Innledning og 161ndash163

Kap 17 Amortized analysis Innledning og s 463ndash465 (tom laquoat most 3raquo)

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Kap 23 Minimum spanning trees

Kap 24 Single-source shortest paths Innledning og 241ndash243

Kap 25 All-pairs shortest paths Innledning 252 og 253

Kap 26 Maximum flow Innledning og 261ndash263

Kap 34 NP-completeness

Oppgaver 23-5 45-3 162-2 og 341-4 med loslashsning

Appendiks AndashF i dette heftet

1

Forelesning 1

Problemer og algoritmer

Vi starter med fagfeltets grunnleggende byggesteiner og skisserer et rammeverk foraring tilegne seg resten av stoffet Spesielt viktig er ideen bak induksjon og rekursjonVi trenger bare se paring siste trinn og kan anta at resten er paring plass

Pensum

Kap 1 The role of algorithms in computing

Kap 2 Getting started Innledning 21ndash22

Kap 3 Growth of functions Innledning og 31

Laeligringsmaringl

[A1] Forstaring bokas pseudokode-konvensjoner[A2] Kjenne egenskapene til random-access machine-modellen (RAM)[A3] Kunne definere problem instans og problemstoslashrrelse

[A4] Kunne definere asymptotisk notasjon O Ω Θ o og ω [A5] Kunne definere best-case average-case og worst-case [A6] Forstaring loslashkkeinvarianter og induksjon [A7] Forstaring rekursiv dekomponering og induksjon over delinstanser

[A8] Forstaring Insertion-Sort

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

2

Forelesning 2

Datastrukturer

For aring unngaring grunnleggende kjoslashretidsfeller er det viktig aring kunne organisere og struk-turere data fornuftig Her skal vi se paring hvordan enkle strukturer kan implementeresi praksis og hva vi vinner paring aring bruke dem i algoritmene varingre

Pensum

Kap 10 Elementary data structures Innledning og 101ndash103

Kap 11 Hash tables s 253ndash264

Kap 17 Amortized analysis Innledning og s 463ndash465 (tom laquoat most 3raquo)

Laeligringsmaringl

[B1] Forstaring hvordan stakker og koslasher fungerer(Stack-Empty Push Pop Enqueue Dequeue)

[B2] Forstaring hvordan lenkede lister fungerer(List-Search List-Insert List-Delete List-Deleteprime List-Searchprime List-Insertprime)

[B3] Forstaring hvordan pekere og objekter kan implementeres [B4] Forstaring hvordan direkte adressering og hashtabeller fungerer

(Hash-Insert Hash-Search)

[B5] Forstaring konfliktloslashsing ved kjeding (chaining)(Chained-Hash-Insert Chained-Hash-Search Chained-Hash-Delete)

[B6] Kjenne til grunnleggende hashfunksjoner[B7] Vite at man for statiske datasett kan ha worst-case O(1) for soslashk[B8] Kunne definere amortisert analyse[B9] Forstaring hvordan dynamiske tabeller fungerer

(Table-Insert)

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

3

Forelesning 3

Splitt og hersk

Rekursiv dekomponering er kanskje den viktigste ideen i hele faget og designmeto-den splitt og hersk er en grunnleggende utgave av det Del instansen i mindre biterloslashs problemet rekursivt for disse og kombineacuter loslashsningene

Pensum

Kap 2 Getting started 23

Kap 4 Divide-and-conquer Innledning 41 og 43ndash45

Kap 7 Quicksort

Oppgaver 23-5 og 45-3 med loslashsning (binaeligrsoslashk)

Appendiks B og C i dette heftet

Laeligringsmaringl

[C1] Forstaring designmetoden divide-and-conquer (splitt og hersk)[C2] Forstaring maximum-subarray-problemet med loslashsninger[C3] Forstaring Bisect og Bisectprime (se appendiks C i dette heftet)[C4] Forstaring Merge-Sort[C5] Forstaring Quicksort og Randomized-Quicksort

[C6] Kunne loslashse rekurrenser med substitusjon rekursjonstraeligr og masterteoremet [C7] Kunne loslashse rekurrenser med iterasjonsmetoden (se appendiks B i dette heftet)

[C8] Forstaring hvordan variabelskifte fungerer

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

4

Forelesning 4

Rangering i lineaeligr tid

Vi kan ofte faring bedre loslashsninger ved aring styrke kravene til input eller ved aring svekkekravene til output Sortering basert paring sammenligninger (x 6 y) er et klassiskeksempel I verste tilfelle maring vi bruke lg n sammenligningermen om vi antar merom elementene eller bare sorterer noen av dem saring kan vi gjoslashre det bedre

Pensum

Kap 8 Sorting in linear time

Kap 9 Medians and order statistics

Laeligringsmaringl

[D1] Forstaring hvorfor sammenligningsbasert sortering har en worst-case paring Ω(n lg n)[D2] Vite hva en stabil sorteringsalgoritme er[D3] Forstaring Counting-Sort og hvorfor den er stabil

[D4] Forstaring Radix-Sort og hvorfor den trenger en stabil subrutine[D5] Forstaring Bucket-Sort[D6] Forstaring Randomized-Select[D7] Kjenne til Select

Merk Det kreves ikke grundig forstaringelse av virkemaringten til Select

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

5

Forelesning 5

Rotfaste trestrukturer

Rotfaste traeligr gjenspeiler rekursiv dekomponering I binaeligre soslashketraeligr er alt i venst-re deltre mindre enn rota mens alt i hoslashyre deltre er stoslashrre og det gjelder rekursivtfor alle deltraeligr Hauger er enklere Alt er mindre enn rota Det begrenser funksjo-naliteten men gjoslashr dem billigere aring bygge og balansere

Pensum

Kap 6 Heapsort

Kap 10 Elementary data structures 104

Kap 12 Binary search trees Innledning og 121ndash123

Laeligringsmaringl

[E1] Forstaring hvordan heaps fungerer og hvordan de kan brukes som prioritetskoslasher(Parent Left Right Max-Heapify Build-Max-Heap Heapsort Max-Heap-InsertHeap-Extract-Max Heap-Increase-Key Heap-Maximum Ogsaring tilsvarende for min-heaps feks Build-Min-Heap og Heap-Extract-Min)

[E2] Forstaring Heapsort[E3] Forstaring hvordan rotfaste traeligr kan implementeres

[E4] Forstaring hvordan binaeligre soslashketraeligr fungerer(Inorder-Tree-Walk Tree-Search Iterative-Tree-Search Tree-Minimum Tree-Maximum Tree-Successor Tree-Predecessor Tree-Insert Transplant Tree-Delete)

[E5] Vite at forventet hoslashyde for et tilfeldig binaeligrt soslashketre er Θ(lg n)[E6] Vite at det finnes soslashketraeligr med garantert hoslashyde paring Θ(lg n)

Merk Det kreves ikke grundig forstaringelse av Transplant og Tree-Delete

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

6

Forelesning 6

Dynamisk programmering

Paring sett og vis en generalisering av splitt og hersk der delprobler kan overlappe Istedet for et tre av delinstans-avhengigheter har vi en rettet asyklisk graf Vi finnerog lagrer del-loslashsninger i en rekkefoslashlge som stemmer med avhengighetene

Pensum

Kap 15 Dynamic programming Innledning og 151 153ndash154

Oppgave 162-2 med loslashsning (0-1 knapsack)

Appendiks D i dette heftet

Delkapitler 152 og 155 kan vaeligre nyttige som stoslashttelitteratur

Laeligringsmaringl

[F1] Forstaring ideen om en delinstansgraf [F2] Forstaring designmetoden dynamisk programmering [F3] Forstaring loslashsning ved memoisering (top-down)

[F4] Forstaring loslashsning ved iterasjon (bottom-up)[F5] Forstaring hvordan man rekonstruerer en loslashsning fra lagrede beslutninger[F6] Forstaring hva optimal delstruktur er[F7] Forstaring hva overlappende delinstanser er[F8] Forstaring eksemplene stavkutting og LCS[F9] Forstaring loslashsningen paring det binaeligre ryggsekkproblemet (se appendiks D i dette

heftet)(Knapsack Knapsackprime)

Merk Noe av stoffet vil kanskje forskyves til forelesning 7

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

7

Forelesning 7

Graringdige algoritmer

Graringdige algoritmer bestaringr av en serie med valg og hvert valg tas lokalt Algorit-men gjoslashr alltid det som ser best ut her og naring uten noe stoslashrre perspektiv Slikealgoritmer er ofte enkle utfordringen ligger i aring finne ut om de gir rett svar

Pensum

Kap 16 Greedy algorithms Innledning og 161ndash163

Laeligringsmaringl

[G1] Forstaring designmetoden graringdighet [G2] Forstaring graringdighetsegenskapen (the greedy-choice property)

[G3] Forstaring eksemplene aktivitet-utvelgelse og det kontinuerlige ryggsekkproblemet[G4] Forstaring Huffman og Huffman-koder

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

8

Forelesning 8

Traversering av grafer

Vi traverserer en graf ved aring besoslashke noder vi vet om Vi vet i utgangspunktet bareom startnoden men oppdager naboene til dem vi besoslashker Traversering er viktig iseg selv men danner ogsaring ryggraden til flere mer avanserte algoritmer

Pensum

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Appendiks E i dette heftet

Laeligringsmaringl

[H1] Forstaring hvordan grafer kan implementeres[H2] Forstaring BFS ogsaring for aring finne korteste vei uten vekter[H3] Forstaring DFS og parentesteoremet[H4] Forstaring hvordan DFS klassifiserer kanter[H5] Forstaring Topological-Sort[H6] Forstaring hvordan DFS kan implementeres med en stakk[H7] Forstaring hva traverseringstraeligr (som bredde-foslashrst- og dybde-foslashrst-traeligr) er

[H8] Forstaring traversering med vilkaringrlig prioritetskoslash

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

9

Forelesning 9

Minimale spenntraeligr

Her har vi en graf med vekter paring kantene og oslashnsker aring bare beholde akkurat dekantene vi maring for aring koble sammen alle nodene med en saring lav vektsum som muligErke-eksempel paring graringdighet Velg eacuten og eacuten kant alltid den billigste lovlige

Pensum

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 23 Minimum spanning trees

Laeligringsmaringl

[I1] Forstaring skog-implementasjonen av disjunkte mengder(Connected-Components Same-Component Make-Set Union Link Find-Set)

[I2] Vite hva spenntraeligr og minimale spenntraeligr er [I3] Forstaring Generic-MST

[I4] Forstaring hvorfor lette kanter er trygge kanter[I5] Forstaring MST-Kruskal[I6] Forstaring MST-Prim

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

10

Forelesning 10

Korteste vei fra eacuten til alle

Bredde-foslashrst-soslashk kan finne stier med faeligrrest mulig kanter men hva om kantenehar ulik lengde Det generelle problemet er uloslashst men vi kan loslashse problemet medgradvis bedre kjoslashretid for grafer (1) uten negative sykler (2) uten negative kanterog (3) uten sykler Og vi bruker samme prinsipp for alle tre

Pensum

Kap 24 Single-source shortest paths Innledning og 241ndash243

Laeligringsmaringl

[J1] Forstaring ulike varianter av korteste-vei- eller korteste-sti-problemet(Single-source single-destination single-pair all-pairs)

[J2] Forstaring strukturen til korteste-vei-problemet[J3] Forstaring at negative sykler gir mening for korteste enkle vei (simple path)[J4] Forstaring at korteste enkle vei kan loslashses vha lengste enkle vei og omvendt[J5] Forstaring hvordan man kan representere et korteste-vei-tre

[J6] Forstaring kant-slakking (edge relaxation) og Relax[J7] Forstaring ulike egenskaper ved korteste veier og slakking

(Triangle inequality upper-bound property no-path property convergence property path-relaxation property predecessor-subgraph property)

[J8] Forstaring Bellman-Ford[J9] Forstaring DAG-Shortest-Path

[J10] Forstaring kobling mellom DAG-Shortest-Path og dynamisk programmering[J11] Forstaring Dijkstra

Merk Noe av stoffet vil kanskje forskyves til forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

11

Forelesning 11

Korteste vei fra alle til alle

Vi kan finne de korteste veiene fra hver node etter tur men mange av delinstanse-ne vil overlappe ndash om vi har mange nok kanter loslashnner det seg aring bruke dynamiskprogrammering med dekomponeringen laquoSkal vi innom k eller ikkeraquo

Pensum

Kap 25 All-pairs shortest paths Innledning 252 og 253

Laeligringsmaringl

[K1] Forstaring forgjengerstrukturen for alle-til-alle-varianten av korteste vei-problemet(Print-All-Pairs-Shortest-Path)

[K2] Forstaring Floyd-Warshall[K3] Forstaring Transitive-Closure[K4] Forstaring Johnson

Merk Noe stoff fra forelesning 12 vil kanskje dekkes her

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

12

Forelesning 12

Maksimal flyt

Et stort skritt i retning av generell lineaeligr optimering (saringkalt lineaeligr programme-ring) Her ser vi paring to tilsynelatende forskjellige problemer som viser seg aring vaeligreduale av hverandre noe som hjelper oss med aring finne en loslashsning

Pensum

Kap 26 Maximum flow Innledning og 261ndash263

Laeligringsmaringl

[L1] Kunne definere flytnett flyt og maks-flyt-problemet[L2] Kunne haringndtere antiparallelle kanter og flere kilder og sluk

[L3] Kunne definere restnettet til et flytnett med en gitt flyt[L4] Forstaring hvordan man kan oppheve (cancel) flyt[L5] Forstaring hva en foroslashkende sti (augmenting path) er[L6] Forstaring hva snitt snitt-kapasitet og minimalt snitt er

[L7] Forstaring maks-flytmin-snitt-teoremet[L8] Forstaring Ford-Fulkerson-Method og Ford-Fulkerson[L9] Vite at Ford-Fulkerson med BFS kalles Edmonds-Karp-algoritmen[L10] Forstaring hvordan maks-flyt kan finne en maksimum bipartitt matching

[L11] Forstaring heltallsteoremet (integrality theorem)

Merk Noe av stoffet vil kanskje dekkes i forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

13

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 5: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

presisjon saring finnes det generelle raringd og tips rundt dette En bok jeg har anbefaltflere og faringtt gode tilbakemeldinger paring er denne

Bokanbefaling

A mind for numbers av Barbara Oakley [2] Naeligrt knyttet til boka er Coursera-kurset Learning how to learn Powerful tools to help you master tough subjects

I de foslashlgende lister med laeligringsmaringl er noen merket med utropstegn Dette er enganske uformell greie men er ment aring indikere temaer som kanskje er viktigere ennman skulle tro Av og til betyr det de merkede maringlene er viktigere enn de andremen iblant ndash for mer marginale ting ndash saring er det mer av typen laquoObs Dette boslashr duikke nedprioritereraquo Men som sagt det er ganske uformelt og ikke noe du boslashr leggealtfor stor vekt paring

Overordnede laeligringsmaringl

De overordnede laeligringsmaringlene for faget er som foslashlgerlowast

Dere skal ha kunnskap om

[X1] Et bredt spekter av etablerte algoritmer og datastrukturer[X2] Klassiske algoritmiske problemer med kjente effektive loslashsninger[X3] Komplekse problemer uten kjente effektive loslashsninger

Dere skal kunne

[X4] Analysere algoritmers korrekthet og effektivitet[X5] Formulere problemer saring de kan loslashses av algoritmer

[X6] Konstruere nye effektive algoritmer

Dere skal vaeligre i stand til

[X7] Aring bruke eksisterende algoritmer og programvare paring nye problemer[X8] Aring utvikle nye loslashsninger paring praktiske algoritmiske problemstillinger

Mer spesifikke laeligringsmaringl er oppgitt for hver forelesning

Punkter nedenfor merket med er pensum Kapittelreferanser er til pensumbokaIntroduction to Algorithms [1]

lowast Se emnebeskrivelsenhttpsntnunostudieremnerTDT4120

iii

ForkunnskaperEn viss bakgrunn er noslashdvendig for aring faring fullt utbytte av faget som beskrevet i fagetsanbefalte forkunnskaperlowast Mye av dette kan man tilegne seg paring egen haringnd om manikke har hatt relevante fag men det kan da vaeligre lurt aring gjoslashre det saring tidlig som muligi semesteretDere boslashr

[Y1] Kjenne til begreper rundt monotone funksjoner[Y2] Kjenne til notasjonene dxe bxc n og a mod n

[Y3] Vite hva polynomer er[Y4] Kjenne grunnleggende potensregning[Y5] Ha noe kunnskap om grenseverdier

[Y6] Vaeligre godt kjent med logaritmer med ulike grunntall[Y7] Kjenne enkel sannsynlighetsregning indikatorvariable og forventning[Y8] Ha noe kjennskap til rekkesummer (se ogsaring side 15 i dette heftet)[Y9] Beherske helt grunnleggende mengdelaeligre[Y10] Kjenne grunnleggende terminologi for relasjoner ordninger og funksjoner[Y11] Kjenne grunnleggende terminologi for og egenskaper ved grafer og traeligr[Y12] Kjenne til enkel kombinatorikk som permutasjoner og kombinasjoner

De foslashlgende punktene er ment aring dekke de anbefalte forkunnskapene De er pensummen antas i hovedsak kjent (bortsett fra bruken av asymptotisk notasjon) Devil derfor i liten grad dekkes av forelesningene De er ogsaring i hovedsak ment sombakgrunnsstoff til hjelp for aring tilegne seg resten av stoffet og vil dermed i mindregrad bli spurt om direkte paring eksamen

Kap 3 Growth of functions 32

Kap 5 Probabilistic analysis s 118ndash120

App A Summations s 1145ndash1146 og ligning (A5)

App B Sets etc

App C Counting and probability s 1183ndash1185 C2 og s 1196ndash1198

Vi vil generelt proslashve aring friske opp relevant kunnskap men om dette stoffet er ukjentsaring regnes det altsaring stort sett som selvstudium Dersom det er noe dere finner spesieltvanskelig saring ta kontakt

Vi forventer ogsaring at dere behersker grunnleggende programmering at dere har noeerfaring med rekursjon og grunnleggende strukturer som tabeller (arrays) og lenkedelister Dere vil faring noe repetisjon av dettelowast Se emnebeskrivelsen

httpsntnunostudieremnerTDT4120

iv

Gjennom semesteretDet foslashlgende er pensum knyttet til flere forelesninger gjennom semesteret

Lysark fra ordinaeligre forelesninger

Appendiks til dette dokumentet

Laeligringsmaringl for hver algoritme

[Z1] Kjenne den formelle definisjonen av det generelle problemet den loslashser[Z2] Kjenne til eventuelle tilleggskrav den stiller for aring vaeligre korrekt[Z3] Vite hvordan den oppfoslashrer seg kunne utfoslashre algoritmen trinn for trinn

[Z4] Forstaring korrekthetsbeviset hvordan og hvorfor virker algoritmen egentlig[Z5] Kjenne til eventuelle styrker eller svakheter sammenlignet med andre[Z6] Kjenne kjoslashretidene under ulike omstendigheter og forstaring utregningen

Laeligringsmaringl for hver datastruktur

[Z7] Forstaring algoritmene (jf maringl Z01ndashZ06) for de ulike operasjonene paring strukturen[Z8] Forstaring hvordan strukturen representeres i minnet

Laeligringsmaringl for hvert problem

[Z9] Kunne angi presist hva input er[Z10] Kunne angi presist hva output er og hvilke egenskaper det maring ha

Hva betyr laquoforstaringraquo

Gode laeligringsmaringl og laeligringsutbyttebeskrivelser formuleres gjerne som hva manskal vaeligre i stand til om man oppnaringr maringlet For enkhelhets skyld har jeg fleresteder brukt begrepet forstaring Dette kan du i praksis oversette til kunne forklare

I pensumheftet brukes en del norske begreper mens laeligreboka er paring engelskEn oversikt over oversettelser som brukes finner du paring nettsidenealgdatidintnunoordhtml

v

PensumoversiktDelkapitler er ogsaring listet opp under tilhoslashrende forelesning sammen med laeligringsmaringlKapittel- og oppgavereferanser er til Introduction to Algorithms av Cormen mfl [1]

Kap 1 The role of algorithms in computing

Kap 2 Getting started

Kap 3 Growth of functions Innledning og 31

Kap 4 Divide-and-conquer Innledning 41 og 43ndash45

Kap 6 Heapsort

Kap 7 Quicksort

Kap 8 Sorting in linear time

Kap 9 Medians and order statistics

Kap 10 Elementary data structures

Kap 11 Hash tables s 253ndash264

Kap 12 Binary search trees Innledning og 121ndash123

Kap 15 Dynamic programming Innledning og 151 153ndash154

Kap 16 Greedy algorithms Innledning og 161ndash163

Kap 17 Amortized analysis Innledning og s 463ndash465 (tom laquoat most 3raquo)

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Kap 23 Minimum spanning trees

Kap 24 Single-source shortest paths Innledning og 241ndash243

Kap 25 All-pairs shortest paths Innledning 252 og 253

Kap 26 Maximum flow Innledning og 261ndash263

Kap 34 NP-completeness

Oppgaver 23-5 45-3 162-2 og 341-4 med loslashsning

Appendiks AndashF i dette heftet

1

Forelesning 1

Problemer og algoritmer

Vi starter med fagfeltets grunnleggende byggesteiner og skisserer et rammeverk foraring tilegne seg resten av stoffet Spesielt viktig er ideen bak induksjon og rekursjonVi trenger bare se paring siste trinn og kan anta at resten er paring plass

Pensum

Kap 1 The role of algorithms in computing

Kap 2 Getting started Innledning 21ndash22

Kap 3 Growth of functions Innledning og 31

Laeligringsmaringl

[A1] Forstaring bokas pseudokode-konvensjoner[A2] Kjenne egenskapene til random-access machine-modellen (RAM)[A3] Kunne definere problem instans og problemstoslashrrelse

[A4] Kunne definere asymptotisk notasjon O Ω Θ o og ω [A5] Kunne definere best-case average-case og worst-case [A6] Forstaring loslashkkeinvarianter og induksjon [A7] Forstaring rekursiv dekomponering og induksjon over delinstanser

[A8] Forstaring Insertion-Sort

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

2

Forelesning 2

Datastrukturer

For aring unngaring grunnleggende kjoslashretidsfeller er det viktig aring kunne organisere og struk-turere data fornuftig Her skal vi se paring hvordan enkle strukturer kan implementeresi praksis og hva vi vinner paring aring bruke dem i algoritmene varingre

Pensum

Kap 10 Elementary data structures Innledning og 101ndash103

Kap 11 Hash tables s 253ndash264

Kap 17 Amortized analysis Innledning og s 463ndash465 (tom laquoat most 3raquo)

Laeligringsmaringl

[B1] Forstaring hvordan stakker og koslasher fungerer(Stack-Empty Push Pop Enqueue Dequeue)

[B2] Forstaring hvordan lenkede lister fungerer(List-Search List-Insert List-Delete List-Deleteprime List-Searchprime List-Insertprime)

[B3] Forstaring hvordan pekere og objekter kan implementeres [B4] Forstaring hvordan direkte adressering og hashtabeller fungerer

(Hash-Insert Hash-Search)

[B5] Forstaring konfliktloslashsing ved kjeding (chaining)(Chained-Hash-Insert Chained-Hash-Search Chained-Hash-Delete)

[B6] Kjenne til grunnleggende hashfunksjoner[B7] Vite at man for statiske datasett kan ha worst-case O(1) for soslashk[B8] Kunne definere amortisert analyse[B9] Forstaring hvordan dynamiske tabeller fungerer

(Table-Insert)

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

3

Forelesning 3

Splitt og hersk

Rekursiv dekomponering er kanskje den viktigste ideen i hele faget og designmeto-den splitt og hersk er en grunnleggende utgave av det Del instansen i mindre biterloslashs problemet rekursivt for disse og kombineacuter loslashsningene

Pensum

Kap 2 Getting started 23

Kap 4 Divide-and-conquer Innledning 41 og 43ndash45

Kap 7 Quicksort

Oppgaver 23-5 og 45-3 med loslashsning (binaeligrsoslashk)

Appendiks B og C i dette heftet

Laeligringsmaringl

[C1] Forstaring designmetoden divide-and-conquer (splitt og hersk)[C2] Forstaring maximum-subarray-problemet med loslashsninger[C3] Forstaring Bisect og Bisectprime (se appendiks C i dette heftet)[C4] Forstaring Merge-Sort[C5] Forstaring Quicksort og Randomized-Quicksort

[C6] Kunne loslashse rekurrenser med substitusjon rekursjonstraeligr og masterteoremet [C7] Kunne loslashse rekurrenser med iterasjonsmetoden (se appendiks B i dette heftet)

[C8] Forstaring hvordan variabelskifte fungerer

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

4

Forelesning 4

Rangering i lineaeligr tid

Vi kan ofte faring bedre loslashsninger ved aring styrke kravene til input eller ved aring svekkekravene til output Sortering basert paring sammenligninger (x 6 y) er et klassiskeksempel I verste tilfelle maring vi bruke lg n sammenligningermen om vi antar merom elementene eller bare sorterer noen av dem saring kan vi gjoslashre det bedre

Pensum

Kap 8 Sorting in linear time

Kap 9 Medians and order statistics

Laeligringsmaringl

[D1] Forstaring hvorfor sammenligningsbasert sortering har en worst-case paring Ω(n lg n)[D2] Vite hva en stabil sorteringsalgoritme er[D3] Forstaring Counting-Sort og hvorfor den er stabil

[D4] Forstaring Radix-Sort og hvorfor den trenger en stabil subrutine[D5] Forstaring Bucket-Sort[D6] Forstaring Randomized-Select[D7] Kjenne til Select

Merk Det kreves ikke grundig forstaringelse av virkemaringten til Select

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

5

Forelesning 5

Rotfaste trestrukturer

Rotfaste traeligr gjenspeiler rekursiv dekomponering I binaeligre soslashketraeligr er alt i venst-re deltre mindre enn rota mens alt i hoslashyre deltre er stoslashrre og det gjelder rekursivtfor alle deltraeligr Hauger er enklere Alt er mindre enn rota Det begrenser funksjo-naliteten men gjoslashr dem billigere aring bygge og balansere

Pensum

Kap 6 Heapsort

Kap 10 Elementary data structures 104

Kap 12 Binary search trees Innledning og 121ndash123

Laeligringsmaringl

[E1] Forstaring hvordan heaps fungerer og hvordan de kan brukes som prioritetskoslasher(Parent Left Right Max-Heapify Build-Max-Heap Heapsort Max-Heap-InsertHeap-Extract-Max Heap-Increase-Key Heap-Maximum Ogsaring tilsvarende for min-heaps feks Build-Min-Heap og Heap-Extract-Min)

[E2] Forstaring Heapsort[E3] Forstaring hvordan rotfaste traeligr kan implementeres

[E4] Forstaring hvordan binaeligre soslashketraeligr fungerer(Inorder-Tree-Walk Tree-Search Iterative-Tree-Search Tree-Minimum Tree-Maximum Tree-Successor Tree-Predecessor Tree-Insert Transplant Tree-Delete)

[E5] Vite at forventet hoslashyde for et tilfeldig binaeligrt soslashketre er Θ(lg n)[E6] Vite at det finnes soslashketraeligr med garantert hoslashyde paring Θ(lg n)

Merk Det kreves ikke grundig forstaringelse av Transplant og Tree-Delete

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

6

Forelesning 6

Dynamisk programmering

Paring sett og vis en generalisering av splitt og hersk der delprobler kan overlappe Istedet for et tre av delinstans-avhengigheter har vi en rettet asyklisk graf Vi finnerog lagrer del-loslashsninger i en rekkefoslashlge som stemmer med avhengighetene

Pensum

Kap 15 Dynamic programming Innledning og 151 153ndash154

Oppgave 162-2 med loslashsning (0-1 knapsack)

Appendiks D i dette heftet

Delkapitler 152 og 155 kan vaeligre nyttige som stoslashttelitteratur

Laeligringsmaringl

[F1] Forstaring ideen om en delinstansgraf [F2] Forstaring designmetoden dynamisk programmering [F3] Forstaring loslashsning ved memoisering (top-down)

[F4] Forstaring loslashsning ved iterasjon (bottom-up)[F5] Forstaring hvordan man rekonstruerer en loslashsning fra lagrede beslutninger[F6] Forstaring hva optimal delstruktur er[F7] Forstaring hva overlappende delinstanser er[F8] Forstaring eksemplene stavkutting og LCS[F9] Forstaring loslashsningen paring det binaeligre ryggsekkproblemet (se appendiks D i dette

heftet)(Knapsack Knapsackprime)

Merk Noe av stoffet vil kanskje forskyves til forelesning 7

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

7

Forelesning 7

Graringdige algoritmer

Graringdige algoritmer bestaringr av en serie med valg og hvert valg tas lokalt Algorit-men gjoslashr alltid det som ser best ut her og naring uten noe stoslashrre perspektiv Slikealgoritmer er ofte enkle utfordringen ligger i aring finne ut om de gir rett svar

Pensum

Kap 16 Greedy algorithms Innledning og 161ndash163

Laeligringsmaringl

[G1] Forstaring designmetoden graringdighet [G2] Forstaring graringdighetsegenskapen (the greedy-choice property)

[G3] Forstaring eksemplene aktivitet-utvelgelse og det kontinuerlige ryggsekkproblemet[G4] Forstaring Huffman og Huffman-koder

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

8

Forelesning 8

Traversering av grafer

Vi traverserer en graf ved aring besoslashke noder vi vet om Vi vet i utgangspunktet bareom startnoden men oppdager naboene til dem vi besoslashker Traversering er viktig iseg selv men danner ogsaring ryggraden til flere mer avanserte algoritmer

Pensum

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Appendiks E i dette heftet

Laeligringsmaringl

[H1] Forstaring hvordan grafer kan implementeres[H2] Forstaring BFS ogsaring for aring finne korteste vei uten vekter[H3] Forstaring DFS og parentesteoremet[H4] Forstaring hvordan DFS klassifiserer kanter[H5] Forstaring Topological-Sort[H6] Forstaring hvordan DFS kan implementeres med en stakk[H7] Forstaring hva traverseringstraeligr (som bredde-foslashrst- og dybde-foslashrst-traeligr) er

[H8] Forstaring traversering med vilkaringrlig prioritetskoslash

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

9

Forelesning 9

Minimale spenntraeligr

Her har vi en graf med vekter paring kantene og oslashnsker aring bare beholde akkurat dekantene vi maring for aring koble sammen alle nodene med en saring lav vektsum som muligErke-eksempel paring graringdighet Velg eacuten og eacuten kant alltid den billigste lovlige

Pensum

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 23 Minimum spanning trees

Laeligringsmaringl

[I1] Forstaring skog-implementasjonen av disjunkte mengder(Connected-Components Same-Component Make-Set Union Link Find-Set)

[I2] Vite hva spenntraeligr og minimale spenntraeligr er [I3] Forstaring Generic-MST

[I4] Forstaring hvorfor lette kanter er trygge kanter[I5] Forstaring MST-Kruskal[I6] Forstaring MST-Prim

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

10

Forelesning 10

Korteste vei fra eacuten til alle

Bredde-foslashrst-soslashk kan finne stier med faeligrrest mulig kanter men hva om kantenehar ulik lengde Det generelle problemet er uloslashst men vi kan loslashse problemet medgradvis bedre kjoslashretid for grafer (1) uten negative sykler (2) uten negative kanterog (3) uten sykler Og vi bruker samme prinsipp for alle tre

Pensum

Kap 24 Single-source shortest paths Innledning og 241ndash243

Laeligringsmaringl

[J1] Forstaring ulike varianter av korteste-vei- eller korteste-sti-problemet(Single-source single-destination single-pair all-pairs)

[J2] Forstaring strukturen til korteste-vei-problemet[J3] Forstaring at negative sykler gir mening for korteste enkle vei (simple path)[J4] Forstaring at korteste enkle vei kan loslashses vha lengste enkle vei og omvendt[J5] Forstaring hvordan man kan representere et korteste-vei-tre

[J6] Forstaring kant-slakking (edge relaxation) og Relax[J7] Forstaring ulike egenskaper ved korteste veier og slakking

(Triangle inequality upper-bound property no-path property convergence property path-relaxation property predecessor-subgraph property)

[J8] Forstaring Bellman-Ford[J9] Forstaring DAG-Shortest-Path

[J10] Forstaring kobling mellom DAG-Shortest-Path og dynamisk programmering[J11] Forstaring Dijkstra

Merk Noe av stoffet vil kanskje forskyves til forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

11

Forelesning 11

Korteste vei fra alle til alle

Vi kan finne de korteste veiene fra hver node etter tur men mange av delinstanse-ne vil overlappe ndash om vi har mange nok kanter loslashnner det seg aring bruke dynamiskprogrammering med dekomponeringen laquoSkal vi innom k eller ikkeraquo

Pensum

Kap 25 All-pairs shortest paths Innledning 252 og 253

Laeligringsmaringl

[K1] Forstaring forgjengerstrukturen for alle-til-alle-varianten av korteste vei-problemet(Print-All-Pairs-Shortest-Path)

[K2] Forstaring Floyd-Warshall[K3] Forstaring Transitive-Closure[K4] Forstaring Johnson

Merk Noe stoff fra forelesning 12 vil kanskje dekkes her

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

12

Forelesning 12

Maksimal flyt

Et stort skritt i retning av generell lineaeligr optimering (saringkalt lineaeligr programme-ring) Her ser vi paring to tilsynelatende forskjellige problemer som viser seg aring vaeligreduale av hverandre noe som hjelper oss med aring finne en loslashsning

Pensum

Kap 26 Maximum flow Innledning og 261ndash263

Laeligringsmaringl

[L1] Kunne definere flytnett flyt og maks-flyt-problemet[L2] Kunne haringndtere antiparallelle kanter og flere kilder og sluk

[L3] Kunne definere restnettet til et flytnett med en gitt flyt[L4] Forstaring hvordan man kan oppheve (cancel) flyt[L5] Forstaring hva en foroslashkende sti (augmenting path) er[L6] Forstaring hva snitt snitt-kapasitet og minimalt snitt er

[L7] Forstaring maks-flytmin-snitt-teoremet[L8] Forstaring Ford-Fulkerson-Method og Ford-Fulkerson[L9] Vite at Ford-Fulkerson med BFS kalles Edmonds-Karp-algoritmen[L10] Forstaring hvordan maks-flyt kan finne en maksimum bipartitt matching

[L11] Forstaring heltallsteoremet (integrality theorem)

Merk Noe av stoffet vil kanskje dekkes i forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

13

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 6: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

ForkunnskaperEn viss bakgrunn er noslashdvendig for aring faring fullt utbytte av faget som beskrevet i fagetsanbefalte forkunnskaperlowast Mye av dette kan man tilegne seg paring egen haringnd om manikke har hatt relevante fag men det kan da vaeligre lurt aring gjoslashre det saring tidlig som muligi semesteretDere boslashr

[Y1] Kjenne til begreper rundt monotone funksjoner[Y2] Kjenne til notasjonene dxe bxc n og a mod n

[Y3] Vite hva polynomer er[Y4] Kjenne grunnleggende potensregning[Y5] Ha noe kunnskap om grenseverdier

[Y6] Vaeligre godt kjent med logaritmer med ulike grunntall[Y7] Kjenne enkel sannsynlighetsregning indikatorvariable og forventning[Y8] Ha noe kjennskap til rekkesummer (se ogsaring side 15 i dette heftet)[Y9] Beherske helt grunnleggende mengdelaeligre[Y10] Kjenne grunnleggende terminologi for relasjoner ordninger og funksjoner[Y11] Kjenne grunnleggende terminologi for og egenskaper ved grafer og traeligr[Y12] Kjenne til enkel kombinatorikk som permutasjoner og kombinasjoner

De foslashlgende punktene er ment aring dekke de anbefalte forkunnskapene De er pensummen antas i hovedsak kjent (bortsett fra bruken av asymptotisk notasjon) Devil derfor i liten grad dekkes av forelesningene De er ogsaring i hovedsak ment sombakgrunnsstoff til hjelp for aring tilegne seg resten av stoffet og vil dermed i mindregrad bli spurt om direkte paring eksamen

Kap 3 Growth of functions 32

Kap 5 Probabilistic analysis s 118ndash120

App A Summations s 1145ndash1146 og ligning (A5)

App B Sets etc

App C Counting and probability s 1183ndash1185 C2 og s 1196ndash1198

Vi vil generelt proslashve aring friske opp relevant kunnskap men om dette stoffet er ukjentsaring regnes det altsaring stort sett som selvstudium Dersom det er noe dere finner spesieltvanskelig saring ta kontakt

Vi forventer ogsaring at dere behersker grunnleggende programmering at dere har noeerfaring med rekursjon og grunnleggende strukturer som tabeller (arrays) og lenkedelister Dere vil faring noe repetisjon av dettelowast Se emnebeskrivelsen

httpsntnunostudieremnerTDT4120

iv

Gjennom semesteretDet foslashlgende er pensum knyttet til flere forelesninger gjennom semesteret

Lysark fra ordinaeligre forelesninger

Appendiks til dette dokumentet

Laeligringsmaringl for hver algoritme

[Z1] Kjenne den formelle definisjonen av det generelle problemet den loslashser[Z2] Kjenne til eventuelle tilleggskrav den stiller for aring vaeligre korrekt[Z3] Vite hvordan den oppfoslashrer seg kunne utfoslashre algoritmen trinn for trinn

[Z4] Forstaring korrekthetsbeviset hvordan og hvorfor virker algoritmen egentlig[Z5] Kjenne til eventuelle styrker eller svakheter sammenlignet med andre[Z6] Kjenne kjoslashretidene under ulike omstendigheter og forstaring utregningen

Laeligringsmaringl for hver datastruktur

[Z7] Forstaring algoritmene (jf maringl Z01ndashZ06) for de ulike operasjonene paring strukturen[Z8] Forstaring hvordan strukturen representeres i minnet

Laeligringsmaringl for hvert problem

[Z9] Kunne angi presist hva input er[Z10] Kunne angi presist hva output er og hvilke egenskaper det maring ha

Hva betyr laquoforstaringraquo

Gode laeligringsmaringl og laeligringsutbyttebeskrivelser formuleres gjerne som hva manskal vaeligre i stand til om man oppnaringr maringlet For enkhelhets skyld har jeg fleresteder brukt begrepet forstaring Dette kan du i praksis oversette til kunne forklare

I pensumheftet brukes en del norske begreper mens laeligreboka er paring engelskEn oversikt over oversettelser som brukes finner du paring nettsidenealgdatidintnunoordhtml

v

PensumoversiktDelkapitler er ogsaring listet opp under tilhoslashrende forelesning sammen med laeligringsmaringlKapittel- og oppgavereferanser er til Introduction to Algorithms av Cormen mfl [1]

Kap 1 The role of algorithms in computing

Kap 2 Getting started

Kap 3 Growth of functions Innledning og 31

Kap 4 Divide-and-conquer Innledning 41 og 43ndash45

Kap 6 Heapsort

Kap 7 Quicksort

Kap 8 Sorting in linear time

Kap 9 Medians and order statistics

Kap 10 Elementary data structures

Kap 11 Hash tables s 253ndash264

Kap 12 Binary search trees Innledning og 121ndash123

Kap 15 Dynamic programming Innledning og 151 153ndash154

Kap 16 Greedy algorithms Innledning og 161ndash163

Kap 17 Amortized analysis Innledning og s 463ndash465 (tom laquoat most 3raquo)

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Kap 23 Minimum spanning trees

Kap 24 Single-source shortest paths Innledning og 241ndash243

Kap 25 All-pairs shortest paths Innledning 252 og 253

Kap 26 Maximum flow Innledning og 261ndash263

Kap 34 NP-completeness

Oppgaver 23-5 45-3 162-2 og 341-4 med loslashsning

Appendiks AndashF i dette heftet

1

Forelesning 1

Problemer og algoritmer

Vi starter med fagfeltets grunnleggende byggesteiner og skisserer et rammeverk foraring tilegne seg resten av stoffet Spesielt viktig er ideen bak induksjon og rekursjonVi trenger bare se paring siste trinn og kan anta at resten er paring plass

Pensum

Kap 1 The role of algorithms in computing

Kap 2 Getting started Innledning 21ndash22

Kap 3 Growth of functions Innledning og 31

Laeligringsmaringl

[A1] Forstaring bokas pseudokode-konvensjoner[A2] Kjenne egenskapene til random-access machine-modellen (RAM)[A3] Kunne definere problem instans og problemstoslashrrelse

[A4] Kunne definere asymptotisk notasjon O Ω Θ o og ω [A5] Kunne definere best-case average-case og worst-case [A6] Forstaring loslashkkeinvarianter og induksjon [A7] Forstaring rekursiv dekomponering og induksjon over delinstanser

[A8] Forstaring Insertion-Sort

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

2

Forelesning 2

Datastrukturer

For aring unngaring grunnleggende kjoslashretidsfeller er det viktig aring kunne organisere og struk-turere data fornuftig Her skal vi se paring hvordan enkle strukturer kan implementeresi praksis og hva vi vinner paring aring bruke dem i algoritmene varingre

Pensum

Kap 10 Elementary data structures Innledning og 101ndash103

Kap 11 Hash tables s 253ndash264

Kap 17 Amortized analysis Innledning og s 463ndash465 (tom laquoat most 3raquo)

Laeligringsmaringl

[B1] Forstaring hvordan stakker og koslasher fungerer(Stack-Empty Push Pop Enqueue Dequeue)

[B2] Forstaring hvordan lenkede lister fungerer(List-Search List-Insert List-Delete List-Deleteprime List-Searchprime List-Insertprime)

[B3] Forstaring hvordan pekere og objekter kan implementeres [B4] Forstaring hvordan direkte adressering og hashtabeller fungerer

(Hash-Insert Hash-Search)

[B5] Forstaring konfliktloslashsing ved kjeding (chaining)(Chained-Hash-Insert Chained-Hash-Search Chained-Hash-Delete)

[B6] Kjenne til grunnleggende hashfunksjoner[B7] Vite at man for statiske datasett kan ha worst-case O(1) for soslashk[B8] Kunne definere amortisert analyse[B9] Forstaring hvordan dynamiske tabeller fungerer

(Table-Insert)

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

3

Forelesning 3

Splitt og hersk

Rekursiv dekomponering er kanskje den viktigste ideen i hele faget og designmeto-den splitt og hersk er en grunnleggende utgave av det Del instansen i mindre biterloslashs problemet rekursivt for disse og kombineacuter loslashsningene

Pensum

Kap 2 Getting started 23

Kap 4 Divide-and-conquer Innledning 41 og 43ndash45

Kap 7 Quicksort

Oppgaver 23-5 og 45-3 med loslashsning (binaeligrsoslashk)

Appendiks B og C i dette heftet

Laeligringsmaringl

[C1] Forstaring designmetoden divide-and-conquer (splitt og hersk)[C2] Forstaring maximum-subarray-problemet med loslashsninger[C3] Forstaring Bisect og Bisectprime (se appendiks C i dette heftet)[C4] Forstaring Merge-Sort[C5] Forstaring Quicksort og Randomized-Quicksort

[C6] Kunne loslashse rekurrenser med substitusjon rekursjonstraeligr og masterteoremet [C7] Kunne loslashse rekurrenser med iterasjonsmetoden (se appendiks B i dette heftet)

[C8] Forstaring hvordan variabelskifte fungerer

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

4

Forelesning 4

Rangering i lineaeligr tid

Vi kan ofte faring bedre loslashsninger ved aring styrke kravene til input eller ved aring svekkekravene til output Sortering basert paring sammenligninger (x 6 y) er et klassiskeksempel I verste tilfelle maring vi bruke lg n sammenligningermen om vi antar merom elementene eller bare sorterer noen av dem saring kan vi gjoslashre det bedre

Pensum

Kap 8 Sorting in linear time

Kap 9 Medians and order statistics

Laeligringsmaringl

[D1] Forstaring hvorfor sammenligningsbasert sortering har en worst-case paring Ω(n lg n)[D2] Vite hva en stabil sorteringsalgoritme er[D3] Forstaring Counting-Sort og hvorfor den er stabil

[D4] Forstaring Radix-Sort og hvorfor den trenger en stabil subrutine[D5] Forstaring Bucket-Sort[D6] Forstaring Randomized-Select[D7] Kjenne til Select

Merk Det kreves ikke grundig forstaringelse av virkemaringten til Select

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

5

Forelesning 5

Rotfaste trestrukturer

Rotfaste traeligr gjenspeiler rekursiv dekomponering I binaeligre soslashketraeligr er alt i venst-re deltre mindre enn rota mens alt i hoslashyre deltre er stoslashrre og det gjelder rekursivtfor alle deltraeligr Hauger er enklere Alt er mindre enn rota Det begrenser funksjo-naliteten men gjoslashr dem billigere aring bygge og balansere

Pensum

Kap 6 Heapsort

Kap 10 Elementary data structures 104

Kap 12 Binary search trees Innledning og 121ndash123

Laeligringsmaringl

[E1] Forstaring hvordan heaps fungerer og hvordan de kan brukes som prioritetskoslasher(Parent Left Right Max-Heapify Build-Max-Heap Heapsort Max-Heap-InsertHeap-Extract-Max Heap-Increase-Key Heap-Maximum Ogsaring tilsvarende for min-heaps feks Build-Min-Heap og Heap-Extract-Min)

[E2] Forstaring Heapsort[E3] Forstaring hvordan rotfaste traeligr kan implementeres

[E4] Forstaring hvordan binaeligre soslashketraeligr fungerer(Inorder-Tree-Walk Tree-Search Iterative-Tree-Search Tree-Minimum Tree-Maximum Tree-Successor Tree-Predecessor Tree-Insert Transplant Tree-Delete)

[E5] Vite at forventet hoslashyde for et tilfeldig binaeligrt soslashketre er Θ(lg n)[E6] Vite at det finnes soslashketraeligr med garantert hoslashyde paring Θ(lg n)

Merk Det kreves ikke grundig forstaringelse av Transplant og Tree-Delete

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

6

Forelesning 6

Dynamisk programmering

Paring sett og vis en generalisering av splitt og hersk der delprobler kan overlappe Istedet for et tre av delinstans-avhengigheter har vi en rettet asyklisk graf Vi finnerog lagrer del-loslashsninger i en rekkefoslashlge som stemmer med avhengighetene

Pensum

Kap 15 Dynamic programming Innledning og 151 153ndash154

Oppgave 162-2 med loslashsning (0-1 knapsack)

Appendiks D i dette heftet

Delkapitler 152 og 155 kan vaeligre nyttige som stoslashttelitteratur

Laeligringsmaringl

[F1] Forstaring ideen om en delinstansgraf [F2] Forstaring designmetoden dynamisk programmering [F3] Forstaring loslashsning ved memoisering (top-down)

[F4] Forstaring loslashsning ved iterasjon (bottom-up)[F5] Forstaring hvordan man rekonstruerer en loslashsning fra lagrede beslutninger[F6] Forstaring hva optimal delstruktur er[F7] Forstaring hva overlappende delinstanser er[F8] Forstaring eksemplene stavkutting og LCS[F9] Forstaring loslashsningen paring det binaeligre ryggsekkproblemet (se appendiks D i dette

heftet)(Knapsack Knapsackprime)

Merk Noe av stoffet vil kanskje forskyves til forelesning 7

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

7

Forelesning 7

Graringdige algoritmer

Graringdige algoritmer bestaringr av en serie med valg og hvert valg tas lokalt Algorit-men gjoslashr alltid det som ser best ut her og naring uten noe stoslashrre perspektiv Slikealgoritmer er ofte enkle utfordringen ligger i aring finne ut om de gir rett svar

Pensum

Kap 16 Greedy algorithms Innledning og 161ndash163

Laeligringsmaringl

[G1] Forstaring designmetoden graringdighet [G2] Forstaring graringdighetsegenskapen (the greedy-choice property)

[G3] Forstaring eksemplene aktivitet-utvelgelse og det kontinuerlige ryggsekkproblemet[G4] Forstaring Huffman og Huffman-koder

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

8

Forelesning 8

Traversering av grafer

Vi traverserer en graf ved aring besoslashke noder vi vet om Vi vet i utgangspunktet bareom startnoden men oppdager naboene til dem vi besoslashker Traversering er viktig iseg selv men danner ogsaring ryggraden til flere mer avanserte algoritmer

Pensum

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Appendiks E i dette heftet

Laeligringsmaringl

[H1] Forstaring hvordan grafer kan implementeres[H2] Forstaring BFS ogsaring for aring finne korteste vei uten vekter[H3] Forstaring DFS og parentesteoremet[H4] Forstaring hvordan DFS klassifiserer kanter[H5] Forstaring Topological-Sort[H6] Forstaring hvordan DFS kan implementeres med en stakk[H7] Forstaring hva traverseringstraeligr (som bredde-foslashrst- og dybde-foslashrst-traeligr) er

[H8] Forstaring traversering med vilkaringrlig prioritetskoslash

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

9

Forelesning 9

Minimale spenntraeligr

Her har vi en graf med vekter paring kantene og oslashnsker aring bare beholde akkurat dekantene vi maring for aring koble sammen alle nodene med en saring lav vektsum som muligErke-eksempel paring graringdighet Velg eacuten og eacuten kant alltid den billigste lovlige

Pensum

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 23 Minimum spanning trees

Laeligringsmaringl

[I1] Forstaring skog-implementasjonen av disjunkte mengder(Connected-Components Same-Component Make-Set Union Link Find-Set)

[I2] Vite hva spenntraeligr og minimale spenntraeligr er [I3] Forstaring Generic-MST

[I4] Forstaring hvorfor lette kanter er trygge kanter[I5] Forstaring MST-Kruskal[I6] Forstaring MST-Prim

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

10

Forelesning 10

Korteste vei fra eacuten til alle

Bredde-foslashrst-soslashk kan finne stier med faeligrrest mulig kanter men hva om kantenehar ulik lengde Det generelle problemet er uloslashst men vi kan loslashse problemet medgradvis bedre kjoslashretid for grafer (1) uten negative sykler (2) uten negative kanterog (3) uten sykler Og vi bruker samme prinsipp for alle tre

Pensum

Kap 24 Single-source shortest paths Innledning og 241ndash243

Laeligringsmaringl

[J1] Forstaring ulike varianter av korteste-vei- eller korteste-sti-problemet(Single-source single-destination single-pair all-pairs)

[J2] Forstaring strukturen til korteste-vei-problemet[J3] Forstaring at negative sykler gir mening for korteste enkle vei (simple path)[J4] Forstaring at korteste enkle vei kan loslashses vha lengste enkle vei og omvendt[J5] Forstaring hvordan man kan representere et korteste-vei-tre

[J6] Forstaring kant-slakking (edge relaxation) og Relax[J7] Forstaring ulike egenskaper ved korteste veier og slakking

(Triangle inequality upper-bound property no-path property convergence property path-relaxation property predecessor-subgraph property)

[J8] Forstaring Bellman-Ford[J9] Forstaring DAG-Shortest-Path

[J10] Forstaring kobling mellom DAG-Shortest-Path og dynamisk programmering[J11] Forstaring Dijkstra

Merk Noe av stoffet vil kanskje forskyves til forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

11

Forelesning 11

Korteste vei fra alle til alle

Vi kan finne de korteste veiene fra hver node etter tur men mange av delinstanse-ne vil overlappe ndash om vi har mange nok kanter loslashnner det seg aring bruke dynamiskprogrammering med dekomponeringen laquoSkal vi innom k eller ikkeraquo

Pensum

Kap 25 All-pairs shortest paths Innledning 252 og 253

Laeligringsmaringl

[K1] Forstaring forgjengerstrukturen for alle-til-alle-varianten av korteste vei-problemet(Print-All-Pairs-Shortest-Path)

[K2] Forstaring Floyd-Warshall[K3] Forstaring Transitive-Closure[K4] Forstaring Johnson

Merk Noe stoff fra forelesning 12 vil kanskje dekkes her

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

12

Forelesning 12

Maksimal flyt

Et stort skritt i retning av generell lineaeligr optimering (saringkalt lineaeligr programme-ring) Her ser vi paring to tilsynelatende forskjellige problemer som viser seg aring vaeligreduale av hverandre noe som hjelper oss med aring finne en loslashsning

Pensum

Kap 26 Maximum flow Innledning og 261ndash263

Laeligringsmaringl

[L1] Kunne definere flytnett flyt og maks-flyt-problemet[L2] Kunne haringndtere antiparallelle kanter og flere kilder og sluk

[L3] Kunne definere restnettet til et flytnett med en gitt flyt[L4] Forstaring hvordan man kan oppheve (cancel) flyt[L5] Forstaring hva en foroslashkende sti (augmenting path) er[L6] Forstaring hva snitt snitt-kapasitet og minimalt snitt er

[L7] Forstaring maks-flytmin-snitt-teoremet[L8] Forstaring Ford-Fulkerson-Method og Ford-Fulkerson[L9] Vite at Ford-Fulkerson med BFS kalles Edmonds-Karp-algoritmen[L10] Forstaring hvordan maks-flyt kan finne en maksimum bipartitt matching

[L11] Forstaring heltallsteoremet (integrality theorem)

Merk Noe av stoffet vil kanskje dekkes i forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

13

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 7: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Gjennom semesteretDet foslashlgende er pensum knyttet til flere forelesninger gjennom semesteret

Lysark fra ordinaeligre forelesninger

Appendiks til dette dokumentet

Laeligringsmaringl for hver algoritme

[Z1] Kjenne den formelle definisjonen av det generelle problemet den loslashser[Z2] Kjenne til eventuelle tilleggskrav den stiller for aring vaeligre korrekt[Z3] Vite hvordan den oppfoslashrer seg kunne utfoslashre algoritmen trinn for trinn

[Z4] Forstaring korrekthetsbeviset hvordan og hvorfor virker algoritmen egentlig[Z5] Kjenne til eventuelle styrker eller svakheter sammenlignet med andre[Z6] Kjenne kjoslashretidene under ulike omstendigheter og forstaring utregningen

Laeligringsmaringl for hver datastruktur

[Z7] Forstaring algoritmene (jf maringl Z01ndashZ06) for de ulike operasjonene paring strukturen[Z8] Forstaring hvordan strukturen representeres i minnet

Laeligringsmaringl for hvert problem

[Z9] Kunne angi presist hva input er[Z10] Kunne angi presist hva output er og hvilke egenskaper det maring ha

Hva betyr laquoforstaringraquo

Gode laeligringsmaringl og laeligringsutbyttebeskrivelser formuleres gjerne som hva manskal vaeligre i stand til om man oppnaringr maringlet For enkhelhets skyld har jeg fleresteder brukt begrepet forstaring Dette kan du i praksis oversette til kunne forklare

I pensumheftet brukes en del norske begreper mens laeligreboka er paring engelskEn oversikt over oversettelser som brukes finner du paring nettsidenealgdatidintnunoordhtml

v

PensumoversiktDelkapitler er ogsaring listet opp under tilhoslashrende forelesning sammen med laeligringsmaringlKapittel- og oppgavereferanser er til Introduction to Algorithms av Cormen mfl [1]

Kap 1 The role of algorithms in computing

Kap 2 Getting started

Kap 3 Growth of functions Innledning og 31

Kap 4 Divide-and-conquer Innledning 41 og 43ndash45

Kap 6 Heapsort

Kap 7 Quicksort

Kap 8 Sorting in linear time

Kap 9 Medians and order statistics

Kap 10 Elementary data structures

Kap 11 Hash tables s 253ndash264

Kap 12 Binary search trees Innledning og 121ndash123

Kap 15 Dynamic programming Innledning og 151 153ndash154

Kap 16 Greedy algorithms Innledning og 161ndash163

Kap 17 Amortized analysis Innledning og s 463ndash465 (tom laquoat most 3raquo)

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Kap 23 Minimum spanning trees

Kap 24 Single-source shortest paths Innledning og 241ndash243

Kap 25 All-pairs shortest paths Innledning 252 og 253

Kap 26 Maximum flow Innledning og 261ndash263

Kap 34 NP-completeness

Oppgaver 23-5 45-3 162-2 og 341-4 med loslashsning

Appendiks AndashF i dette heftet

1

Forelesning 1

Problemer og algoritmer

Vi starter med fagfeltets grunnleggende byggesteiner og skisserer et rammeverk foraring tilegne seg resten av stoffet Spesielt viktig er ideen bak induksjon og rekursjonVi trenger bare se paring siste trinn og kan anta at resten er paring plass

Pensum

Kap 1 The role of algorithms in computing

Kap 2 Getting started Innledning 21ndash22

Kap 3 Growth of functions Innledning og 31

Laeligringsmaringl

[A1] Forstaring bokas pseudokode-konvensjoner[A2] Kjenne egenskapene til random-access machine-modellen (RAM)[A3] Kunne definere problem instans og problemstoslashrrelse

[A4] Kunne definere asymptotisk notasjon O Ω Θ o og ω [A5] Kunne definere best-case average-case og worst-case [A6] Forstaring loslashkkeinvarianter og induksjon [A7] Forstaring rekursiv dekomponering og induksjon over delinstanser

[A8] Forstaring Insertion-Sort

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

2

Forelesning 2

Datastrukturer

For aring unngaring grunnleggende kjoslashretidsfeller er det viktig aring kunne organisere og struk-turere data fornuftig Her skal vi se paring hvordan enkle strukturer kan implementeresi praksis og hva vi vinner paring aring bruke dem i algoritmene varingre

Pensum

Kap 10 Elementary data structures Innledning og 101ndash103

Kap 11 Hash tables s 253ndash264

Kap 17 Amortized analysis Innledning og s 463ndash465 (tom laquoat most 3raquo)

Laeligringsmaringl

[B1] Forstaring hvordan stakker og koslasher fungerer(Stack-Empty Push Pop Enqueue Dequeue)

[B2] Forstaring hvordan lenkede lister fungerer(List-Search List-Insert List-Delete List-Deleteprime List-Searchprime List-Insertprime)

[B3] Forstaring hvordan pekere og objekter kan implementeres [B4] Forstaring hvordan direkte adressering og hashtabeller fungerer

(Hash-Insert Hash-Search)

[B5] Forstaring konfliktloslashsing ved kjeding (chaining)(Chained-Hash-Insert Chained-Hash-Search Chained-Hash-Delete)

[B6] Kjenne til grunnleggende hashfunksjoner[B7] Vite at man for statiske datasett kan ha worst-case O(1) for soslashk[B8] Kunne definere amortisert analyse[B9] Forstaring hvordan dynamiske tabeller fungerer

(Table-Insert)

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

3

Forelesning 3

Splitt og hersk

Rekursiv dekomponering er kanskje den viktigste ideen i hele faget og designmeto-den splitt og hersk er en grunnleggende utgave av det Del instansen i mindre biterloslashs problemet rekursivt for disse og kombineacuter loslashsningene

Pensum

Kap 2 Getting started 23

Kap 4 Divide-and-conquer Innledning 41 og 43ndash45

Kap 7 Quicksort

Oppgaver 23-5 og 45-3 med loslashsning (binaeligrsoslashk)

Appendiks B og C i dette heftet

Laeligringsmaringl

[C1] Forstaring designmetoden divide-and-conquer (splitt og hersk)[C2] Forstaring maximum-subarray-problemet med loslashsninger[C3] Forstaring Bisect og Bisectprime (se appendiks C i dette heftet)[C4] Forstaring Merge-Sort[C5] Forstaring Quicksort og Randomized-Quicksort

[C6] Kunne loslashse rekurrenser med substitusjon rekursjonstraeligr og masterteoremet [C7] Kunne loslashse rekurrenser med iterasjonsmetoden (se appendiks B i dette heftet)

[C8] Forstaring hvordan variabelskifte fungerer

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

4

Forelesning 4

Rangering i lineaeligr tid

Vi kan ofte faring bedre loslashsninger ved aring styrke kravene til input eller ved aring svekkekravene til output Sortering basert paring sammenligninger (x 6 y) er et klassiskeksempel I verste tilfelle maring vi bruke lg n sammenligningermen om vi antar merom elementene eller bare sorterer noen av dem saring kan vi gjoslashre det bedre

Pensum

Kap 8 Sorting in linear time

Kap 9 Medians and order statistics

Laeligringsmaringl

[D1] Forstaring hvorfor sammenligningsbasert sortering har en worst-case paring Ω(n lg n)[D2] Vite hva en stabil sorteringsalgoritme er[D3] Forstaring Counting-Sort og hvorfor den er stabil

[D4] Forstaring Radix-Sort og hvorfor den trenger en stabil subrutine[D5] Forstaring Bucket-Sort[D6] Forstaring Randomized-Select[D7] Kjenne til Select

Merk Det kreves ikke grundig forstaringelse av virkemaringten til Select

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

5

Forelesning 5

Rotfaste trestrukturer

Rotfaste traeligr gjenspeiler rekursiv dekomponering I binaeligre soslashketraeligr er alt i venst-re deltre mindre enn rota mens alt i hoslashyre deltre er stoslashrre og det gjelder rekursivtfor alle deltraeligr Hauger er enklere Alt er mindre enn rota Det begrenser funksjo-naliteten men gjoslashr dem billigere aring bygge og balansere

Pensum

Kap 6 Heapsort

Kap 10 Elementary data structures 104

Kap 12 Binary search trees Innledning og 121ndash123

Laeligringsmaringl

[E1] Forstaring hvordan heaps fungerer og hvordan de kan brukes som prioritetskoslasher(Parent Left Right Max-Heapify Build-Max-Heap Heapsort Max-Heap-InsertHeap-Extract-Max Heap-Increase-Key Heap-Maximum Ogsaring tilsvarende for min-heaps feks Build-Min-Heap og Heap-Extract-Min)

[E2] Forstaring Heapsort[E3] Forstaring hvordan rotfaste traeligr kan implementeres

[E4] Forstaring hvordan binaeligre soslashketraeligr fungerer(Inorder-Tree-Walk Tree-Search Iterative-Tree-Search Tree-Minimum Tree-Maximum Tree-Successor Tree-Predecessor Tree-Insert Transplant Tree-Delete)

[E5] Vite at forventet hoslashyde for et tilfeldig binaeligrt soslashketre er Θ(lg n)[E6] Vite at det finnes soslashketraeligr med garantert hoslashyde paring Θ(lg n)

Merk Det kreves ikke grundig forstaringelse av Transplant og Tree-Delete

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

6

Forelesning 6

Dynamisk programmering

Paring sett og vis en generalisering av splitt og hersk der delprobler kan overlappe Istedet for et tre av delinstans-avhengigheter har vi en rettet asyklisk graf Vi finnerog lagrer del-loslashsninger i en rekkefoslashlge som stemmer med avhengighetene

Pensum

Kap 15 Dynamic programming Innledning og 151 153ndash154

Oppgave 162-2 med loslashsning (0-1 knapsack)

Appendiks D i dette heftet

Delkapitler 152 og 155 kan vaeligre nyttige som stoslashttelitteratur

Laeligringsmaringl

[F1] Forstaring ideen om en delinstansgraf [F2] Forstaring designmetoden dynamisk programmering [F3] Forstaring loslashsning ved memoisering (top-down)

[F4] Forstaring loslashsning ved iterasjon (bottom-up)[F5] Forstaring hvordan man rekonstruerer en loslashsning fra lagrede beslutninger[F6] Forstaring hva optimal delstruktur er[F7] Forstaring hva overlappende delinstanser er[F8] Forstaring eksemplene stavkutting og LCS[F9] Forstaring loslashsningen paring det binaeligre ryggsekkproblemet (se appendiks D i dette

heftet)(Knapsack Knapsackprime)

Merk Noe av stoffet vil kanskje forskyves til forelesning 7

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

7

Forelesning 7

Graringdige algoritmer

Graringdige algoritmer bestaringr av en serie med valg og hvert valg tas lokalt Algorit-men gjoslashr alltid det som ser best ut her og naring uten noe stoslashrre perspektiv Slikealgoritmer er ofte enkle utfordringen ligger i aring finne ut om de gir rett svar

Pensum

Kap 16 Greedy algorithms Innledning og 161ndash163

Laeligringsmaringl

[G1] Forstaring designmetoden graringdighet [G2] Forstaring graringdighetsegenskapen (the greedy-choice property)

[G3] Forstaring eksemplene aktivitet-utvelgelse og det kontinuerlige ryggsekkproblemet[G4] Forstaring Huffman og Huffman-koder

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

8

Forelesning 8

Traversering av grafer

Vi traverserer en graf ved aring besoslashke noder vi vet om Vi vet i utgangspunktet bareom startnoden men oppdager naboene til dem vi besoslashker Traversering er viktig iseg selv men danner ogsaring ryggraden til flere mer avanserte algoritmer

Pensum

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Appendiks E i dette heftet

Laeligringsmaringl

[H1] Forstaring hvordan grafer kan implementeres[H2] Forstaring BFS ogsaring for aring finne korteste vei uten vekter[H3] Forstaring DFS og parentesteoremet[H4] Forstaring hvordan DFS klassifiserer kanter[H5] Forstaring Topological-Sort[H6] Forstaring hvordan DFS kan implementeres med en stakk[H7] Forstaring hva traverseringstraeligr (som bredde-foslashrst- og dybde-foslashrst-traeligr) er

[H8] Forstaring traversering med vilkaringrlig prioritetskoslash

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

9

Forelesning 9

Minimale spenntraeligr

Her har vi en graf med vekter paring kantene og oslashnsker aring bare beholde akkurat dekantene vi maring for aring koble sammen alle nodene med en saring lav vektsum som muligErke-eksempel paring graringdighet Velg eacuten og eacuten kant alltid den billigste lovlige

Pensum

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 23 Minimum spanning trees

Laeligringsmaringl

[I1] Forstaring skog-implementasjonen av disjunkte mengder(Connected-Components Same-Component Make-Set Union Link Find-Set)

[I2] Vite hva spenntraeligr og minimale spenntraeligr er [I3] Forstaring Generic-MST

[I4] Forstaring hvorfor lette kanter er trygge kanter[I5] Forstaring MST-Kruskal[I6] Forstaring MST-Prim

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

10

Forelesning 10

Korteste vei fra eacuten til alle

Bredde-foslashrst-soslashk kan finne stier med faeligrrest mulig kanter men hva om kantenehar ulik lengde Det generelle problemet er uloslashst men vi kan loslashse problemet medgradvis bedre kjoslashretid for grafer (1) uten negative sykler (2) uten negative kanterog (3) uten sykler Og vi bruker samme prinsipp for alle tre

Pensum

Kap 24 Single-source shortest paths Innledning og 241ndash243

Laeligringsmaringl

[J1] Forstaring ulike varianter av korteste-vei- eller korteste-sti-problemet(Single-source single-destination single-pair all-pairs)

[J2] Forstaring strukturen til korteste-vei-problemet[J3] Forstaring at negative sykler gir mening for korteste enkle vei (simple path)[J4] Forstaring at korteste enkle vei kan loslashses vha lengste enkle vei og omvendt[J5] Forstaring hvordan man kan representere et korteste-vei-tre

[J6] Forstaring kant-slakking (edge relaxation) og Relax[J7] Forstaring ulike egenskaper ved korteste veier og slakking

(Triangle inequality upper-bound property no-path property convergence property path-relaxation property predecessor-subgraph property)

[J8] Forstaring Bellman-Ford[J9] Forstaring DAG-Shortest-Path

[J10] Forstaring kobling mellom DAG-Shortest-Path og dynamisk programmering[J11] Forstaring Dijkstra

Merk Noe av stoffet vil kanskje forskyves til forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

11

Forelesning 11

Korteste vei fra alle til alle

Vi kan finne de korteste veiene fra hver node etter tur men mange av delinstanse-ne vil overlappe ndash om vi har mange nok kanter loslashnner det seg aring bruke dynamiskprogrammering med dekomponeringen laquoSkal vi innom k eller ikkeraquo

Pensum

Kap 25 All-pairs shortest paths Innledning 252 og 253

Laeligringsmaringl

[K1] Forstaring forgjengerstrukturen for alle-til-alle-varianten av korteste vei-problemet(Print-All-Pairs-Shortest-Path)

[K2] Forstaring Floyd-Warshall[K3] Forstaring Transitive-Closure[K4] Forstaring Johnson

Merk Noe stoff fra forelesning 12 vil kanskje dekkes her

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

12

Forelesning 12

Maksimal flyt

Et stort skritt i retning av generell lineaeligr optimering (saringkalt lineaeligr programme-ring) Her ser vi paring to tilsynelatende forskjellige problemer som viser seg aring vaeligreduale av hverandre noe som hjelper oss med aring finne en loslashsning

Pensum

Kap 26 Maximum flow Innledning og 261ndash263

Laeligringsmaringl

[L1] Kunne definere flytnett flyt og maks-flyt-problemet[L2] Kunne haringndtere antiparallelle kanter og flere kilder og sluk

[L3] Kunne definere restnettet til et flytnett med en gitt flyt[L4] Forstaring hvordan man kan oppheve (cancel) flyt[L5] Forstaring hva en foroslashkende sti (augmenting path) er[L6] Forstaring hva snitt snitt-kapasitet og minimalt snitt er

[L7] Forstaring maks-flytmin-snitt-teoremet[L8] Forstaring Ford-Fulkerson-Method og Ford-Fulkerson[L9] Vite at Ford-Fulkerson med BFS kalles Edmonds-Karp-algoritmen[L10] Forstaring hvordan maks-flyt kan finne en maksimum bipartitt matching

[L11] Forstaring heltallsteoremet (integrality theorem)

Merk Noe av stoffet vil kanskje dekkes i forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

13

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 8: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

PensumoversiktDelkapitler er ogsaring listet opp under tilhoslashrende forelesning sammen med laeligringsmaringlKapittel- og oppgavereferanser er til Introduction to Algorithms av Cormen mfl [1]

Kap 1 The role of algorithms in computing

Kap 2 Getting started

Kap 3 Growth of functions Innledning og 31

Kap 4 Divide-and-conquer Innledning 41 og 43ndash45

Kap 6 Heapsort

Kap 7 Quicksort

Kap 8 Sorting in linear time

Kap 9 Medians and order statistics

Kap 10 Elementary data structures

Kap 11 Hash tables s 253ndash264

Kap 12 Binary search trees Innledning og 121ndash123

Kap 15 Dynamic programming Innledning og 151 153ndash154

Kap 16 Greedy algorithms Innledning og 161ndash163

Kap 17 Amortized analysis Innledning og s 463ndash465 (tom laquoat most 3raquo)

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Kap 23 Minimum spanning trees

Kap 24 Single-source shortest paths Innledning og 241ndash243

Kap 25 All-pairs shortest paths Innledning 252 og 253

Kap 26 Maximum flow Innledning og 261ndash263

Kap 34 NP-completeness

Oppgaver 23-5 45-3 162-2 og 341-4 med loslashsning

Appendiks AndashF i dette heftet

1

Forelesning 1

Problemer og algoritmer

Vi starter med fagfeltets grunnleggende byggesteiner og skisserer et rammeverk foraring tilegne seg resten av stoffet Spesielt viktig er ideen bak induksjon og rekursjonVi trenger bare se paring siste trinn og kan anta at resten er paring plass

Pensum

Kap 1 The role of algorithms in computing

Kap 2 Getting started Innledning 21ndash22

Kap 3 Growth of functions Innledning og 31

Laeligringsmaringl

[A1] Forstaring bokas pseudokode-konvensjoner[A2] Kjenne egenskapene til random-access machine-modellen (RAM)[A3] Kunne definere problem instans og problemstoslashrrelse

[A4] Kunne definere asymptotisk notasjon O Ω Θ o og ω [A5] Kunne definere best-case average-case og worst-case [A6] Forstaring loslashkkeinvarianter og induksjon [A7] Forstaring rekursiv dekomponering og induksjon over delinstanser

[A8] Forstaring Insertion-Sort

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

2

Forelesning 2

Datastrukturer

For aring unngaring grunnleggende kjoslashretidsfeller er det viktig aring kunne organisere og struk-turere data fornuftig Her skal vi se paring hvordan enkle strukturer kan implementeresi praksis og hva vi vinner paring aring bruke dem i algoritmene varingre

Pensum

Kap 10 Elementary data structures Innledning og 101ndash103

Kap 11 Hash tables s 253ndash264

Kap 17 Amortized analysis Innledning og s 463ndash465 (tom laquoat most 3raquo)

Laeligringsmaringl

[B1] Forstaring hvordan stakker og koslasher fungerer(Stack-Empty Push Pop Enqueue Dequeue)

[B2] Forstaring hvordan lenkede lister fungerer(List-Search List-Insert List-Delete List-Deleteprime List-Searchprime List-Insertprime)

[B3] Forstaring hvordan pekere og objekter kan implementeres [B4] Forstaring hvordan direkte adressering og hashtabeller fungerer

(Hash-Insert Hash-Search)

[B5] Forstaring konfliktloslashsing ved kjeding (chaining)(Chained-Hash-Insert Chained-Hash-Search Chained-Hash-Delete)

[B6] Kjenne til grunnleggende hashfunksjoner[B7] Vite at man for statiske datasett kan ha worst-case O(1) for soslashk[B8] Kunne definere amortisert analyse[B9] Forstaring hvordan dynamiske tabeller fungerer

(Table-Insert)

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

3

Forelesning 3

Splitt og hersk

Rekursiv dekomponering er kanskje den viktigste ideen i hele faget og designmeto-den splitt og hersk er en grunnleggende utgave av det Del instansen i mindre biterloslashs problemet rekursivt for disse og kombineacuter loslashsningene

Pensum

Kap 2 Getting started 23

Kap 4 Divide-and-conquer Innledning 41 og 43ndash45

Kap 7 Quicksort

Oppgaver 23-5 og 45-3 med loslashsning (binaeligrsoslashk)

Appendiks B og C i dette heftet

Laeligringsmaringl

[C1] Forstaring designmetoden divide-and-conquer (splitt og hersk)[C2] Forstaring maximum-subarray-problemet med loslashsninger[C3] Forstaring Bisect og Bisectprime (se appendiks C i dette heftet)[C4] Forstaring Merge-Sort[C5] Forstaring Quicksort og Randomized-Quicksort

[C6] Kunne loslashse rekurrenser med substitusjon rekursjonstraeligr og masterteoremet [C7] Kunne loslashse rekurrenser med iterasjonsmetoden (se appendiks B i dette heftet)

[C8] Forstaring hvordan variabelskifte fungerer

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

4

Forelesning 4

Rangering i lineaeligr tid

Vi kan ofte faring bedre loslashsninger ved aring styrke kravene til input eller ved aring svekkekravene til output Sortering basert paring sammenligninger (x 6 y) er et klassiskeksempel I verste tilfelle maring vi bruke lg n sammenligningermen om vi antar merom elementene eller bare sorterer noen av dem saring kan vi gjoslashre det bedre

Pensum

Kap 8 Sorting in linear time

Kap 9 Medians and order statistics

Laeligringsmaringl

[D1] Forstaring hvorfor sammenligningsbasert sortering har en worst-case paring Ω(n lg n)[D2] Vite hva en stabil sorteringsalgoritme er[D3] Forstaring Counting-Sort og hvorfor den er stabil

[D4] Forstaring Radix-Sort og hvorfor den trenger en stabil subrutine[D5] Forstaring Bucket-Sort[D6] Forstaring Randomized-Select[D7] Kjenne til Select

Merk Det kreves ikke grundig forstaringelse av virkemaringten til Select

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

5

Forelesning 5

Rotfaste trestrukturer

Rotfaste traeligr gjenspeiler rekursiv dekomponering I binaeligre soslashketraeligr er alt i venst-re deltre mindre enn rota mens alt i hoslashyre deltre er stoslashrre og det gjelder rekursivtfor alle deltraeligr Hauger er enklere Alt er mindre enn rota Det begrenser funksjo-naliteten men gjoslashr dem billigere aring bygge og balansere

Pensum

Kap 6 Heapsort

Kap 10 Elementary data structures 104

Kap 12 Binary search trees Innledning og 121ndash123

Laeligringsmaringl

[E1] Forstaring hvordan heaps fungerer og hvordan de kan brukes som prioritetskoslasher(Parent Left Right Max-Heapify Build-Max-Heap Heapsort Max-Heap-InsertHeap-Extract-Max Heap-Increase-Key Heap-Maximum Ogsaring tilsvarende for min-heaps feks Build-Min-Heap og Heap-Extract-Min)

[E2] Forstaring Heapsort[E3] Forstaring hvordan rotfaste traeligr kan implementeres

[E4] Forstaring hvordan binaeligre soslashketraeligr fungerer(Inorder-Tree-Walk Tree-Search Iterative-Tree-Search Tree-Minimum Tree-Maximum Tree-Successor Tree-Predecessor Tree-Insert Transplant Tree-Delete)

[E5] Vite at forventet hoslashyde for et tilfeldig binaeligrt soslashketre er Θ(lg n)[E6] Vite at det finnes soslashketraeligr med garantert hoslashyde paring Θ(lg n)

Merk Det kreves ikke grundig forstaringelse av Transplant og Tree-Delete

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

6

Forelesning 6

Dynamisk programmering

Paring sett og vis en generalisering av splitt og hersk der delprobler kan overlappe Istedet for et tre av delinstans-avhengigheter har vi en rettet asyklisk graf Vi finnerog lagrer del-loslashsninger i en rekkefoslashlge som stemmer med avhengighetene

Pensum

Kap 15 Dynamic programming Innledning og 151 153ndash154

Oppgave 162-2 med loslashsning (0-1 knapsack)

Appendiks D i dette heftet

Delkapitler 152 og 155 kan vaeligre nyttige som stoslashttelitteratur

Laeligringsmaringl

[F1] Forstaring ideen om en delinstansgraf [F2] Forstaring designmetoden dynamisk programmering [F3] Forstaring loslashsning ved memoisering (top-down)

[F4] Forstaring loslashsning ved iterasjon (bottom-up)[F5] Forstaring hvordan man rekonstruerer en loslashsning fra lagrede beslutninger[F6] Forstaring hva optimal delstruktur er[F7] Forstaring hva overlappende delinstanser er[F8] Forstaring eksemplene stavkutting og LCS[F9] Forstaring loslashsningen paring det binaeligre ryggsekkproblemet (se appendiks D i dette

heftet)(Knapsack Knapsackprime)

Merk Noe av stoffet vil kanskje forskyves til forelesning 7

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

7

Forelesning 7

Graringdige algoritmer

Graringdige algoritmer bestaringr av en serie med valg og hvert valg tas lokalt Algorit-men gjoslashr alltid det som ser best ut her og naring uten noe stoslashrre perspektiv Slikealgoritmer er ofte enkle utfordringen ligger i aring finne ut om de gir rett svar

Pensum

Kap 16 Greedy algorithms Innledning og 161ndash163

Laeligringsmaringl

[G1] Forstaring designmetoden graringdighet [G2] Forstaring graringdighetsegenskapen (the greedy-choice property)

[G3] Forstaring eksemplene aktivitet-utvelgelse og det kontinuerlige ryggsekkproblemet[G4] Forstaring Huffman og Huffman-koder

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

8

Forelesning 8

Traversering av grafer

Vi traverserer en graf ved aring besoslashke noder vi vet om Vi vet i utgangspunktet bareom startnoden men oppdager naboene til dem vi besoslashker Traversering er viktig iseg selv men danner ogsaring ryggraden til flere mer avanserte algoritmer

Pensum

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Appendiks E i dette heftet

Laeligringsmaringl

[H1] Forstaring hvordan grafer kan implementeres[H2] Forstaring BFS ogsaring for aring finne korteste vei uten vekter[H3] Forstaring DFS og parentesteoremet[H4] Forstaring hvordan DFS klassifiserer kanter[H5] Forstaring Topological-Sort[H6] Forstaring hvordan DFS kan implementeres med en stakk[H7] Forstaring hva traverseringstraeligr (som bredde-foslashrst- og dybde-foslashrst-traeligr) er

[H8] Forstaring traversering med vilkaringrlig prioritetskoslash

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

9

Forelesning 9

Minimale spenntraeligr

Her har vi en graf med vekter paring kantene og oslashnsker aring bare beholde akkurat dekantene vi maring for aring koble sammen alle nodene med en saring lav vektsum som muligErke-eksempel paring graringdighet Velg eacuten og eacuten kant alltid den billigste lovlige

Pensum

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 23 Minimum spanning trees

Laeligringsmaringl

[I1] Forstaring skog-implementasjonen av disjunkte mengder(Connected-Components Same-Component Make-Set Union Link Find-Set)

[I2] Vite hva spenntraeligr og minimale spenntraeligr er [I3] Forstaring Generic-MST

[I4] Forstaring hvorfor lette kanter er trygge kanter[I5] Forstaring MST-Kruskal[I6] Forstaring MST-Prim

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

10

Forelesning 10

Korteste vei fra eacuten til alle

Bredde-foslashrst-soslashk kan finne stier med faeligrrest mulig kanter men hva om kantenehar ulik lengde Det generelle problemet er uloslashst men vi kan loslashse problemet medgradvis bedre kjoslashretid for grafer (1) uten negative sykler (2) uten negative kanterog (3) uten sykler Og vi bruker samme prinsipp for alle tre

Pensum

Kap 24 Single-source shortest paths Innledning og 241ndash243

Laeligringsmaringl

[J1] Forstaring ulike varianter av korteste-vei- eller korteste-sti-problemet(Single-source single-destination single-pair all-pairs)

[J2] Forstaring strukturen til korteste-vei-problemet[J3] Forstaring at negative sykler gir mening for korteste enkle vei (simple path)[J4] Forstaring at korteste enkle vei kan loslashses vha lengste enkle vei og omvendt[J5] Forstaring hvordan man kan representere et korteste-vei-tre

[J6] Forstaring kant-slakking (edge relaxation) og Relax[J7] Forstaring ulike egenskaper ved korteste veier og slakking

(Triangle inequality upper-bound property no-path property convergence property path-relaxation property predecessor-subgraph property)

[J8] Forstaring Bellman-Ford[J9] Forstaring DAG-Shortest-Path

[J10] Forstaring kobling mellom DAG-Shortest-Path og dynamisk programmering[J11] Forstaring Dijkstra

Merk Noe av stoffet vil kanskje forskyves til forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

11

Forelesning 11

Korteste vei fra alle til alle

Vi kan finne de korteste veiene fra hver node etter tur men mange av delinstanse-ne vil overlappe ndash om vi har mange nok kanter loslashnner det seg aring bruke dynamiskprogrammering med dekomponeringen laquoSkal vi innom k eller ikkeraquo

Pensum

Kap 25 All-pairs shortest paths Innledning 252 og 253

Laeligringsmaringl

[K1] Forstaring forgjengerstrukturen for alle-til-alle-varianten av korteste vei-problemet(Print-All-Pairs-Shortest-Path)

[K2] Forstaring Floyd-Warshall[K3] Forstaring Transitive-Closure[K4] Forstaring Johnson

Merk Noe stoff fra forelesning 12 vil kanskje dekkes her

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

12

Forelesning 12

Maksimal flyt

Et stort skritt i retning av generell lineaeligr optimering (saringkalt lineaeligr programme-ring) Her ser vi paring to tilsynelatende forskjellige problemer som viser seg aring vaeligreduale av hverandre noe som hjelper oss med aring finne en loslashsning

Pensum

Kap 26 Maximum flow Innledning og 261ndash263

Laeligringsmaringl

[L1] Kunne definere flytnett flyt og maks-flyt-problemet[L2] Kunne haringndtere antiparallelle kanter og flere kilder og sluk

[L3] Kunne definere restnettet til et flytnett med en gitt flyt[L4] Forstaring hvordan man kan oppheve (cancel) flyt[L5] Forstaring hva en foroslashkende sti (augmenting path) er[L6] Forstaring hva snitt snitt-kapasitet og minimalt snitt er

[L7] Forstaring maks-flytmin-snitt-teoremet[L8] Forstaring Ford-Fulkerson-Method og Ford-Fulkerson[L9] Vite at Ford-Fulkerson med BFS kalles Edmonds-Karp-algoritmen[L10] Forstaring hvordan maks-flyt kan finne en maksimum bipartitt matching

[L11] Forstaring heltallsteoremet (integrality theorem)

Merk Noe av stoffet vil kanskje dekkes i forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

13

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 9: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Forelesning 1

Problemer og algoritmer

Vi starter med fagfeltets grunnleggende byggesteiner og skisserer et rammeverk foraring tilegne seg resten av stoffet Spesielt viktig er ideen bak induksjon og rekursjonVi trenger bare se paring siste trinn og kan anta at resten er paring plass

Pensum

Kap 1 The role of algorithms in computing

Kap 2 Getting started Innledning 21ndash22

Kap 3 Growth of functions Innledning og 31

Laeligringsmaringl

[A1] Forstaring bokas pseudokode-konvensjoner[A2] Kjenne egenskapene til random-access machine-modellen (RAM)[A3] Kunne definere problem instans og problemstoslashrrelse

[A4] Kunne definere asymptotisk notasjon O Ω Θ o og ω [A5] Kunne definere best-case average-case og worst-case [A6] Forstaring loslashkkeinvarianter og induksjon [A7] Forstaring rekursiv dekomponering og induksjon over delinstanser

[A8] Forstaring Insertion-Sort

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

2

Forelesning 2

Datastrukturer

For aring unngaring grunnleggende kjoslashretidsfeller er det viktig aring kunne organisere og struk-turere data fornuftig Her skal vi se paring hvordan enkle strukturer kan implementeresi praksis og hva vi vinner paring aring bruke dem i algoritmene varingre

Pensum

Kap 10 Elementary data structures Innledning og 101ndash103

Kap 11 Hash tables s 253ndash264

Kap 17 Amortized analysis Innledning og s 463ndash465 (tom laquoat most 3raquo)

Laeligringsmaringl

[B1] Forstaring hvordan stakker og koslasher fungerer(Stack-Empty Push Pop Enqueue Dequeue)

[B2] Forstaring hvordan lenkede lister fungerer(List-Search List-Insert List-Delete List-Deleteprime List-Searchprime List-Insertprime)

[B3] Forstaring hvordan pekere og objekter kan implementeres [B4] Forstaring hvordan direkte adressering og hashtabeller fungerer

(Hash-Insert Hash-Search)

[B5] Forstaring konfliktloslashsing ved kjeding (chaining)(Chained-Hash-Insert Chained-Hash-Search Chained-Hash-Delete)

[B6] Kjenne til grunnleggende hashfunksjoner[B7] Vite at man for statiske datasett kan ha worst-case O(1) for soslashk[B8] Kunne definere amortisert analyse[B9] Forstaring hvordan dynamiske tabeller fungerer

(Table-Insert)

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

3

Forelesning 3

Splitt og hersk

Rekursiv dekomponering er kanskje den viktigste ideen i hele faget og designmeto-den splitt og hersk er en grunnleggende utgave av det Del instansen i mindre biterloslashs problemet rekursivt for disse og kombineacuter loslashsningene

Pensum

Kap 2 Getting started 23

Kap 4 Divide-and-conquer Innledning 41 og 43ndash45

Kap 7 Quicksort

Oppgaver 23-5 og 45-3 med loslashsning (binaeligrsoslashk)

Appendiks B og C i dette heftet

Laeligringsmaringl

[C1] Forstaring designmetoden divide-and-conquer (splitt og hersk)[C2] Forstaring maximum-subarray-problemet med loslashsninger[C3] Forstaring Bisect og Bisectprime (se appendiks C i dette heftet)[C4] Forstaring Merge-Sort[C5] Forstaring Quicksort og Randomized-Quicksort

[C6] Kunne loslashse rekurrenser med substitusjon rekursjonstraeligr og masterteoremet [C7] Kunne loslashse rekurrenser med iterasjonsmetoden (se appendiks B i dette heftet)

[C8] Forstaring hvordan variabelskifte fungerer

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

4

Forelesning 4

Rangering i lineaeligr tid

Vi kan ofte faring bedre loslashsninger ved aring styrke kravene til input eller ved aring svekkekravene til output Sortering basert paring sammenligninger (x 6 y) er et klassiskeksempel I verste tilfelle maring vi bruke lg n sammenligningermen om vi antar merom elementene eller bare sorterer noen av dem saring kan vi gjoslashre det bedre

Pensum

Kap 8 Sorting in linear time

Kap 9 Medians and order statistics

Laeligringsmaringl

[D1] Forstaring hvorfor sammenligningsbasert sortering har en worst-case paring Ω(n lg n)[D2] Vite hva en stabil sorteringsalgoritme er[D3] Forstaring Counting-Sort og hvorfor den er stabil

[D4] Forstaring Radix-Sort og hvorfor den trenger en stabil subrutine[D5] Forstaring Bucket-Sort[D6] Forstaring Randomized-Select[D7] Kjenne til Select

Merk Det kreves ikke grundig forstaringelse av virkemaringten til Select

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

5

Forelesning 5

Rotfaste trestrukturer

Rotfaste traeligr gjenspeiler rekursiv dekomponering I binaeligre soslashketraeligr er alt i venst-re deltre mindre enn rota mens alt i hoslashyre deltre er stoslashrre og det gjelder rekursivtfor alle deltraeligr Hauger er enklere Alt er mindre enn rota Det begrenser funksjo-naliteten men gjoslashr dem billigere aring bygge og balansere

Pensum

Kap 6 Heapsort

Kap 10 Elementary data structures 104

Kap 12 Binary search trees Innledning og 121ndash123

Laeligringsmaringl

[E1] Forstaring hvordan heaps fungerer og hvordan de kan brukes som prioritetskoslasher(Parent Left Right Max-Heapify Build-Max-Heap Heapsort Max-Heap-InsertHeap-Extract-Max Heap-Increase-Key Heap-Maximum Ogsaring tilsvarende for min-heaps feks Build-Min-Heap og Heap-Extract-Min)

[E2] Forstaring Heapsort[E3] Forstaring hvordan rotfaste traeligr kan implementeres

[E4] Forstaring hvordan binaeligre soslashketraeligr fungerer(Inorder-Tree-Walk Tree-Search Iterative-Tree-Search Tree-Minimum Tree-Maximum Tree-Successor Tree-Predecessor Tree-Insert Transplant Tree-Delete)

[E5] Vite at forventet hoslashyde for et tilfeldig binaeligrt soslashketre er Θ(lg n)[E6] Vite at det finnes soslashketraeligr med garantert hoslashyde paring Θ(lg n)

Merk Det kreves ikke grundig forstaringelse av Transplant og Tree-Delete

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

6

Forelesning 6

Dynamisk programmering

Paring sett og vis en generalisering av splitt og hersk der delprobler kan overlappe Istedet for et tre av delinstans-avhengigheter har vi en rettet asyklisk graf Vi finnerog lagrer del-loslashsninger i en rekkefoslashlge som stemmer med avhengighetene

Pensum

Kap 15 Dynamic programming Innledning og 151 153ndash154

Oppgave 162-2 med loslashsning (0-1 knapsack)

Appendiks D i dette heftet

Delkapitler 152 og 155 kan vaeligre nyttige som stoslashttelitteratur

Laeligringsmaringl

[F1] Forstaring ideen om en delinstansgraf [F2] Forstaring designmetoden dynamisk programmering [F3] Forstaring loslashsning ved memoisering (top-down)

[F4] Forstaring loslashsning ved iterasjon (bottom-up)[F5] Forstaring hvordan man rekonstruerer en loslashsning fra lagrede beslutninger[F6] Forstaring hva optimal delstruktur er[F7] Forstaring hva overlappende delinstanser er[F8] Forstaring eksemplene stavkutting og LCS[F9] Forstaring loslashsningen paring det binaeligre ryggsekkproblemet (se appendiks D i dette

heftet)(Knapsack Knapsackprime)

Merk Noe av stoffet vil kanskje forskyves til forelesning 7

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

7

Forelesning 7

Graringdige algoritmer

Graringdige algoritmer bestaringr av en serie med valg og hvert valg tas lokalt Algorit-men gjoslashr alltid det som ser best ut her og naring uten noe stoslashrre perspektiv Slikealgoritmer er ofte enkle utfordringen ligger i aring finne ut om de gir rett svar

Pensum

Kap 16 Greedy algorithms Innledning og 161ndash163

Laeligringsmaringl

[G1] Forstaring designmetoden graringdighet [G2] Forstaring graringdighetsegenskapen (the greedy-choice property)

[G3] Forstaring eksemplene aktivitet-utvelgelse og det kontinuerlige ryggsekkproblemet[G4] Forstaring Huffman og Huffman-koder

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

8

Forelesning 8

Traversering av grafer

Vi traverserer en graf ved aring besoslashke noder vi vet om Vi vet i utgangspunktet bareom startnoden men oppdager naboene til dem vi besoslashker Traversering er viktig iseg selv men danner ogsaring ryggraden til flere mer avanserte algoritmer

Pensum

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Appendiks E i dette heftet

Laeligringsmaringl

[H1] Forstaring hvordan grafer kan implementeres[H2] Forstaring BFS ogsaring for aring finne korteste vei uten vekter[H3] Forstaring DFS og parentesteoremet[H4] Forstaring hvordan DFS klassifiserer kanter[H5] Forstaring Topological-Sort[H6] Forstaring hvordan DFS kan implementeres med en stakk[H7] Forstaring hva traverseringstraeligr (som bredde-foslashrst- og dybde-foslashrst-traeligr) er

[H8] Forstaring traversering med vilkaringrlig prioritetskoslash

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

9

Forelesning 9

Minimale spenntraeligr

Her har vi en graf med vekter paring kantene og oslashnsker aring bare beholde akkurat dekantene vi maring for aring koble sammen alle nodene med en saring lav vektsum som muligErke-eksempel paring graringdighet Velg eacuten og eacuten kant alltid den billigste lovlige

Pensum

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 23 Minimum spanning trees

Laeligringsmaringl

[I1] Forstaring skog-implementasjonen av disjunkte mengder(Connected-Components Same-Component Make-Set Union Link Find-Set)

[I2] Vite hva spenntraeligr og minimale spenntraeligr er [I3] Forstaring Generic-MST

[I4] Forstaring hvorfor lette kanter er trygge kanter[I5] Forstaring MST-Kruskal[I6] Forstaring MST-Prim

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

10

Forelesning 10

Korteste vei fra eacuten til alle

Bredde-foslashrst-soslashk kan finne stier med faeligrrest mulig kanter men hva om kantenehar ulik lengde Det generelle problemet er uloslashst men vi kan loslashse problemet medgradvis bedre kjoslashretid for grafer (1) uten negative sykler (2) uten negative kanterog (3) uten sykler Og vi bruker samme prinsipp for alle tre

Pensum

Kap 24 Single-source shortest paths Innledning og 241ndash243

Laeligringsmaringl

[J1] Forstaring ulike varianter av korteste-vei- eller korteste-sti-problemet(Single-source single-destination single-pair all-pairs)

[J2] Forstaring strukturen til korteste-vei-problemet[J3] Forstaring at negative sykler gir mening for korteste enkle vei (simple path)[J4] Forstaring at korteste enkle vei kan loslashses vha lengste enkle vei og omvendt[J5] Forstaring hvordan man kan representere et korteste-vei-tre

[J6] Forstaring kant-slakking (edge relaxation) og Relax[J7] Forstaring ulike egenskaper ved korteste veier og slakking

(Triangle inequality upper-bound property no-path property convergence property path-relaxation property predecessor-subgraph property)

[J8] Forstaring Bellman-Ford[J9] Forstaring DAG-Shortest-Path

[J10] Forstaring kobling mellom DAG-Shortest-Path og dynamisk programmering[J11] Forstaring Dijkstra

Merk Noe av stoffet vil kanskje forskyves til forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

11

Forelesning 11

Korteste vei fra alle til alle

Vi kan finne de korteste veiene fra hver node etter tur men mange av delinstanse-ne vil overlappe ndash om vi har mange nok kanter loslashnner det seg aring bruke dynamiskprogrammering med dekomponeringen laquoSkal vi innom k eller ikkeraquo

Pensum

Kap 25 All-pairs shortest paths Innledning 252 og 253

Laeligringsmaringl

[K1] Forstaring forgjengerstrukturen for alle-til-alle-varianten av korteste vei-problemet(Print-All-Pairs-Shortest-Path)

[K2] Forstaring Floyd-Warshall[K3] Forstaring Transitive-Closure[K4] Forstaring Johnson

Merk Noe stoff fra forelesning 12 vil kanskje dekkes her

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

12

Forelesning 12

Maksimal flyt

Et stort skritt i retning av generell lineaeligr optimering (saringkalt lineaeligr programme-ring) Her ser vi paring to tilsynelatende forskjellige problemer som viser seg aring vaeligreduale av hverandre noe som hjelper oss med aring finne en loslashsning

Pensum

Kap 26 Maximum flow Innledning og 261ndash263

Laeligringsmaringl

[L1] Kunne definere flytnett flyt og maks-flyt-problemet[L2] Kunne haringndtere antiparallelle kanter og flere kilder og sluk

[L3] Kunne definere restnettet til et flytnett med en gitt flyt[L4] Forstaring hvordan man kan oppheve (cancel) flyt[L5] Forstaring hva en foroslashkende sti (augmenting path) er[L6] Forstaring hva snitt snitt-kapasitet og minimalt snitt er

[L7] Forstaring maks-flytmin-snitt-teoremet[L8] Forstaring Ford-Fulkerson-Method og Ford-Fulkerson[L9] Vite at Ford-Fulkerson med BFS kalles Edmonds-Karp-algoritmen[L10] Forstaring hvordan maks-flyt kan finne en maksimum bipartitt matching

[L11] Forstaring heltallsteoremet (integrality theorem)

Merk Noe av stoffet vil kanskje dekkes i forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

13

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 10: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Forelesning 2

Datastrukturer

For aring unngaring grunnleggende kjoslashretidsfeller er det viktig aring kunne organisere og struk-turere data fornuftig Her skal vi se paring hvordan enkle strukturer kan implementeresi praksis og hva vi vinner paring aring bruke dem i algoritmene varingre

Pensum

Kap 10 Elementary data structures Innledning og 101ndash103

Kap 11 Hash tables s 253ndash264

Kap 17 Amortized analysis Innledning og s 463ndash465 (tom laquoat most 3raquo)

Laeligringsmaringl

[B1] Forstaring hvordan stakker og koslasher fungerer(Stack-Empty Push Pop Enqueue Dequeue)

[B2] Forstaring hvordan lenkede lister fungerer(List-Search List-Insert List-Delete List-Deleteprime List-Searchprime List-Insertprime)

[B3] Forstaring hvordan pekere og objekter kan implementeres [B4] Forstaring hvordan direkte adressering og hashtabeller fungerer

(Hash-Insert Hash-Search)

[B5] Forstaring konfliktloslashsing ved kjeding (chaining)(Chained-Hash-Insert Chained-Hash-Search Chained-Hash-Delete)

[B6] Kjenne til grunnleggende hashfunksjoner[B7] Vite at man for statiske datasett kan ha worst-case O(1) for soslashk[B8] Kunne definere amortisert analyse[B9] Forstaring hvordan dynamiske tabeller fungerer

(Table-Insert)

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

3

Forelesning 3

Splitt og hersk

Rekursiv dekomponering er kanskje den viktigste ideen i hele faget og designmeto-den splitt og hersk er en grunnleggende utgave av det Del instansen i mindre biterloslashs problemet rekursivt for disse og kombineacuter loslashsningene

Pensum

Kap 2 Getting started 23

Kap 4 Divide-and-conquer Innledning 41 og 43ndash45

Kap 7 Quicksort

Oppgaver 23-5 og 45-3 med loslashsning (binaeligrsoslashk)

Appendiks B og C i dette heftet

Laeligringsmaringl

[C1] Forstaring designmetoden divide-and-conquer (splitt og hersk)[C2] Forstaring maximum-subarray-problemet med loslashsninger[C3] Forstaring Bisect og Bisectprime (se appendiks C i dette heftet)[C4] Forstaring Merge-Sort[C5] Forstaring Quicksort og Randomized-Quicksort

[C6] Kunne loslashse rekurrenser med substitusjon rekursjonstraeligr og masterteoremet [C7] Kunne loslashse rekurrenser med iterasjonsmetoden (se appendiks B i dette heftet)

[C8] Forstaring hvordan variabelskifte fungerer

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

4

Forelesning 4

Rangering i lineaeligr tid

Vi kan ofte faring bedre loslashsninger ved aring styrke kravene til input eller ved aring svekkekravene til output Sortering basert paring sammenligninger (x 6 y) er et klassiskeksempel I verste tilfelle maring vi bruke lg n sammenligningermen om vi antar merom elementene eller bare sorterer noen av dem saring kan vi gjoslashre det bedre

Pensum

Kap 8 Sorting in linear time

Kap 9 Medians and order statistics

Laeligringsmaringl

[D1] Forstaring hvorfor sammenligningsbasert sortering har en worst-case paring Ω(n lg n)[D2] Vite hva en stabil sorteringsalgoritme er[D3] Forstaring Counting-Sort og hvorfor den er stabil

[D4] Forstaring Radix-Sort og hvorfor den trenger en stabil subrutine[D5] Forstaring Bucket-Sort[D6] Forstaring Randomized-Select[D7] Kjenne til Select

Merk Det kreves ikke grundig forstaringelse av virkemaringten til Select

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

5

Forelesning 5

Rotfaste trestrukturer

Rotfaste traeligr gjenspeiler rekursiv dekomponering I binaeligre soslashketraeligr er alt i venst-re deltre mindre enn rota mens alt i hoslashyre deltre er stoslashrre og det gjelder rekursivtfor alle deltraeligr Hauger er enklere Alt er mindre enn rota Det begrenser funksjo-naliteten men gjoslashr dem billigere aring bygge og balansere

Pensum

Kap 6 Heapsort

Kap 10 Elementary data structures 104

Kap 12 Binary search trees Innledning og 121ndash123

Laeligringsmaringl

[E1] Forstaring hvordan heaps fungerer og hvordan de kan brukes som prioritetskoslasher(Parent Left Right Max-Heapify Build-Max-Heap Heapsort Max-Heap-InsertHeap-Extract-Max Heap-Increase-Key Heap-Maximum Ogsaring tilsvarende for min-heaps feks Build-Min-Heap og Heap-Extract-Min)

[E2] Forstaring Heapsort[E3] Forstaring hvordan rotfaste traeligr kan implementeres

[E4] Forstaring hvordan binaeligre soslashketraeligr fungerer(Inorder-Tree-Walk Tree-Search Iterative-Tree-Search Tree-Minimum Tree-Maximum Tree-Successor Tree-Predecessor Tree-Insert Transplant Tree-Delete)

[E5] Vite at forventet hoslashyde for et tilfeldig binaeligrt soslashketre er Θ(lg n)[E6] Vite at det finnes soslashketraeligr med garantert hoslashyde paring Θ(lg n)

Merk Det kreves ikke grundig forstaringelse av Transplant og Tree-Delete

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

6

Forelesning 6

Dynamisk programmering

Paring sett og vis en generalisering av splitt og hersk der delprobler kan overlappe Istedet for et tre av delinstans-avhengigheter har vi en rettet asyklisk graf Vi finnerog lagrer del-loslashsninger i en rekkefoslashlge som stemmer med avhengighetene

Pensum

Kap 15 Dynamic programming Innledning og 151 153ndash154

Oppgave 162-2 med loslashsning (0-1 knapsack)

Appendiks D i dette heftet

Delkapitler 152 og 155 kan vaeligre nyttige som stoslashttelitteratur

Laeligringsmaringl

[F1] Forstaring ideen om en delinstansgraf [F2] Forstaring designmetoden dynamisk programmering [F3] Forstaring loslashsning ved memoisering (top-down)

[F4] Forstaring loslashsning ved iterasjon (bottom-up)[F5] Forstaring hvordan man rekonstruerer en loslashsning fra lagrede beslutninger[F6] Forstaring hva optimal delstruktur er[F7] Forstaring hva overlappende delinstanser er[F8] Forstaring eksemplene stavkutting og LCS[F9] Forstaring loslashsningen paring det binaeligre ryggsekkproblemet (se appendiks D i dette

heftet)(Knapsack Knapsackprime)

Merk Noe av stoffet vil kanskje forskyves til forelesning 7

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

7

Forelesning 7

Graringdige algoritmer

Graringdige algoritmer bestaringr av en serie med valg og hvert valg tas lokalt Algorit-men gjoslashr alltid det som ser best ut her og naring uten noe stoslashrre perspektiv Slikealgoritmer er ofte enkle utfordringen ligger i aring finne ut om de gir rett svar

Pensum

Kap 16 Greedy algorithms Innledning og 161ndash163

Laeligringsmaringl

[G1] Forstaring designmetoden graringdighet [G2] Forstaring graringdighetsegenskapen (the greedy-choice property)

[G3] Forstaring eksemplene aktivitet-utvelgelse og det kontinuerlige ryggsekkproblemet[G4] Forstaring Huffman og Huffman-koder

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

8

Forelesning 8

Traversering av grafer

Vi traverserer en graf ved aring besoslashke noder vi vet om Vi vet i utgangspunktet bareom startnoden men oppdager naboene til dem vi besoslashker Traversering er viktig iseg selv men danner ogsaring ryggraden til flere mer avanserte algoritmer

Pensum

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Appendiks E i dette heftet

Laeligringsmaringl

[H1] Forstaring hvordan grafer kan implementeres[H2] Forstaring BFS ogsaring for aring finne korteste vei uten vekter[H3] Forstaring DFS og parentesteoremet[H4] Forstaring hvordan DFS klassifiserer kanter[H5] Forstaring Topological-Sort[H6] Forstaring hvordan DFS kan implementeres med en stakk[H7] Forstaring hva traverseringstraeligr (som bredde-foslashrst- og dybde-foslashrst-traeligr) er

[H8] Forstaring traversering med vilkaringrlig prioritetskoslash

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

9

Forelesning 9

Minimale spenntraeligr

Her har vi en graf med vekter paring kantene og oslashnsker aring bare beholde akkurat dekantene vi maring for aring koble sammen alle nodene med en saring lav vektsum som muligErke-eksempel paring graringdighet Velg eacuten og eacuten kant alltid den billigste lovlige

Pensum

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 23 Minimum spanning trees

Laeligringsmaringl

[I1] Forstaring skog-implementasjonen av disjunkte mengder(Connected-Components Same-Component Make-Set Union Link Find-Set)

[I2] Vite hva spenntraeligr og minimale spenntraeligr er [I3] Forstaring Generic-MST

[I4] Forstaring hvorfor lette kanter er trygge kanter[I5] Forstaring MST-Kruskal[I6] Forstaring MST-Prim

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

10

Forelesning 10

Korteste vei fra eacuten til alle

Bredde-foslashrst-soslashk kan finne stier med faeligrrest mulig kanter men hva om kantenehar ulik lengde Det generelle problemet er uloslashst men vi kan loslashse problemet medgradvis bedre kjoslashretid for grafer (1) uten negative sykler (2) uten negative kanterog (3) uten sykler Og vi bruker samme prinsipp for alle tre

Pensum

Kap 24 Single-source shortest paths Innledning og 241ndash243

Laeligringsmaringl

[J1] Forstaring ulike varianter av korteste-vei- eller korteste-sti-problemet(Single-source single-destination single-pair all-pairs)

[J2] Forstaring strukturen til korteste-vei-problemet[J3] Forstaring at negative sykler gir mening for korteste enkle vei (simple path)[J4] Forstaring at korteste enkle vei kan loslashses vha lengste enkle vei og omvendt[J5] Forstaring hvordan man kan representere et korteste-vei-tre

[J6] Forstaring kant-slakking (edge relaxation) og Relax[J7] Forstaring ulike egenskaper ved korteste veier og slakking

(Triangle inequality upper-bound property no-path property convergence property path-relaxation property predecessor-subgraph property)

[J8] Forstaring Bellman-Ford[J9] Forstaring DAG-Shortest-Path

[J10] Forstaring kobling mellom DAG-Shortest-Path og dynamisk programmering[J11] Forstaring Dijkstra

Merk Noe av stoffet vil kanskje forskyves til forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

11

Forelesning 11

Korteste vei fra alle til alle

Vi kan finne de korteste veiene fra hver node etter tur men mange av delinstanse-ne vil overlappe ndash om vi har mange nok kanter loslashnner det seg aring bruke dynamiskprogrammering med dekomponeringen laquoSkal vi innom k eller ikkeraquo

Pensum

Kap 25 All-pairs shortest paths Innledning 252 og 253

Laeligringsmaringl

[K1] Forstaring forgjengerstrukturen for alle-til-alle-varianten av korteste vei-problemet(Print-All-Pairs-Shortest-Path)

[K2] Forstaring Floyd-Warshall[K3] Forstaring Transitive-Closure[K4] Forstaring Johnson

Merk Noe stoff fra forelesning 12 vil kanskje dekkes her

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

12

Forelesning 12

Maksimal flyt

Et stort skritt i retning av generell lineaeligr optimering (saringkalt lineaeligr programme-ring) Her ser vi paring to tilsynelatende forskjellige problemer som viser seg aring vaeligreduale av hverandre noe som hjelper oss med aring finne en loslashsning

Pensum

Kap 26 Maximum flow Innledning og 261ndash263

Laeligringsmaringl

[L1] Kunne definere flytnett flyt og maks-flyt-problemet[L2] Kunne haringndtere antiparallelle kanter og flere kilder og sluk

[L3] Kunne definere restnettet til et flytnett med en gitt flyt[L4] Forstaring hvordan man kan oppheve (cancel) flyt[L5] Forstaring hva en foroslashkende sti (augmenting path) er[L6] Forstaring hva snitt snitt-kapasitet og minimalt snitt er

[L7] Forstaring maks-flytmin-snitt-teoremet[L8] Forstaring Ford-Fulkerson-Method og Ford-Fulkerson[L9] Vite at Ford-Fulkerson med BFS kalles Edmonds-Karp-algoritmen[L10] Forstaring hvordan maks-flyt kan finne en maksimum bipartitt matching

[L11] Forstaring heltallsteoremet (integrality theorem)

Merk Noe av stoffet vil kanskje dekkes i forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

13

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 11: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Forelesning 3

Splitt og hersk

Rekursiv dekomponering er kanskje den viktigste ideen i hele faget og designmeto-den splitt og hersk er en grunnleggende utgave av det Del instansen i mindre biterloslashs problemet rekursivt for disse og kombineacuter loslashsningene

Pensum

Kap 2 Getting started 23

Kap 4 Divide-and-conquer Innledning 41 og 43ndash45

Kap 7 Quicksort

Oppgaver 23-5 og 45-3 med loslashsning (binaeligrsoslashk)

Appendiks B og C i dette heftet

Laeligringsmaringl

[C1] Forstaring designmetoden divide-and-conquer (splitt og hersk)[C2] Forstaring maximum-subarray-problemet med loslashsninger[C3] Forstaring Bisect og Bisectprime (se appendiks C i dette heftet)[C4] Forstaring Merge-Sort[C5] Forstaring Quicksort og Randomized-Quicksort

[C6] Kunne loslashse rekurrenser med substitusjon rekursjonstraeligr og masterteoremet [C7] Kunne loslashse rekurrenser med iterasjonsmetoden (se appendiks B i dette heftet)

[C8] Forstaring hvordan variabelskifte fungerer

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

4

Forelesning 4

Rangering i lineaeligr tid

Vi kan ofte faring bedre loslashsninger ved aring styrke kravene til input eller ved aring svekkekravene til output Sortering basert paring sammenligninger (x 6 y) er et klassiskeksempel I verste tilfelle maring vi bruke lg n sammenligningermen om vi antar merom elementene eller bare sorterer noen av dem saring kan vi gjoslashre det bedre

Pensum

Kap 8 Sorting in linear time

Kap 9 Medians and order statistics

Laeligringsmaringl

[D1] Forstaring hvorfor sammenligningsbasert sortering har en worst-case paring Ω(n lg n)[D2] Vite hva en stabil sorteringsalgoritme er[D3] Forstaring Counting-Sort og hvorfor den er stabil

[D4] Forstaring Radix-Sort og hvorfor den trenger en stabil subrutine[D5] Forstaring Bucket-Sort[D6] Forstaring Randomized-Select[D7] Kjenne til Select

Merk Det kreves ikke grundig forstaringelse av virkemaringten til Select

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

5

Forelesning 5

Rotfaste trestrukturer

Rotfaste traeligr gjenspeiler rekursiv dekomponering I binaeligre soslashketraeligr er alt i venst-re deltre mindre enn rota mens alt i hoslashyre deltre er stoslashrre og det gjelder rekursivtfor alle deltraeligr Hauger er enklere Alt er mindre enn rota Det begrenser funksjo-naliteten men gjoslashr dem billigere aring bygge og balansere

Pensum

Kap 6 Heapsort

Kap 10 Elementary data structures 104

Kap 12 Binary search trees Innledning og 121ndash123

Laeligringsmaringl

[E1] Forstaring hvordan heaps fungerer og hvordan de kan brukes som prioritetskoslasher(Parent Left Right Max-Heapify Build-Max-Heap Heapsort Max-Heap-InsertHeap-Extract-Max Heap-Increase-Key Heap-Maximum Ogsaring tilsvarende for min-heaps feks Build-Min-Heap og Heap-Extract-Min)

[E2] Forstaring Heapsort[E3] Forstaring hvordan rotfaste traeligr kan implementeres

[E4] Forstaring hvordan binaeligre soslashketraeligr fungerer(Inorder-Tree-Walk Tree-Search Iterative-Tree-Search Tree-Minimum Tree-Maximum Tree-Successor Tree-Predecessor Tree-Insert Transplant Tree-Delete)

[E5] Vite at forventet hoslashyde for et tilfeldig binaeligrt soslashketre er Θ(lg n)[E6] Vite at det finnes soslashketraeligr med garantert hoslashyde paring Θ(lg n)

Merk Det kreves ikke grundig forstaringelse av Transplant og Tree-Delete

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

6

Forelesning 6

Dynamisk programmering

Paring sett og vis en generalisering av splitt og hersk der delprobler kan overlappe Istedet for et tre av delinstans-avhengigheter har vi en rettet asyklisk graf Vi finnerog lagrer del-loslashsninger i en rekkefoslashlge som stemmer med avhengighetene

Pensum

Kap 15 Dynamic programming Innledning og 151 153ndash154

Oppgave 162-2 med loslashsning (0-1 knapsack)

Appendiks D i dette heftet

Delkapitler 152 og 155 kan vaeligre nyttige som stoslashttelitteratur

Laeligringsmaringl

[F1] Forstaring ideen om en delinstansgraf [F2] Forstaring designmetoden dynamisk programmering [F3] Forstaring loslashsning ved memoisering (top-down)

[F4] Forstaring loslashsning ved iterasjon (bottom-up)[F5] Forstaring hvordan man rekonstruerer en loslashsning fra lagrede beslutninger[F6] Forstaring hva optimal delstruktur er[F7] Forstaring hva overlappende delinstanser er[F8] Forstaring eksemplene stavkutting og LCS[F9] Forstaring loslashsningen paring det binaeligre ryggsekkproblemet (se appendiks D i dette

heftet)(Knapsack Knapsackprime)

Merk Noe av stoffet vil kanskje forskyves til forelesning 7

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

7

Forelesning 7

Graringdige algoritmer

Graringdige algoritmer bestaringr av en serie med valg og hvert valg tas lokalt Algorit-men gjoslashr alltid det som ser best ut her og naring uten noe stoslashrre perspektiv Slikealgoritmer er ofte enkle utfordringen ligger i aring finne ut om de gir rett svar

Pensum

Kap 16 Greedy algorithms Innledning og 161ndash163

Laeligringsmaringl

[G1] Forstaring designmetoden graringdighet [G2] Forstaring graringdighetsegenskapen (the greedy-choice property)

[G3] Forstaring eksemplene aktivitet-utvelgelse og det kontinuerlige ryggsekkproblemet[G4] Forstaring Huffman og Huffman-koder

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

8

Forelesning 8

Traversering av grafer

Vi traverserer en graf ved aring besoslashke noder vi vet om Vi vet i utgangspunktet bareom startnoden men oppdager naboene til dem vi besoslashker Traversering er viktig iseg selv men danner ogsaring ryggraden til flere mer avanserte algoritmer

Pensum

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Appendiks E i dette heftet

Laeligringsmaringl

[H1] Forstaring hvordan grafer kan implementeres[H2] Forstaring BFS ogsaring for aring finne korteste vei uten vekter[H3] Forstaring DFS og parentesteoremet[H4] Forstaring hvordan DFS klassifiserer kanter[H5] Forstaring Topological-Sort[H6] Forstaring hvordan DFS kan implementeres med en stakk[H7] Forstaring hva traverseringstraeligr (som bredde-foslashrst- og dybde-foslashrst-traeligr) er

[H8] Forstaring traversering med vilkaringrlig prioritetskoslash

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

9

Forelesning 9

Minimale spenntraeligr

Her har vi en graf med vekter paring kantene og oslashnsker aring bare beholde akkurat dekantene vi maring for aring koble sammen alle nodene med en saring lav vektsum som muligErke-eksempel paring graringdighet Velg eacuten og eacuten kant alltid den billigste lovlige

Pensum

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 23 Minimum spanning trees

Laeligringsmaringl

[I1] Forstaring skog-implementasjonen av disjunkte mengder(Connected-Components Same-Component Make-Set Union Link Find-Set)

[I2] Vite hva spenntraeligr og minimale spenntraeligr er [I3] Forstaring Generic-MST

[I4] Forstaring hvorfor lette kanter er trygge kanter[I5] Forstaring MST-Kruskal[I6] Forstaring MST-Prim

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

10

Forelesning 10

Korteste vei fra eacuten til alle

Bredde-foslashrst-soslashk kan finne stier med faeligrrest mulig kanter men hva om kantenehar ulik lengde Det generelle problemet er uloslashst men vi kan loslashse problemet medgradvis bedre kjoslashretid for grafer (1) uten negative sykler (2) uten negative kanterog (3) uten sykler Og vi bruker samme prinsipp for alle tre

Pensum

Kap 24 Single-source shortest paths Innledning og 241ndash243

Laeligringsmaringl

[J1] Forstaring ulike varianter av korteste-vei- eller korteste-sti-problemet(Single-source single-destination single-pair all-pairs)

[J2] Forstaring strukturen til korteste-vei-problemet[J3] Forstaring at negative sykler gir mening for korteste enkle vei (simple path)[J4] Forstaring at korteste enkle vei kan loslashses vha lengste enkle vei og omvendt[J5] Forstaring hvordan man kan representere et korteste-vei-tre

[J6] Forstaring kant-slakking (edge relaxation) og Relax[J7] Forstaring ulike egenskaper ved korteste veier og slakking

(Triangle inequality upper-bound property no-path property convergence property path-relaxation property predecessor-subgraph property)

[J8] Forstaring Bellman-Ford[J9] Forstaring DAG-Shortest-Path

[J10] Forstaring kobling mellom DAG-Shortest-Path og dynamisk programmering[J11] Forstaring Dijkstra

Merk Noe av stoffet vil kanskje forskyves til forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

11

Forelesning 11

Korteste vei fra alle til alle

Vi kan finne de korteste veiene fra hver node etter tur men mange av delinstanse-ne vil overlappe ndash om vi har mange nok kanter loslashnner det seg aring bruke dynamiskprogrammering med dekomponeringen laquoSkal vi innom k eller ikkeraquo

Pensum

Kap 25 All-pairs shortest paths Innledning 252 og 253

Laeligringsmaringl

[K1] Forstaring forgjengerstrukturen for alle-til-alle-varianten av korteste vei-problemet(Print-All-Pairs-Shortest-Path)

[K2] Forstaring Floyd-Warshall[K3] Forstaring Transitive-Closure[K4] Forstaring Johnson

Merk Noe stoff fra forelesning 12 vil kanskje dekkes her

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

12

Forelesning 12

Maksimal flyt

Et stort skritt i retning av generell lineaeligr optimering (saringkalt lineaeligr programme-ring) Her ser vi paring to tilsynelatende forskjellige problemer som viser seg aring vaeligreduale av hverandre noe som hjelper oss med aring finne en loslashsning

Pensum

Kap 26 Maximum flow Innledning og 261ndash263

Laeligringsmaringl

[L1] Kunne definere flytnett flyt og maks-flyt-problemet[L2] Kunne haringndtere antiparallelle kanter og flere kilder og sluk

[L3] Kunne definere restnettet til et flytnett med en gitt flyt[L4] Forstaring hvordan man kan oppheve (cancel) flyt[L5] Forstaring hva en foroslashkende sti (augmenting path) er[L6] Forstaring hva snitt snitt-kapasitet og minimalt snitt er

[L7] Forstaring maks-flytmin-snitt-teoremet[L8] Forstaring Ford-Fulkerson-Method og Ford-Fulkerson[L9] Vite at Ford-Fulkerson med BFS kalles Edmonds-Karp-algoritmen[L10] Forstaring hvordan maks-flyt kan finne en maksimum bipartitt matching

[L11] Forstaring heltallsteoremet (integrality theorem)

Merk Noe av stoffet vil kanskje dekkes i forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

13

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 12: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Forelesning 4

Rangering i lineaeligr tid

Vi kan ofte faring bedre loslashsninger ved aring styrke kravene til input eller ved aring svekkekravene til output Sortering basert paring sammenligninger (x 6 y) er et klassiskeksempel I verste tilfelle maring vi bruke lg n sammenligningermen om vi antar merom elementene eller bare sorterer noen av dem saring kan vi gjoslashre det bedre

Pensum

Kap 8 Sorting in linear time

Kap 9 Medians and order statistics

Laeligringsmaringl

[D1] Forstaring hvorfor sammenligningsbasert sortering har en worst-case paring Ω(n lg n)[D2] Vite hva en stabil sorteringsalgoritme er[D3] Forstaring Counting-Sort og hvorfor den er stabil

[D4] Forstaring Radix-Sort og hvorfor den trenger en stabil subrutine[D5] Forstaring Bucket-Sort[D6] Forstaring Randomized-Select[D7] Kjenne til Select

Merk Det kreves ikke grundig forstaringelse av virkemaringten til Select

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

5

Forelesning 5

Rotfaste trestrukturer

Rotfaste traeligr gjenspeiler rekursiv dekomponering I binaeligre soslashketraeligr er alt i venst-re deltre mindre enn rota mens alt i hoslashyre deltre er stoslashrre og det gjelder rekursivtfor alle deltraeligr Hauger er enklere Alt er mindre enn rota Det begrenser funksjo-naliteten men gjoslashr dem billigere aring bygge og balansere

Pensum

Kap 6 Heapsort

Kap 10 Elementary data structures 104

Kap 12 Binary search trees Innledning og 121ndash123

Laeligringsmaringl

[E1] Forstaring hvordan heaps fungerer og hvordan de kan brukes som prioritetskoslasher(Parent Left Right Max-Heapify Build-Max-Heap Heapsort Max-Heap-InsertHeap-Extract-Max Heap-Increase-Key Heap-Maximum Ogsaring tilsvarende for min-heaps feks Build-Min-Heap og Heap-Extract-Min)

[E2] Forstaring Heapsort[E3] Forstaring hvordan rotfaste traeligr kan implementeres

[E4] Forstaring hvordan binaeligre soslashketraeligr fungerer(Inorder-Tree-Walk Tree-Search Iterative-Tree-Search Tree-Minimum Tree-Maximum Tree-Successor Tree-Predecessor Tree-Insert Transplant Tree-Delete)

[E5] Vite at forventet hoslashyde for et tilfeldig binaeligrt soslashketre er Θ(lg n)[E6] Vite at det finnes soslashketraeligr med garantert hoslashyde paring Θ(lg n)

Merk Det kreves ikke grundig forstaringelse av Transplant og Tree-Delete

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

6

Forelesning 6

Dynamisk programmering

Paring sett og vis en generalisering av splitt og hersk der delprobler kan overlappe Istedet for et tre av delinstans-avhengigheter har vi en rettet asyklisk graf Vi finnerog lagrer del-loslashsninger i en rekkefoslashlge som stemmer med avhengighetene

Pensum

Kap 15 Dynamic programming Innledning og 151 153ndash154

Oppgave 162-2 med loslashsning (0-1 knapsack)

Appendiks D i dette heftet

Delkapitler 152 og 155 kan vaeligre nyttige som stoslashttelitteratur

Laeligringsmaringl

[F1] Forstaring ideen om en delinstansgraf [F2] Forstaring designmetoden dynamisk programmering [F3] Forstaring loslashsning ved memoisering (top-down)

[F4] Forstaring loslashsning ved iterasjon (bottom-up)[F5] Forstaring hvordan man rekonstruerer en loslashsning fra lagrede beslutninger[F6] Forstaring hva optimal delstruktur er[F7] Forstaring hva overlappende delinstanser er[F8] Forstaring eksemplene stavkutting og LCS[F9] Forstaring loslashsningen paring det binaeligre ryggsekkproblemet (se appendiks D i dette

heftet)(Knapsack Knapsackprime)

Merk Noe av stoffet vil kanskje forskyves til forelesning 7

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

7

Forelesning 7

Graringdige algoritmer

Graringdige algoritmer bestaringr av en serie med valg og hvert valg tas lokalt Algorit-men gjoslashr alltid det som ser best ut her og naring uten noe stoslashrre perspektiv Slikealgoritmer er ofte enkle utfordringen ligger i aring finne ut om de gir rett svar

Pensum

Kap 16 Greedy algorithms Innledning og 161ndash163

Laeligringsmaringl

[G1] Forstaring designmetoden graringdighet [G2] Forstaring graringdighetsegenskapen (the greedy-choice property)

[G3] Forstaring eksemplene aktivitet-utvelgelse og det kontinuerlige ryggsekkproblemet[G4] Forstaring Huffman og Huffman-koder

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

8

Forelesning 8

Traversering av grafer

Vi traverserer en graf ved aring besoslashke noder vi vet om Vi vet i utgangspunktet bareom startnoden men oppdager naboene til dem vi besoslashker Traversering er viktig iseg selv men danner ogsaring ryggraden til flere mer avanserte algoritmer

Pensum

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Appendiks E i dette heftet

Laeligringsmaringl

[H1] Forstaring hvordan grafer kan implementeres[H2] Forstaring BFS ogsaring for aring finne korteste vei uten vekter[H3] Forstaring DFS og parentesteoremet[H4] Forstaring hvordan DFS klassifiserer kanter[H5] Forstaring Topological-Sort[H6] Forstaring hvordan DFS kan implementeres med en stakk[H7] Forstaring hva traverseringstraeligr (som bredde-foslashrst- og dybde-foslashrst-traeligr) er

[H8] Forstaring traversering med vilkaringrlig prioritetskoslash

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

9

Forelesning 9

Minimale spenntraeligr

Her har vi en graf med vekter paring kantene og oslashnsker aring bare beholde akkurat dekantene vi maring for aring koble sammen alle nodene med en saring lav vektsum som muligErke-eksempel paring graringdighet Velg eacuten og eacuten kant alltid den billigste lovlige

Pensum

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 23 Minimum spanning trees

Laeligringsmaringl

[I1] Forstaring skog-implementasjonen av disjunkte mengder(Connected-Components Same-Component Make-Set Union Link Find-Set)

[I2] Vite hva spenntraeligr og minimale spenntraeligr er [I3] Forstaring Generic-MST

[I4] Forstaring hvorfor lette kanter er trygge kanter[I5] Forstaring MST-Kruskal[I6] Forstaring MST-Prim

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

10

Forelesning 10

Korteste vei fra eacuten til alle

Bredde-foslashrst-soslashk kan finne stier med faeligrrest mulig kanter men hva om kantenehar ulik lengde Det generelle problemet er uloslashst men vi kan loslashse problemet medgradvis bedre kjoslashretid for grafer (1) uten negative sykler (2) uten negative kanterog (3) uten sykler Og vi bruker samme prinsipp for alle tre

Pensum

Kap 24 Single-source shortest paths Innledning og 241ndash243

Laeligringsmaringl

[J1] Forstaring ulike varianter av korteste-vei- eller korteste-sti-problemet(Single-source single-destination single-pair all-pairs)

[J2] Forstaring strukturen til korteste-vei-problemet[J3] Forstaring at negative sykler gir mening for korteste enkle vei (simple path)[J4] Forstaring at korteste enkle vei kan loslashses vha lengste enkle vei og omvendt[J5] Forstaring hvordan man kan representere et korteste-vei-tre

[J6] Forstaring kant-slakking (edge relaxation) og Relax[J7] Forstaring ulike egenskaper ved korteste veier og slakking

(Triangle inequality upper-bound property no-path property convergence property path-relaxation property predecessor-subgraph property)

[J8] Forstaring Bellman-Ford[J9] Forstaring DAG-Shortest-Path

[J10] Forstaring kobling mellom DAG-Shortest-Path og dynamisk programmering[J11] Forstaring Dijkstra

Merk Noe av stoffet vil kanskje forskyves til forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

11

Forelesning 11

Korteste vei fra alle til alle

Vi kan finne de korteste veiene fra hver node etter tur men mange av delinstanse-ne vil overlappe ndash om vi har mange nok kanter loslashnner det seg aring bruke dynamiskprogrammering med dekomponeringen laquoSkal vi innom k eller ikkeraquo

Pensum

Kap 25 All-pairs shortest paths Innledning 252 og 253

Laeligringsmaringl

[K1] Forstaring forgjengerstrukturen for alle-til-alle-varianten av korteste vei-problemet(Print-All-Pairs-Shortest-Path)

[K2] Forstaring Floyd-Warshall[K3] Forstaring Transitive-Closure[K4] Forstaring Johnson

Merk Noe stoff fra forelesning 12 vil kanskje dekkes her

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

12

Forelesning 12

Maksimal flyt

Et stort skritt i retning av generell lineaeligr optimering (saringkalt lineaeligr programme-ring) Her ser vi paring to tilsynelatende forskjellige problemer som viser seg aring vaeligreduale av hverandre noe som hjelper oss med aring finne en loslashsning

Pensum

Kap 26 Maximum flow Innledning og 261ndash263

Laeligringsmaringl

[L1] Kunne definere flytnett flyt og maks-flyt-problemet[L2] Kunne haringndtere antiparallelle kanter og flere kilder og sluk

[L3] Kunne definere restnettet til et flytnett med en gitt flyt[L4] Forstaring hvordan man kan oppheve (cancel) flyt[L5] Forstaring hva en foroslashkende sti (augmenting path) er[L6] Forstaring hva snitt snitt-kapasitet og minimalt snitt er

[L7] Forstaring maks-flytmin-snitt-teoremet[L8] Forstaring Ford-Fulkerson-Method og Ford-Fulkerson[L9] Vite at Ford-Fulkerson med BFS kalles Edmonds-Karp-algoritmen[L10] Forstaring hvordan maks-flyt kan finne en maksimum bipartitt matching

[L11] Forstaring heltallsteoremet (integrality theorem)

Merk Noe av stoffet vil kanskje dekkes i forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

13

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 13: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Forelesning 5

Rotfaste trestrukturer

Rotfaste traeligr gjenspeiler rekursiv dekomponering I binaeligre soslashketraeligr er alt i venst-re deltre mindre enn rota mens alt i hoslashyre deltre er stoslashrre og det gjelder rekursivtfor alle deltraeligr Hauger er enklere Alt er mindre enn rota Det begrenser funksjo-naliteten men gjoslashr dem billigere aring bygge og balansere

Pensum

Kap 6 Heapsort

Kap 10 Elementary data structures 104

Kap 12 Binary search trees Innledning og 121ndash123

Laeligringsmaringl

[E1] Forstaring hvordan heaps fungerer og hvordan de kan brukes som prioritetskoslasher(Parent Left Right Max-Heapify Build-Max-Heap Heapsort Max-Heap-InsertHeap-Extract-Max Heap-Increase-Key Heap-Maximum Ogsaring tilsvarende for min-heaps feks Build-Min-Heap og Heap-Extract-Min)

[E2] Forstaring Heapsort[E3] Forstaring hvordan rotfaste traeligr kan implementeres

[E4] Forstaring hvordan binaeligre soslashketraeligr fungerer(Inorder-Tree-Walk Tree-Search Iterative-Tree-Search Tree-Minimum Tree-Maximum Tree-Successor Tree-Predecessor Tree-Insert Transplant Tree-Delete)

[E5] Vite at forventet hoslashyde for et tilfeldig binaeligrt soslashketre er Θ(lg n)[E6] Vite at det finnes soslashketraeligr med garantert hoslashyde paring Θ(lg n)

Merk Det kreves ikke grundig forstaringelse av Transplant og Tree-Delete

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

6

Forelesning 6

Dynamisk programmering

Paring sett og vis en generalisering av splitt og hersk der delprobler kan overlappe Istedet for et tre av delinstans-avhengigheter har vi en rettet asyklisk graf Vi finnerog lagrer del-loslashsninger i en rekkefoslashlge som stemmer med avhengighetene

Pensum

Kap 15 Dynamic programming Innledning og 151 153ndash154

Oppgave 162-2 med loslashsning (0-1 knapsack)

Appendiks D i dette heftet

Delkapitler 152 og 155 kan vaeligre nyttige som stoslashttelitteratur

Laeligringsmaringl

[F1] Forstaring ideen om en delinstansgraf [F2] Forstaring designmetoden dynamisk programmering [F3] Forstaring loslashsning ved memoisering (top-down)

[F4] Forstaring loslashsning ved iterasjon (bottom-up)[F5] Forstaring hvordan man rekonstruerer en loslashsning fra lagrede beslutninger[F6] Forstaring hva optimal delstruktur er[F7] Forstaring hva overlappende delinstanser er[F8] Forstaring eksemplene stavkutting og LCS[F9] Forstaring loslashsningen paring det binaeligre ryggsekkproblemet (se appendiks D i dette

heftet)(Knapsack Knapsackprime)

Merk Noe av stoffet vil kanskje forskyves til forelesning 7

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

7

Forelesning 7

Graringdige algoritmer

Graringdige algoritmer bestaringr av en serie med valg og hvert valg tas lokalt Algorit-men gjoslashr alltid det som ser best ut her og naring uten noe stoslashrre perspektiv Slikealgoritmer er ofte enkle utfordringen ligger i aring finne ut om de gir rett svar

Pensum

Kap 16 Greedy algorithms Innledning og 161ndash163

Laeligringsmaringl

[G1] Forstaring designmetoden graringdighet [G2] Forstaring graringdighetsegenskapen (the greedy-choice property)

[G3] Forstaring eksemplene aktivitet-utvelgelse og det kontinuerlige ryggsekkproblemet[G4] Forstaring Huffman og Huffman-koder

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

8

Forelesning 8

Traversering av grafer

Vi traverserer en graf ved aring besoslashke noder vi vet om Vi vet i utgangspunktet bareom startnoden men oppdager naboene til dem vi besoslashker Traversering er viktig iseg selv men danner ogsaring ryggraden til flere mer avanserte algoritmer

Pensum

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Appendiks E i dette heftet

Laeligringsmaringl

[H1] Forstaring hvordan grafer kan implementeres[H2] Forstaring BFS ogsaring for aring finne korteste vei uten vekter[H3] Forstaring DFS og parentesteoremet[H4] Forstaring hvordan DFS klassifiserer kanter[H5] Forstaring Topological-Sort[H6] Forstaring hvordan DFS kan implementeres med en stakk[H7] Forstaring hva traverseringstraeligr (som bredde-foslashrst- og dybde-foslashrst-traeligr) er

[H8] Forstaring traversering med vilkaringrlig prioritetskoslash

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

9

Forelesning 9

Minimale spenntraeligr

Her har vi en graf med vekter paring kantene og oslashnsker aring bare beholde akkurat dekantene vi maring for aring koble sammen alle nodene med en saring lav vektsum som muligErke-eksempel paring graringdighet Velg eacuten og eacuten kant alltid den billigste lovlige

Pensum

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 23 Minimum spanning trees

Laeligringsmaringl

[I1] Forstaring skog-implementasjonen av disjunkte mengder(Connected-Components Same-Component Make-Set Union Link Find-Set)

[I2] Vite hva spenntraeligr og minimale spenntraeligr er [I3] Forstaring Generic-MST

[I4] Forstaring hvorfor lette kanter er trygge kanter[I5] Forstaring MST-Kruskal[I6] Forstaring MST-Prim

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

10

Forelesning 10

Korteste vei fra eacuten til alle

Bredde-foslashrst-soslashk kan finne stier med faeligrrest mulig kanter men hva om kantenehar ulik lengde Det generelle problemet er uloslashst men vi kan loslashse problemet medgradvis bedre kjoslashretid for grafer (1) uten negative sykler (2) uten negative kanterog (3) uten sykler Og vi bruker samme prinsipp for alle tre

Pensum

Kap 24 Single-source shortest paths Innledning og 241ndash243

Laeligringsmaringl

[J1] Forstaring ulike varianter av korteste-vei- eller korteste-sti-problemet(Single-source single-destination single-pair all-pairs)

[J2] Forstaring strukturen til korteste-vei-problemet[J3] Forstaring at negative sykler gir mening for korteste enkle vei (simple path)[J4] Forstaring at korteste enkle vei kan loslashses vha lengste enkle vei og omvendt[J5] Forstaring hvordan man kan representere et korteste-vei-tre

[J6] Forstaring kant-slakking (edge relaxation) og Relax[J7] Forstaring ulike egenskaper ved korteste veier og slakking

(Triangle inequality upper-bound property no-path property convergence property path-relaxation property predecessor-subgraph property)

[J8] Forstaring Bellman-Ford[J9] Forstaring DAG-Shortest-Path

[J10] Forstaring kobling mellom DAG-Shortest-Path og dynamisk programmering[J11] Forstaring Dijkstra

Merk Noe av stoffet vil kanskje forskyves til forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

11

Forelesning 11

Korteste vei fra alle til alle

Vi kan finne de korteste veiene fra hver node etter tur men mange av delinstanse-ne vil overlappe ndash om vi har mange nok kanter loslashnner det seg aring bruke dynamiskprogrammering med dekomponeringen laquoSkal vi innom k eller ikkeraquo

Pensum

Kap 25 All-pairs shortest paths Innledning 252 og 253

Laeligringsmaringl

[K1] Forstaring forgjengerstrukturen for alle-til-alle-varianten av korteste vei-problemet(Print-All-Pairs-Shortest-Path)

[K2] Forstaring Floyd-Warshall[K3] Forstaring Transitive-Closure[K4] Forstaring Johnson

Merk Noe stoff fra forelesning 12 vil kanskje dekkes her

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

12

Forelesning 12

Maksimal flyt

Et stort skritt i retning av generell lineaeligr optimering (saringkalt lineaeligr programme-ring) Her ser vi paring to tilsynelatende forskjellige problemer som viser seg aring vaeligreduale av hverandre noe som hjelper oss med aring finne en loslashsning

Pensum

Kap 26 Maximum flow Innledning og 261ndash263

Laeligringsmaringl

[L1] Kunne definere flytnett flyt og maks-flyt-problemet[L2] Kunne haringndtere antiparallelle kanter og flere kilder og sluk

[L3] Kunne definere restnettet til et flytnett med en gitt flyt[L4] Forstaring hvordan man kan oppheve (cancel) flyt[L5] Forstaring hva en foroslashkende sti (augmenting path) er[L6] Forstaring hva snitt snitt-kapasitet og minimalt snitt er

[L7] Forstaring maks-flytmin-snitt-teoremet[L8] Forstaring Ford-Fulkerson-Method og Ford-Fulkerson[L9] Vite at Ford-Fulkerson med BFS kalles Edmonds-Karp-algoritmen[L10] Forstaring hvordan maks-flyt kan finne en maksimum bipartitt matching

[L11] Forstaring heltallsteoremet (integrality theorem)

Merk Noe av stoffet vil kanskje dekkes i forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

13

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 14: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Forelesning 6

Dynamisk programmering

Paring sett og vis en generalisering av splitt og hersk der delprobler kan overlappe Istedet for et tre av delinstans-avhengigheter har vi en rettet asyklisk graf Vi finnerog lagrer del-loslashsninger i en rekkefoslashlge som stemmer med avhengighetene

Pensum

Kap 15 Dynamic programming Innledning og 151 153ndash154

Oppgave 162-2 med loslashsning (0-1 knapsack)

Appendiks D i dette heftet

Delkapitler 152 og 155 kan vaeligre nyttige som stoslashttelitteratur

Laeligringsmaringl

[F1] Forstaring ideen om en delinstansgraf [F2] Forstaring designmetoden dynamisk programmering [F3] Forstaring loslashsning ved memoisering (top-down)

[F4] Forstaring loslashsning ved iterasjon (bottom-up)[F5] Forstaring hvordan man rekonstruerer en loslashsning fra lagrede beslutninger[F6] Forstaring hva optimal delstruktur er[F7] Forstaring hva overlappende delinstanser er[F8] Forstaring eksemplene stavkutting og LCS[F9] Forstaring loslashsningen paring det binaeligre ryggsekkproblemet (se appendiks D i dette

heftet)(Knapsack Knapsackprime)

Merk Noe av stoffet vil kanskje forskyves til forelesning 7

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

7

Forelesning 7

Graringdige algoritmer

Graringdige algoritmer bestaringr av en serie med valg og hvert valg tas lokalt Algorit-men gjoslashr alltid det som ser best ut her og naring uten noe stoslashrre perspektiv Slikealgoritmer er ofte enkle utfordringen ligger i aring finne ut om de gir rett svar

Pensum

Kap 16 Greedy algorithms Innledning og 161ndash163

Laeligringsmaringl

[G1] Forstaring designmetoden graringdighet [G2] Forstaring graringdighetsegenskapen (the greedy-choice property)

[G3] Forstaring eksemplene aktivitet-utvelgelse og det kontinuerlige ryggsekkproblemet[G4] Forstaring Huffman og Huffman-koder

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

8

Forelesning 8

Traversering av grafer

Vi traverserer en graf ved aring besoslashke noder vi vet om Vi vet i utgangspunktet bareom startnoden men oppdager naboene til dem vi besoslashker Traversering er viktig iseg selv men danner ogsaring ryggraden til flere mer avanserte algoritmer

Pensum

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Appendiks E i dette heftet

Laeligringsmaringl

[H1] Forstaring hvordan grafer kan implementeres[H2] Forstaring BFS ogsaring for aring finne korteste vei uten vekter[H3] Forstaring DFS og parentesteoremet[H4] Forstaring hvordan DFS klassifiserer kanter[H5] Forstaring Topological-Sort[H6] Forstaring hvordan DFS kan implementeres med en stakk[H7] Forstaring hva traverseringstraeligr (som bredde-foslashrst- og dybde-foslashrst-traeligr) er

[H8] Forstaring traversering med vilkaringrlig prioritetskoslash

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

9

Forelesning 9

Minimale spenntraeligr

Her har vi en graf med vekter paring kantene og oslashnsker aring bare beholde akkurat dekantene vi maring for aring koble sammen alle nodene med en saring lav vektsum som muligErke-eksempel paring graringdighet Velg eacuten og eacuten kant alltid den billigste lovlige

Pensum

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 23 Minimum spanning trees

Laeligringsmaringl

[I1] Forstaring skog-implementasjonen av disjunkte mengder(Connected-Components Same-Component Make-Set Union Link Find-Set)

[I2] Vite hva spenntraeligr og minimale spenntraeligr er [I3] Forstaring Generic-MST

[I4] Forstaring hvorfor lette kanter er trygge kanter[I5] Forstaring MST-Kruskal[I6] Forstaring MST-Prim

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

10

Forelesning 10

Korteste vei fra eacuten til alle

Bredde-foslashrst-soslashk kan finne stier med faeligrrest mulig kanter men hva om kantenehar ulik lengde Det generelle problemet er uloslashst men vi kan loslashse problemet medgradvis bedre kjoslashretid for grafer (1) uten negative sykler (2) uten negative kanterog (3) uten sykler Og vi bruker samme prinsipp for alle tre

Pensum

Kap 24 Single-source shortest paths Innledning og 241ndash243

Laeligringsmaringl

[J1] Forstaring ulike varianter av korteste-vei- eller korteste-sti-problemet(Single-source single-destination single-pair all-pairs)

[J2] Forstaring strukturen til korteste-vei-problemet[J3] Forstaring at negative sykler gir mening for korteste enkle vei (simple path)[J4] Forstaring at korteste enkle vei kan loslashses vha lengste enkle vei og omvendt[J5] Forstaring hvordan man kan representere et korteste-vei-tre

[J6] Forstaring kant-slakking (edge relaxation) og Relax[J7] Forstaring ulike egenskaper ved korteste veier og slakking

(Triangle inequality upper-bound property no-path property convergence property path-relaxation property predecessor-subgraph property)

[J8] Forstaring Bellman-Ford[J9] Forstaring DAG-Shortest-Path

[J10] Forstaring kobling mellom DAG-Shortest-Path og dynamisk programmering[J11] Forstaring Dijkstra

Merk Noe av stoffet vil kanskje forskyves til forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

11

Forelesning 11

Korteste vei fra alle til alle

Vi kan finne de korteste veiene fra hver node etter tur men mange av delinstanse-ne vil overlappe ndash om vi har mange nok kanter loslashnner det seg aring bruke dynamiskprogrammering med dekomponeringen laquoSkal vi innom k eller ikkeraquo

Pensum

Kap 25 All-pairs shortest paths Innledning 252 og 253

Laeligringsmaringl

[K1] Forstaring forgjengerstrukturen for alle-til-alle-varianten av korteste vei-problemet(Print-All-Pairs-Shortest-Path)

[K2] Forstaring Floyd-Warshall[K3] Forstaring Transitive-Closure[K4] Forstaring Johnson

Merk Noe stoff fra forelesning 12 vil kanskje dekkes her

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

12

Forelesning 12

Maksimal flyt

Et stort skritt i retning av generell lineaeligr optimering (saringkalt lineaeligr programme-ring) Her ser vi paring to tilsynelatende forskjellige problemer som viser seg aring vaeligreduale av hverandre noe som hjelper oss med aring finne en loslashsning

Pensum

Kap 26 Maximum flow Innledning og 261ndash263

Laeligringsmaringl

[L1] Kunne definere flytnett flyt og maks-flyt-problemet[L2] Kunne haringndtere antiparallelle kanter og flere kilder og sluk

[L3] Kunne definere restnettet til et flytnett med en gitt flyt[L4] Forstaring hvordan man kan oppheve (cancel) flyt[L5] Forstaring hva en foroslashkende sti (augmenting path) er[L6] Forstaring hva snitt snitt-kapasitet og minimalt snitt er

[L7] Forstaring maks-flytmin-snitt-teoremet[L8] Forstaring Ford-Fulkerson-Method og Ford-Fulkerson[L9] Vite at Ford-Fulkerson med BFS kalles Edmonds-Karp-algoritmen[L10] Forstaring hvordan maks-flyt kan finne en maksimum bipartitt matching

[L11] Forstaring heltallsteoremet (integrality theorem)

Merk Noe av stoffet vil kanskje dekkes i forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

13

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 15: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Forelesning 7

Graringdige algoritmer

Graringdige algoritmer bestaringr av en serie med valg og hvert valg tas lokalt Algorit-men gjoslashr alltid det som ser best ut her og naring uten noe stoslashrre perspektiv Slikealgoritmer er ofte enkle utfordringen ligger i aring finne ut om de gir rett svar

Pensum

Kap 16 Greedy algorithms Innledning og 161ndash163

Laeligringsmaringl

[G1] Forstaring designmetoden graringdighet [G2] Forstaring graringdighetsegenskapen (the greedy-choice property)

[G3] Forstaring eksemplene aktivitet-utvelgelse og det kontinuerlige ryggsekkproblemet[G4] Forstaring Huffman og Huffman-koder

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

8

Forelesning 8

Traversering av grafer

Vi traverserer en graf ved aring besoslashke noder vi vet om Vi vet i utgangspunktet bareom startnoden men oppdager naboene til dem vi besoslashker Traversering er viktig iseg selv men danner ogsaring ryggraden til flere mer avanserte algoritmer

Pensum

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Appendiks E i dette heftet

Laeligringsmaringl

[H1] Forstaring hvordan grafer kan implementeres[H2] Forstaring BFS ogsaring for aring finne korteste vei uten vekter[H3] Forstaring DFS og parentesteoremet[H4] Forstaring hvordan DFS klassifiserer kanter[H5] Forstaring Topological-Sort[H6] Forstaring hvordan DFS kan implementeres med en stakk[H7] Forstaring hva traverseringstraeligr (som bredde-foslashrst- og dybde-foslashrst-traeligr) er

[H8] Forstaring traversering med vilkaringrlig prioritetskoslash

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

9

Forelesning 9

Minimale spenntraeligr

Her har vi en graf med vekter paring kantene og oslashnsker aring bare beholde akkurat dekantene vi maring for aring koble sammen alle nodene med en saring lav vektsum som muligErke-eksempel paring graringdighet Velg eacuten og eacuten kant alltid den billigste lovlige

Pensum

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 23 Minimum spanning trees

Laeligringsmaringl

[I1] Forstaring skog-implementasjonen av disjunkte mengder(Connected-Components Same-Component Make-Set Union Link Find-Set)

[I2] Vite hva spenntraeligr og minimale spenntraeligr er [I3] Forstaring Generic-MST

[I4] Forstaring hvorfor lette kanter er trygge kanter[I5] Forstaring MST-Kruskal[I6] Forstaring MST-Prim

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

10

Forelesning 10

Korteste vei fra eacuten til alle

Bredde-foslashrst-soslashk kan finne stier med faeligrrest mulig kanter men hva om kantenehar ulik lengde Det generelle problemet er uloslashst men vi kan loslashse problemet medgradvis bedre kjoslashretid for grafer (1) uten negative sykler (2) uten negative kanterog (3) uten sykler Og vi bruker samme prinsipp for alle tre

Pensum

Kap 24 Single-source shortest paths Innledning og 241ndash243

Laeligringsmaringl

[J1] Forstaring ulike varianter av korteste-vei- eller korteste-sti-problemet(Single-source single-destination single-pair all-pairs)

[J2] Forstaring strukturen til korteste-vei-problemet[J3] Forstaring at negative sykler gir mening for korteste enkle vei (simple path)[J4] Forstaring at korteste enkle vei kan loslashses vha lengste enkle vei og omvendt[J5] Forstaring hvordan man kan representere et korteste-vei-tre

[J6] Forstaring kant-slakking (edge relaxation) og Relax[J7] Forstaring ulike egenskaper ved korteste veier og slakking

(Triangle inequality upper-bound property no-path property convergence property path-relaxation property predecessor-subgraph property)

[J8] Forstaring Bellman-Ford[J9] Forstaring DAG-Shortest-Path

[J10] Forstaring kobling mellom DAG-Shortest-Path og dynamisk programmering[J11] Forstaring Dijkstra

Merk Noe av stoffet vil kanskje forskyves til forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

11

Forelesning 11

Korteste vei fra alle til alle

Vi kan finne de korteste veiene fra hver node etter tur men mange av delinstanse-ne vil overlappe ndash om vi har mange nok kanter loslashnner det seg aring bruke dynamiskprogrammering med dekomponeringen laquoSkal vi innom k eller ikkeraquo

Pensum

Kap 25 All-pairs shortest paths Innledning 252 og 253

Laeligringsmaringl

[K1] Forstaring forgjengerstrukturen for alle-til-alle-varianten av korteste vei-problemet(Print-All-Pairs-Shortest-Path)

[K2] Forstaring Floyd-Warshall[K3] Forstaring Transitive-Closure[K4] Forstaring Johnson

Merk Noe stoff fra forelesning 12 vil kanskje dekkes her

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

12

Forelesning 12

Maksimal flyt

Et stort skritt i retning av generell lineaeligr optimering (saringkalt lineaeligr programme-ring) Her ser vi paring to tilsynelatende forskjellige problemer som viser seg aring vaeligreduale av hverandre noe som hjelper oss med aring finne en loslashsning

Pensum

Kap 26 Maximum flow Innledning og 261ndash263

Laeligringsmaringl

[L1] Kunne definere flytnett flyt og maks-flyt-problemet[L2] Kunne haringndtere antiparallelle kanter og flere kilder og sluk

[L3] Kunne definere restnettet til et flytnett med en gitt flyt[L4] Forstaring hvordan man kan oppheve (cancel) flyt[L5] Forstaring hva en foroslashkende sti (augmenting path) er[L6] Forstaring hva snitt snitt-kapasitet og minimalt snitt er

[L7] Forstaring maks-flytmin-snitt-teoremet[L8] Forstaring Ford-Fulkerson-Method og Ford-Fulkerson[L9] Vite at Ford-Fulkerson med BFS kalles Edmonds-Karp-algoritmen[L10] Forstaring hvordan maks-flyt kan finne en maksimum bipartitt matching

[L11] Forstaring heltallsteoremet (integrality theorem)

Merk Noe av stoffet vil kanskje dekkes i forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

13

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 16: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Forelesning 8

Traversering av grafer

Vi traverserer en graf ved aring besoslashke noder vi vet om Vi vet i utgangspunktet bareom startnoden men oppdager naboene til dem vi besoslashker Traversering er viktig iseg selv men danner ogsaring ryggraden til flere mer avanserte algoritmer

Pensum

Kap 22 Elementary graph algorithms Innledning og 221ndash224

Appendiks E i dette heftet

Laeligringsmaringl

[H1] Forstaring hvordan grafer kan implementeres[H2] Forstaring BFS ogsaring for aring finne korteste vei uten vekter[H3] Forstaring DFS og parentesteoremet[H4] Forstaring hvordan DFS klassifiserer kanter[H5] Forstaring Topological-Sort[H6] Forstaring hvordan DFS kan implementeres med en stakk[H7] Forstaring hva traverseringstraeligr (som bredde-foslashrst- og dybde-foslashrst-traeligr) er

[H8] Forstaring traversering med vilkaringrlig prioritetskoslash

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

9

Forelesning 9

Minimale spenntraeligr

Her har vi en graf med vekter paring kantene og oslashnsker aring bare beholde akkurat dekantene vi maring for aring koble sammen alle nodene med en saring lav vektsum som muligErke-eksempel paring graringdighet Velg eacuten og eacuten kant alltid den billigste lovlige

Pensum

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 23 Minimum spanning trees

Laeligringsmaringl

[I1] Forstaring skog-implementasjonen av disjunkte mengder(Connected-Components Same-Component Make-Set Union Link Find-Set)

[I2] Vite hva spenntraeligr og minimale spenntraeligr er [I3] Forstaring Generic-MST

[I4] Forstaring hvorfor lette kanter er trygge kanter[I5] Forstaring MST-Kruskal[I6] Forstaring MST-Prim

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

10

Forelesning 10

Korteste vei fra eacuten til alle

Bredde-foslashrst-soslashk kan finne stier med faeligrrest mulig kanter men hva om kantenehar ulik lengde Det generelle problemet er uloslashst men vi kan loslashse problemet medgradvis bedre kjoslashretid for grafer (1) uten negative sykler (2) uten negative kanterog (3) uten sykler Og vi bruker samme prinsipp for alle tre

Pensum

Kap 24 Single-source shortest paths Innledning og 241ndash243

Laeligringsmaringl

[J1] Forstaring ulike varianter av korteste-vei- eller korteste-sti-problemet(Single-source single-destination single-pair all-pairs)

[J2] Forstaring strukturen til korteste-vei-problemet[J3] Forstaring at negative sykler gir mening for korteste enkle vei (simple path)[J4] Forstaring at korteste enkle vei kan loslashses vha lengste enkle vei og omvendt[J5] Forstaring hvordan man kan representere et korteste-vei-tre

[J6] Forstaring kant-slakking (edge relaxation) og Relax[J7] Forstaring ulike egenskaper ved korteste veier og slakking

(Triangle inequality upper-bound property no-path property convergence property path-relaxation property predecessor-subgraph property)

[J8] Forstaring Bellman-Ford[J9] Forstaring DAG-Shortest-Path

[J10] Forstaring kobling mellom DAG-Shortest-Path og dynamisk programmering[J11] Forstaring Dijkstra

Merk Noe av stoffet vil kanskje forskyves til forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

11

Forelesning 11

Korteste vei fra alle til alle

Vi kan finne de korteste veiene fra hver node etter tur men mange av delinstanse-ne vil overlappe ndash om vi har mange nok kanter loslashnner det seg aring bruke dynamiskprogrammering med dekomponeringen laquoSkal vi innom k eller ikkeraquo

Pensum

Kap 25 All-pairs shortest paths Innledning 252 og 253

Laeligringsmaringl

[K1] Forstaring forgjengerstrukturen for alle-til-alle-varianten av korteste vei-problemet(Print-All-Pairs-Shortest-Path)

[K2] Forstaring Floyd-Warshall[K3] Forstaring Transitive-Closure[K4] Forstaring Johnson

Merk Noe stoff fra forelesning 12 vil kanskje dekkes her

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

12

Forelesning 12

Maksimal flyt

Et stort skritt i retning av generell lineaeligr optimering (saringkalt lineaeligr programme-ring) Her ser vi paring to tilsynelatende forskjellige problemer som viser seg aring vaeligreduale av hverandre noe som hjelper oss med aring finne en loslashsning

Pensum

Kap 26 Maximum flow Innledning og 261ndash263

Laeligringsmaringl

[L1] Kunne definere flytnett flyt og maks-flyt-problemet[L2] Kunne haringndtere antiparallelle kanter og flere kilder og sluk

[L3] Kunne definere restnettet til et flytnett med en gitt flyt[L4] Forstaring hvordan man kan oppheve (cancel) flyt[L5] Forstaring hva en foroslashkende sti (augmenting path) er[L6] Forstaring hva snitt snitt-kapasitet og minimalt snitt er

[L7] Forstaring maks-flytmin-snitt-teoremet[L8] Forstaring Ford-Fulkerson-Method og Ford-Fulkerson[L9] Vite at Ford-Fulkerson med BFS kalles Edmonds-Karp-algoritmen[L10] Forstaring hvordan maks-flyt kan finne en maksimum bipartitt matching

[L11] Forstaring heltallsteoremet (integrality theorem)

Merk Noe av stoffet vil kanskje dekkes i forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

13

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 17: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Forelesning 9

Minimale spenntraeligr

Her har vi en graf med vekter paring kantene og oslashnsker aring bare beholde akkurat dekantene vi maring for aring koble sammen alle nodene med en saring lav vektsum som muligErke-eksempel paring graringdighet Velg eacuten og eacuten kant alltid den billigste lovlige

Pensum

Kap 21 Data structures for disjoint sets Innledning 211 og 213

Kap 23 Minimum spanning trees

Laeligringsmaringl

[I1] Forstaring skog-implementasjonen av disjunkte mengder(Connected-Components Same-Component Make-Set Union Link Find-Set)

[I2] Vite hva spenntraeligr og minimale spenntraeligr er [I3] Forstaring Generic-MST

[I4] Forstaring hvorfor lette kanter er trygge kanter[I5] Forstaring MST-Kruskal[I6] Forstaring MST-Prim

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

10

Forelesning 10

Korteste vei fra eacuten til alle

Bredde-foslashrst-soslashk kan finne stier med faeligrrest mulig kanter men hva om kantenehar ulik lengde Det generelle problemet er uloslashst men vi kan loslashse problemet medgradvis bedre kjoslashretid for grafer (1) uten negative sykler (2) uten negative kanterog (3) uten sykler Og vi bruker samme prinsipp for alle tre

Pensum

Kap 24 Single-source shortest paths Innledning og 241ndash243

Laeligringsmaringl

[J1] Forstaring ulike varianter av korteste-vei- eller korteste-sti-problemet(Single-source single-destination single-pair all-pairs)

[J2] Forstaring strukturen til korteste-vei-problemet[J3] Forstaring at negative sykler gir mening for korteste enkle vei (simple path)[J4] Forstaring at korteste enkle vei kan loslashses vha lengste enkle vei og omvendt[J5] Forstaring hvordan man kan representere et korteste-vei-tre

[J6] Forstaring kant-slakking (edge relaxation) og Relax[J7] Forstaring ulike egenskaper ved korteste veier og slakking

(Triangle inequality upper-bound property no-path property convergence property path-relaxation property predecessor-subgraph property)

[J8] Forstaring Bellman-Ford[J9] Forstaring DAG-Shortest-Path

[J10] Forstaring kobling mellom DAG-Shortest-Path og dynamisk programmering[J11] Forstaring Dijkstra

Merk Noe av stoffet vil kanskje forskyves til forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

11

Forelesning 11

Korteste vei fra alle til alle

Vi kan finne de korteste veiene fra hver node etter tur men mange av delinstanse-ne vil overlappe ndash om vi har mange nok kanter loslashnner det seg aring bruke dynamiskprogrammering med dekomponeringen laquoSkal vi innom k eller ikkeraquo

Pensum

Kap 25 All-pairs shortest paths Innledning 252 og 253

Laeligringsmaringl

[K1] Forstaring forgjengerstrukturen for alle-til-alle-varianten av korteste vei-problemet(Print-All-Pairs-Shortest-Path)

[K2] Forstaring Floyd-Warshall[K3] Forstaring Transitive-Closure[K4] Forstaring Johnson

Merk Noe stoff fra forelesning 12 vil kanskje dekkes her

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

12

Forelesning 12

Maksimal flyt

Et stort skritt i retning av generell lineaeligr optimering (saringkalt lineaeligr programme-ring) Her ser vi paring to tilsynelatende forskjellige problemer som viser seg aring vaeligreduale av hverandre noe som hjelper oss med aring finne en loslashsning

Pensum

Kap 26 Maximum flow Innledning og 261ndash263

Laeligringsmaringl

[L1] Kunne definere flytnett flyt og maks-flyt-problemet[L2] Kunne haringndtere antiparallelle kanter og flere kilder og sluk

[L3] Kunne definere restnettet til et flytnett med en gitt flyt[L4] Forstaring hvordan man kan oppheve (cancel) flyt[L5] Forstaring hva en foroslashkende sti (augmenting path) er[L6] Forstaring hva snitt snitt-kapasitet og minimalt snitt er

[L7] Forstaring maks-flytmin-snitt-teoremet[L8] Forstaring Ford-Fulkerson-Method og Ford-Fulkerson[L9] Vite at Ford-Fulkerson med BFS kalles Edmonds-Karp-algoritmen[L10] Forstaring hvordan maks-flyt kan finne en maksimum bipartitt matching

[L11] Forstaring heltallsteoremet (integrality theorem)

Merk Noe av stoffet vil kanskje dekkes i forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

13

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 18: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Forelesning 10

Korteste vei fra eacuten til alle

Bredde-foslashrst-soslashk kan finne stier med faeligrrest mulig kanter men hva om kantenehar ulik lengde Det generelle problemet er uloslashst men vi kan loslashse problemet medgradvis bedre kjoslashretid for grafer (1) uten negative sykler (2) uten negative kanterog (3) uten sykler Og vi bruker samme prinsipp for alle tre

Pensum

Kap 24 Single-source shortest paths Innledning og 241ndash243

Laeligringsmaringl

[J1] Forstaring ulike varianter av korteste-vei- eller korteste-sti-problemet(Single-source single-destination single-pair all-pairs)

[J2] Forstaring strukturen til korteste-vei-problemet[J3] Forstaring at negative sykler gir mening for korteste enkle vei (simple path)[J4] Forstaring at korteste enkle vei kan loslashses vha lengste enkle vei og omvendt[J5] Forstaring hvordan man kan representere et korteste-vei-tre

[J6] Forstaring kant-slakking (edge relaxation) og Relax[J7] Forstaring ulike egenskaper ved korteste veier og slakking

(Triangle inequality upper-bound property no-path property convergence property path-relaxation property predecessor-subgraph property)

[J8] Forstaring Bellman-Ford[J9] Forstaring DAG-Shortest-Path

[J10] Forstaring kobling mellom DAG-Shortest-Path og dynamisk programmering[J11] Forstaring Dijkstra

Merk Noe av stoffet vil kanskje forskyves til forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

11

Forelesning 11

Korteste vei fra alle til alle

Vi kan finne de korteste veiene fra hver node etter tur men mange av delinstanse-ne vil overlappe ndash om vi har mange nok kanter loslashnner det seg aring bruke dynamiskprogrammering med dekomponeringen laquoSkal vi innom k eller ikkeraquo

Pensum

Kap 25 All-pairs shortest paths Innledning 252 og 253

Laeligringsmaringl

[K1] Forstaring forgjengerstrukturen for alle-til-alle-varianten av korteste vei-problemet(Print-All-Pairs-Shortest-Path)

[K2] Forstaring Floyd-Warshall[K3] Forstaring Transitive-Closure[K4] Forstaring Johnson

Merk Noe stoff fra forelesning 12 vil kanskje dekkes her

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

12

Forelesning 12

Maksimal flyt

Et stort skritt i retning av generell lineaeligr optimering (saringkalt lineaeligr programme-ring) Her ser vi paring to tilsynelatende forskjellige problemer som viser seg aring vaeligreduale av hverandre noe som hjelper oss med aring finne en loslashsning

Pensum

Kap 26 Maximum flow Innledning og 261ndash263

Laeligringsmaringl

[L1] Kunne definere flytnett flyt og maks-flyt-problemet[L2] Kunne haringndtere antiparallelle kanter og flere kilder og sluk

[L3] Kunne definere restnettet til et flytnett med en gitt flyt[L4] Forstaring hvordan man kan oppheve (cancel) flyt[L5] Forstaring hva en foroslashkende sti (augmenting path) er[L6] Forstaring hva snitt snitt-kapasitet og minimalt snitt er

[L7] Forstaring maks-flytmin-snitt-teoremet[L8] Forstaring Ford-Fulkerson-Method og Ford-Fulkerson[L9] Vite at Ford-Fulkerson med BFS kalles Edmonds-Karp-algoritmen[L10] Forstaring hvordan maks-flyt kan finne en maksimum bipartitt matching

[L11] Forstaring heltallsteoremet (integrality theorem)

Merk Noe av stoffet vil kanskje dekkes i forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

13

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 19: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Forelesning 11

Korteste vei fra alle til alle

Vi kan finne de korteste veiene fra hver node etter tur men mange av delinstanse-ne vil overlappe ndash om vi har mange nok kanter loslashnner det seg aring bruke dynamiskprogrammering med dekomponeringen laquoSkal vi innom k eller ikkeraquo

Pensum

Kap 25 All-pairs shortest paths Innledning 252 og 253

Laeligringsmaringl

[K1] Forstaring forgjengerstrukturen for alle-til-alle-varianten av korteste vei-problemet(Print-All-Pairs-Shortest-Path)

[K2] Forstaring Floyd-Warshall[K3] Forstaring Transitive-Closure[K4] Forstaring Johnson

Merk Noe stoff fra forelesning 12 vil kanskje dekkes her

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

12

Forelesning 12

Maksimal flyt

Et stort skritt i retning av generell lineaeligr optimering (saringkalt lineaeligr programme-ring) Her ser vi paring to tilsynelatende forskjellige problemer som viser seg aring vaeligreduale av hverandre noe som hjelper oss med aring finne en loslashsning

Pensum

Kap 26 Maximum flow Innledning og 261ndash263

Laeligringsmaringl

[L1] Kunne definere flytnett flyt og maks-flyt-problemet[L2] Kunne haringndtere antiparallelle kanter og flere kilder og sluk

[L3] Kunne definere restnettet til et flytnett med en gitt flyt[L4] Forstaring hvordan man kan oppheve (cancel) flyt[L5] Forstaring hva en foroslashkende sti (augmenting path) er[L6] Forstaring hva snitt snitt-kapasitet og minimalt snitt er

[L7] Forstaring maks-flytmin-snitt-teoremet[L8] Forstaring Ford-Fulkerson-Method og Ford-Fulkerson[L9] Vite at Ford-Fulkerson med BFS kalles Edmonds-Karp-algoritmen[L10] Forstaring hvordan maks-flyt kan finne en maksimum bipartitt matching

[L11] Forstaring heltallsteoremet (integrality theorem)

Merk Noe av stoffet vil kanskje dekkes i forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

13

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 20: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Forelesning 12

Maksimal flyt

Et stort skritt i retning av generell lineaeligr optimering (saringkalt lineaeligr programme-ring) Her ser vi paring to tilsynelatende forskjellige problemer som viser seg aring vaeligreduale av hverandre noe som hjelper oss med aring finne en loslashsning

Pensum

Kap 26 Maximum flow Innledning og 261ndash263

Laeligringsmaringl

[L1] Kunne definere flytnett flyt og maks-flyt-problemet[L2] Kunne haringndtere antiparallelle kanter og flere kilder og sluk

[L3] Kunne definere restnettet til et flytnett med en gitt flyt[L4] Forstaring hvordan man kan oppheve (cancel) flyt[L5] Forstaring hva en foroslashkende sti (augmenting path) er[L6] Forstaring hva snitt snitt-kapasitet og minimalt snitt er

[L7] Forstaring maks-flytmin-snitt-teoremet[L8] Forstaring Ford-Fulkerson-Method og Ford-Fulkerson[L9] Vite at Ford-Fulkerson med BFS kalles Edmonds-Karp-algoritmen[L10] Forstaring hvordan maks-flyt kan finne en maksimum bipartitt matching

[L11] Forstaring heltallsteoremet (integrality theorem)

Merk Noe av stoffet vil kanskje dekkes i forelesning 11

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

13

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 21: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Forelesning 13

NP-kompletthet

NP er den enorme klassen av ja-nei-problemer der ethvert ja-svar har et bevis somkan sjekkes i polynomisk tid Alle problemer i NP kan i polynomisk tid reduserestil de saringkalt komplette problemene i NP Dermed kan ikke disse loslashses i polynomisktid med mindre alt i NP kan det Ingen har klart det saring langt

Pensum

Kap 34 NP-completeness

Oppgave 341-4 med loslashsning (0-1 knapsack)

Se ogsaring appendiks D i dette heftet

Laeligringsmaringl

[M1] Forstaring sammenhengen mellom optimerings- og beslutnings-problemer[M2] Forstaring koding (encoding) av en instans[M3] Forstaring hvorfor loslashsningen varingr paring det binaeligre ryggsekkproblemet ikke er poly-

nomisk[M4] Forstaring forskjellen paring konkrete og abstrakte problemer[M5] Forstaring representasjonen av beslutningsproblemer som formelle spraringk[M6] Forstaring definisjonen av klassene P NP og co-NP[M7] Forstaring redusibilitets-relasjonen 6P

[M8] Forstaring definisjonen av NP-hardhet og NP-kompletthet[M9] Forstaring den konvensjonelle hypotesen om forholdet mellom P NP og NPC

[M10] Forstaring hvordan NP-kompletthet kan bevises ved eacuten reduksjon [M11] Kjenne de NP-komplette problemene CIRCUIT-SAT SAT 3-CNF-SAT

CLIQUE VERTEX-COVER HAM-CYCLE TSP og SUBSET-SUM[M12] Forstaring at det binaeligre ryggsekkproblemet er NP-hardt[M13] Forstaring at lengste enkle-vei-problemet er NP-hardt[M14] Vaeligre i stand til aring konstruere enkle NP-kompletthetsbevis

Merk Det kreves ikke grundig forstaringelse av de ulike NP-kompletthetsbevisene

Husk ogsaring laeligringsmaringl Z1ndashZ10 paring side v som gjelder hver forelesning

14

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 22: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Appendiks A

Noen gjengangere

Enkelte tema dukker opp flere ganger i faget uten at de noslashdvendigvis er knyttettil eacuten bestemt forelesning eller ett bestemt pensumkapittel Her beskriver jeg noenslike tema som det kan vaeligre greit aring faring litt i fingrene fra tidlig av siden det kangjoslashre det lettere aring forstaring en god del andre ting i faget

HaringndtrykksformelenDette er eacuten av to enkle men viktige formler som stadig dukker opp naringr man skalanalysere algoritmer Formelen er

nminus1sumi=0

i = n(nminus 1)2

Den kalles gjerne haringndtrykksformelen fordi den beskriver antall haringndtrykk somutfoslashres om n personer skal hilse paring hverandre Vi kan vise dette ved aring telle antallharingndtrykk paring to ulike maringter De to resultatene maring da vaeligre like

Telling 1 La oss se paring personene eacuten etter eacuten Foslashrste person hilser paring alle de andrenminus 1 personene Andre person har allerede hilst paring foslashrste person men bidrar mednminus 2 nye haringndtrykk ved aring hilse paring de gjenvaeligrende Generelt vil person i bidra mednminus i nye haringndtrykk saring totalen blir

(nminus 1) + (nminus 2) + middot middot middot+ 2 + 1 + 0

Om vi snur summen saring vi faringr 0 + 1 + middot middot middot+ (nminus 1) saring er dette den venstre siden avligningen Dette oppstaringr typisk i algoritmer de vi utfoslashrer en loslashkke gjentatte gangerog antall iterasjoner i loslashkken oslashker eller synker med 1 for hver gang slik

1 for i = 1 to nminus 12 for j = i + 1 to n3 i tar j i haringnden

Telling 2 Vi kan ogsaring telle paring en mer rett frem maringte Hver person tar alle de andrei haringnden og inngaringr dermed i nminus 1 haringndtrykk Hvis vi bare teller hver enkelt personsin halvdel av haringndtrykket faringr vi altsaring n(nminus 1) halve haringndtrykk To slike halveharingndtrykk utgjoslashr jo ett helt saring det totale antallet haringndtrykk blir den hoslashyre sidenav ligningen nemlig n(nminus 1)2

15

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 23: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Man kan ogsaring gjoslashre om en sum av denne typen ved aring brette den paring midten oglegge sammen foslashrste og siste element nest foslashrste og nest siste etc Vi faringr da

(nminus 1 + 0) + (nminus 2 + 1) + (nminus 3 + 2) +

Hvert ledd summerer til nminus 1 og det er n2 ledd Mer generelt er summen av enaritmetisk rekke (der vi oslashker med en konstant fra ledd til ledd) lik gjennomsnittetav foslashrste og siste ledd multiplisert med antallet ledd i rekken

UtslagsturneringerDette er den andre av de to sentrale formlene

hminus1sumi=0

2i = 2h minus 1

Det vil si de foslashrste toerpotensene summerer til eacuten mindre enn den neste Enmaringte aring se dette paring er av totallssystemet der et tall a = 11 middot middot middot 1 med h ettalletterfoslashlges av tallet b = 100 middot middot middot 0 som bestaringr av ett ettall og h nuller Her era = 20 + 21 + middot middot middot+ 2hminus1 og b = 2h saring a = bminus 1

Et grundigere bevis kan vi faring ved aring bruke samme teknikk som foslashr og tellesamme ting paring to ulike maringter Det vi vil telle er antall matcher i en utslagsturnering(knockout-turnering) det vil si en turnering der taperen i en match er ute av spilletDette blir altsaring annerledes enn saringkalte round robin-turneringer der alle moslashter allendash for dem kan vi bruke haringndtrykksformelen for aring finne antall matcher siden hvermatch tilsvarer ett haringndtrykk

Telling 1 Vi begynner med aring sette opp et turneringstre

1 2 3 4 middot middot middot n

h

Her er deltakerne plassert nederst i loslashvnodene hver av de tomme hvite nodenerepresenterer en match og vil etterhvert fylles med vinneren av de to i nodeneunder helt til vi staringr igjen med eacuten vinner paring toppen Vi garingr altsaring gjennom hrunder og i hver runde organiseres de spillerne som gjenstaringr i par som skal moslashtesOm vi nummererer rundene baklengs etter hvor mange runder det er igjen tilfinalen saring vil antall matcher i runde i vaeligre 2i Det totale antall matcher er altsaring20 + 21 + middot middot middot+ 2hminus1 som er venstresiden av ligningen varingr

16

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 24: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Telling 2 Antall deltakere er n = 2h I hver match blir eacuten deltaker slaringtt ut helt tilvi sitter igjen med eacuten vinner etter finalen Antall matcher trenger vi for aring slaring utalle bortsett fra eacuten er nminus 1 eller 2h minus 1 som er hoslashyresiden i ligningen

Det er foroslashvrig ogsaring viktig aring merke seg hoslashyden til treet h = log2 n Dette er altsaringantall doblinger fra 1 til n eller antall halveringer fra n til 1 Det er ogsaring ensammenheng som vil dukke opp ofte

ReduksjonerOfte jobber vi med aring bryte ned problemer i sine enkelte bestanddeler og deretterbygge opp en loslashsning fra bunnen av trinn for trinn Men av og til har vi kanskjeallerede en loslashsning paring et problem som ligner paring det vi proslashver aring loslashse Eller kanskje vivet at et lignende problem er spesielt vanskelig aring loslashse ndash at ingen har klart det ennaringI slike sammenhenger kan vi benytte oss av det som kalles en reduksjonsalgoritmeeller reduksjon En reduksjon transformerer input fra ett problem til et annet slikat vi kan konsentrere oss om aring loslashse problemet vi har redusert til Transformasjonenmaring vaeligre slik at om vi loslashser det nye problemet saring vil loslashsningen ogsaring vaeligre riktigfor det opprinnelige problemet (gitt opprinnelig input) Av og til tillater vi oss aringtransformere svaret tilbake og regner denne transformasjonen ogsaring som en del avreduksjonen

input til A

input til B output fra B

output fra A

reduksjon

evt loslashsning paring B

Ut fra dette kan vi trekke to logisk ekvivalente konklusjoner

(i) Hvis vi kan loslashse B saring kan vi loslashse A

(ii) Hvis vi ikke kan loslashse A saring kan vi ikke loslashse B

Det foslashrste utsagnet ser vi av figuren over Straks vi plugger inn en loslashsning for Bsaring kan den kombineres med reduksjonen for aring lage en loslashsning for A Det andreutsagnet foslashlger ved kontraposisjon Om vi lar LA og LB vaeligre de logiske utsagneneat vi har en loslashsning for hhv A og B saring kan vi skrive om konklusjonene

LB rArr LA og notLA rArr notLB

Vi kan ogsaring slenge paring et par betraktningene

(iii) Hvis vi ikke kan loslashse B saring sier det ingenting om A

(iv) Hvis vi kan loslashse A saring sier det ingenting om B

17

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 25: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Selv om vi ikke kan loslashse B saring kan det jo hende at vi kan loslashse A paring en annen maringteOg om vi kan loslashse A saring er det jo ikke sikkert at vi gjorde det ved aring redusere tilB Disse tilfellene gir oss altsaring ingen informasjon Med andre ord Om vi alleredeer kjent med et problem X og saring stoslashter paring et nytt og ukjent problem Y saring har vito scenarier der vi kan gjoslashre noe fornuftig Hva vi gjoslashr avhenger av om vi lar Y faringrollen som A eller B i figuren over Hvis vi vi vise at Y ikke er vanskeligere enn Xsaring kan vi la Y innta rollen som A og proslashve aring finne en reduksjon fra Y til X Det erdette vi ofte gjoslashr naringr vi proslashver aring bruke eksisterende algoritmer for et problem X aringloslashse et nytt problem Y Vi reduserer Y til X og loslashser saring X

Men av og til mistenker vi at et problem vi stoslashter paring er vanskelig Kanskje vikjenner til et problem X som vi vet er vanskelig og vi vil vise at Y er minst likevanskelig Da maring vi i stedet la Y innta rollen som B og redusere fra det vanskeligeproblemet Vi skriver A 6 B for aring uttrykke at problemet A er redusibelt til B detvil si at det finnes en reduksjon fra A til B saring A kan loslashses ved hjelp av B Det betyraltsaring at A ikke er vanskeligere enn B siden vi jo kan redusere til B og ekvivalentat B er minst like vanskelig som A

Vanligvis oslashnsker vi aring vaeligre noe mer nyanserte enn at det finnes eller ikke finnesen loslashsning paring et problem Vi kan for eksempel lure paring hvor effektive algoritmer vikan finne for problemet Da er det viktig at ogsaring reduksjonen varingr er effektiv Fordersom reduksjonen bruker ubegrenset lang tid saring vil jo ikke en effektiv loslashsning paringB fortelle oss noe om hvor effektivt vi kan loslashse A

18

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 26: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Appendiks B

Iterasjonsmetoden

I laeligreboka er rekursjonstraeligr en sentral metode for aring loslashse rekurrensligninger Detteer en mer visuell fremgangsmaringte enn den som ble brukt i tidligere utgaver somde kalte iterasjonsmetoden Det er egentlig akkurat samme prinsipp bare at manjobber mer direkte paring ligningene Ideen er at man bruker rekurrensen selv til aringekspandere de rekursive termene For eksempel

T(0) = 0T(n) = T(nminus 1) + 1 (n gt 1)

Her oslashnsker vi aring bli kvitt T(nminus 1) paring hoslashyre side i ligningen Om vi antar at n gt 1saring kan vi bruke definisjonen T(n) = T(n minus 1) + 1 til aring finne ut hva T(n minus 1) ernemlig (T((nminus 1)minus 1) + 1) + 1 eller T(nminus 2) + 2 Det er altsaring eacuten ekspansjon (elleriterasjon) Vi kan fortsette paring samme maringte trinn for trinn helt til vi ser et moslashnsterdukke opp

T(0) = 0T(n) = T(nminus 1) + 1 (1)

= T(nminus 2) + 2 (2)= T(nminus 3) + 3 (3)

= T(nminus i) + i (i)= T(nminus n) + n = n (n)

Foslashrst ekspanderer vi altsaring T(n) saring T(nminus 1) og saring T(nminus 2) og saring videre hele tidenved hjelp av den opprinnelige rekurrensen Linjenummeret (til hoslashyre) viser hvormange ekspansjoner vi har gjort Etter hvert klarer vi altsaring aring uttrykke resultatetetter et vilkaringrlig antall ekspansjoner i Her kan i vaeligre 1 2 3 eller et hvilket somhelst annet tall saring lenge vi ikke ekspanderer oss laquoforbiraquo grunntilfellet T(0) = 0Og det er nettopp grunntilfellet vi oslashnsker aring naring vi vil gi T argumentet 0 For aringfaring til det maring vi altsaring faring nminus i til aring bli 0 og altsaring sette i = n Dette gir oss svaretsom vist i siste linje Et litt mer interessant eksempel finner du i appendiks C derhver ekspansjon halverer argumentet til T saring trenger bare lg n ekspansjoner foslashr vikommer ned til T(1) som er grunntilfellet der

19

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 27: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Appendiks C

Binaeligrsoslashk

Laeligreboka sin beskrivelse av binaeligrsoslashk paring engelsk binary search eller bisectionbegrenser seg til et par oppgaver (23-5 og 45-3 med problemet definert i 21-3) Algoritmen er gjennomgaringtt i mer detalj i forelesningene men den sentraleinformasjonen er oppsummert her Selve algoritmen er definert som foslashlger dertabellen A[1 n] antas aring vaeligre sortert

Bisect(A p r v)1 if p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 return Bisect(A p q minus 1 v)7 else return Bisect(A q + 1 r v)8 else return nil

Dersom A inneholder v saring vil Bisect(A 1 n v) returnere en indeks i som erslik at A[i] == v Hvis ikke saring returneres nil

Korrekthet kan vises ved induksjon over lengden til segmentet A[p r] Vi harto grunntilfeller Enten er p gt r saring segmentet er tomt og vi returnerer nil ellerssaring har vi p = r og v = A[q] og vi returnerer q Begge disse er korrekte Anta saringat p 6 r og at Bisect gir rett svar for kortere intervaller Baringde A[p q minus 1] ogA[q + 1 r] er kortere intervaller saring samme hvilket rekursivt kall som velges saring vilvi returnere rett indeks

For aring finne kjoslashretiden kan vi for eksempel telle antall ganger sammenligningenp 6 r utfoslashres Vi kan gjoslashre noen antagelser for aring forenkle utregningen Disse haringenting aring si for den asymptotiske kjoslashretiden For det foslashrste antar vi at n = 2kfor et eller annet heltall k gt 0 slik at vi alltid kan dele noslashyaktig paring midten helttil vi ender med p == q For det andre saring antar vi at v finnes i A saring rekursjonenstanser her For aring sikre at vi deler paring midten kan vi til og med anta at den enesteforekomsten av v er A[n] saring vi alltid velger det hoslashyre segmentet A[q + 1 r] (Vikan bruke induksjon dvs substitusjonsmetoden til aring verifisere at den asymptotiskekjoslashretiden vi finner er gyldig ogsaring om disse antagelsene ikke gjelder) Vi faringr da

20

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 28: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

foslashlgende rekurrensutregning

T(1) = 1T(n) = T(n2) + 1 (1)

= T(n4) + 2 (2)= T(n8) + 3 (3)

= T(n2i) + i (i)= T(nn) + lg n = lg n + 1 (lg n)

Med andre ord er kjoslashretiden Θ(lg n)Som saring ofte ellers saring hjelper det aring tenke rekursivt for aring forstaring hvordan algoritmen

fungerer men det er som alltid mulig aring kvitte seg med rekursjonen og faring en iterativversjon

Bisectprime(A p r v)1 while p 6 r2 q = b(p + r)2c3 if v == A[q]4 return q5 else if v lt A[q]6 r = q minus 17 else p = q + 18 return nil

Denne versjonen vil generelt vaeligre mer effektiv siden man slipper ekstra kostnaderved funksjonskalllowast Baringde korrekthetsbevis og kjoslashretidsberegning kan oversettesganske direkte fra Bisect til Bisectprime

lowast Siden returverdien fra det rekursive kallet returneres direkte uten noe mer kode imellom ndash etsaringkalt tail call ndash saring vil enkelte spraringk kunne gjoslashre denne transformasjonen automatisk ved hjelpav saringkalt tail-call elimination eller tail-call optimization

21

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 29: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Appendiks D

Ryggsekkproblemet

Det saringkalte ryggsekkproblemet kommer i flere varianter og to av dem er beskrevetparing side 425ndash426 i laeligreboka Den kontinuerlige varianten er lett aring loslashse Man tar baremed seg saring mye som mulig av den dyreste gjenstanden og fortsetter nedover paring listasortert etter kilopris I den binaeligre varianten derimot blir ting litt vanskeligeremdashhermaring man ta med en hel gjenstand eller la den ligge Loslashsningen er egentlig beskrevetparing 426 men den er litt bortgjemt i teksten og er beskrevet svaeligrt skissepreget

Akkurat som i for eksempel Floyd-Warshall saring baserer dekomponeringenseg paring et ja-nei-sposlashrsmaringl i dette tilfelle laquoSkal vi ta med gjenstand iraquo For hver avde to mulighetene sitter vi igjen med et delinstans som vi loslashser rekursivt (i hvertfall konseptuelt) Som vanlig tenker vi oss at dette er siste trinn og antar at vi hargjenstander 1 i tilgjengelige Vi har da foslashlgende alternativer

(i) Ja vi tar med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus 1men der kapasiteten er redusert med wi Vi legger saring til vi til slutt

(ii) Nei vi tar ikke med gjenstand i Vi loslashser saring problemet for gjenstander 1 iminus1 men kan fortsatt bruke hele kapasiteten Til gjengjeld faringr vi ikke legge til vi

til slutt

Situasjonen er illustrert i Fig D1 der hver rute representerer en delloslashsning (encelle i loslashsningstabellen for eksempel) og pilene er avhengigheter som vanlig Vi kansette opp en rekursiv loslashsning slik (der vi antar at vektene og verdiene er globalevariable for enkelhets skyld)

inkludeacuter obj n ekskludeacuter obj n

n

W

Wminus wn

nminus 1 nminus 1

W+vn

Figur D1 Dekomponering for det binaeligre ryggsekkproblemet

22

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 30: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Knapsack(n W)1 if n == 02 return 03 x = Knapsack(nminus 1 W)4 if wn gt W5 return x6 else y = Knapsack(nminus 1 Wminus wn) + vn

7 return max(x y)

Denne prosedyren vil naturligvis ha eksponentiell kjoslashretid Vi kan loslashse det vedaring bruke memoisering eller vi kan skrive den om til en iterativ bottom-up-loslashsningsom nedenfor

Knapsackprime(n W)1 let K[0 n 0 W] be a new table2 for j = 0 to W3 K[0 j] = 04 for i = 1 to n5 for j = 0 to W6 x = K[iminus 1 j]7 if j lt wi

8 K[i j] = x9 else y = K[iminus 1 j minus wi] + vi

10 K[i j] = max(x y)

Forskjellen ligger i at vi her eksplisitt legger inn for-loslashkker for aring garing gjennom alledelinstansene heller enn aring gjoslashre det direkte (implisitt) med rekursjon

Men dette er ikke polynomiskDet binaeligre ryggsekkproblemet er et saringkalt NP-hardt problem og det er ingen somhar funnet noen polynomisk loslashsning paring det trolig vil ingen noen gang finne detheller Det ser jo ut til aring motsi diskusjonen over der vi kom frem til det som absoluttser ut som en algoritme med polynomisk kjoslashretid Hva er det som foregaringr her

Kjoslashretiden til baringde Knapsack og Knapsackprime er Θ(nW) siden det er nWdelinstanser og vi utfoslashrer en konstant mengde arbeid per delinstans Og det errett at dette er en polynomisk funksjon av n og W men det er ikke nok til at vikan si at algoritmene laquohar polynomisk kjoslashretidraquo Sposlashrsmaringlet er som funksjon avhva Hvis vi eksplisitt sier laquosom funksjon av n og Wraquo er alt i orden Men om viikke oppgir noen eksplisitte parametre saring antas kjoslashretiden aring vaeligre en funksjon avinput-stoslashrrelsen som altsaring er hvor stor plass en instans tar Akkurat hvordan vimaringler denne stoslashrrelsen kan avhenge av problemet (se side 25 i laeligreboka) men naringrvi regner paring om ting kan loslashses i polynomisk tid (i forbindelse med NP-kompletthetog denslags) holder vi oss til antall bits i input i en rimelig encoding Stoslashrrelsenblir da Θ(n + lg W) siden vi bare trenger Θ(lg W) bits for aring lagre parameteren WPoenget er altsaring at W vokser eksponentielt som funksjon av lg W og kjoslashretiden erteknisk sett eksponentiell

23

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 31: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Dette er kanskje enda enklere aring se hvis vi lar m vaeligre antall bits i W saring vi kanskrive kjoslashretiden som

T(n m) = Θ(n2m)

Da er det forharingpentligvis tydelig at dette ikke er en polynomisk kjoslashretid Kjoslashretidersom er polynomiske hvis vi lar et tall fra input vaeligre med som parameter tilkjoslashretiden (slik som Θ(nW) der W er et tall fra input og ikke direkte en del avproblemstoslashrrelsen) kaller vi pseudopolynomiske

24

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 32: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Appendiks E

Generell graftraversering

Laeligreboka beskriver to traverseringsalgoritmer bredde-foslashrst-soslashk (222) og dybde-foslashrst-soslashk (223) Disse fremstilles ganske ulikt men er naeligrt beslektede Prosedyren BFS(paring side 595) kan tilpasses til aring oppfoslashre seg omtrent likt med DFS (side 605)ved aring bytte ut FIFO-koslashen Q med en LIFO-koslash eller stakk (stack) Vi mister datidsmerkingen (vd og vf) men rekkefoslashlgen noder farges graring og svarte paring vil bliden samme (En annen forskjell er at DFS slik den er beskrevet i boka ikke harnoen startnode men bare starter fra hver node etter tur til den har naringdd helegrafen saringnn sett er BFS mer beslektet med DFS-Visit)

Koslashen Q i BFS er rett og slett en liste med noder vi har oppdaget via kanter fratidligere besoslashkte noder men som vi ennaring ikke har besoslashkt Noder er hvite foslashr delegges inn graring naringr de er i Q og svarte etterparing Det at vi bruker en FIFO-koslash er detsom lar BFS finne de korteste stiene til alle noder siden vi utforsker grafen laquolagvisraquoutover men vi kan egentlig velge vilkaringrlige noder fra Q i hver iterasjon og vi villikevel traversere hele den delen av grafen vi kan naring fra startnoden

Grunnen til at en LIFO-koslash gir oss samme atferd som en rekursiv traversering(altsaring DFS) er at vi egentlig bare simulerer hvordan rekursjon er implementertInternt bruker maskina en kallstakk der informasjon om hvert kall legges oslashverst oghentes frem igjen naringr rekursive kall er ferdige

Som Cormen mfl paringpeker saring bruker Prims og Dijkstras algoritmer svaeligrtlignende ideer Prosedyrene MST-Prim (side 634) og Dijkstra (side 658) forenklerting litt ved aring sette Q = GV foslashr loslashkken som bruker Q saring vi mister den delenav traverseringen som handler om aring oppdage noder I eldre fremstillinger av dissealgoritmene saring ligner de mer paring BFS og noder legges inn i Q naringr de oppdagesDen sentrale forskjellen er hvilke noder som tas ut av Q altsaring hvilke noder somprioriteres I BFS prioriteres de eldste og i DFS prioriteres de nyeste i Dijkstraprioriteres noder med lavt avstandsestimat (vd) mens i Prim prioriteres nodersom har en lett kant til eacuten av de besoslashkte (svarte) nodene I tillegg oppdateres disseprioritetene underveis

Andre prioriteringer vil gi andre traverseringsalgoritmer som for eksempel densaringkalte Alowast-algoritmen (ikke pensum)

25

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 33: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Appendiks F

Rekursjon og iterasjon

Iterative funksjoner kan oversettes til ekvivalente rekursive funksjoner og omvendtDette er noe vi ofte gjoslashr under konstruksjon av algoritmer basert paring rekursivdekomponering kanskje spesielt innen dynamisk programmering De to maringtenearing tenke paring kan vaeligre anvendelige i ulike situasjoner for eksempel kan det vaeligrepraktisk aring tenke rekursivt naringr man bygger loslashsninger fra del-loslashsninger men iterativeloslashsninger unngaringr ekstrakostnader til funksjonskall som kan vaeligre viktig naringr enalgoritme faktisk skal implementeres

Fra iterasjon til rekursjonDette er en transisjon man ofte maring gjoslashre om man skal laeligre seg saringkalt funksjonellprogrammering Aring leke seg med funksjonelle spraringk kan vaeligre nyttig for aring bli grundigvant til rekursjonlowast

Det enkleste aring oversette direkte er kanskje loslashkker av typen repeat-while (i mangespraringk kjent som do-while) der betingelsen kommer til slutt For eksempel

1 repeat2 body3 while condition

Dette kan man oversette til

Func(vars)1 body2 if condition3 Func(vars)

Ett kall tilsvarer her eacuten iterasjon av loslashkken og vars tilsvarer lokale variable somsendes med fra iterasjon til iterasjon La oss si vi feks vil skrive ut tallene 1 n

1 i = 12 repeat3 print i4 i = i + 15 while i 6 nlowast Ta for eksempel en titt paring Haskell (httpshaskellorg)

26

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 34: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Vi kan da skrive om det til

Numbers(i n)1 print i2 i = i + 13 if i 6 n4 Numbers(i n)

Funksjonen kalles da med argumenter 1 og n til aring begynne medIntuitivt kan dette tolkes paring flere maringter Eacuten veldig enkel tolkning er at kallet til

Numbers forteller maskina at vi skal garing tilbake til start og utfoslashre definisjonen avNumbers akkurat som i en loslashkke Det blir som om vi hadde skrevet om loslashkken tildet foslashlgende (om vi antar at i alt er satt til 1)

1 print i2 i = i + 13 if i 6 n4 go to 1

Internt er det nettopp denne typen go to-utsagn kompilatoren oversetter loslashkkertil I mange spraringk er det ogsaring nettopp slik kode man faringr om man bruker rekursjonslik som vi har gjort over Med andre ord Baringde loslashkker og rekursjon kan ende medsamme primitive maskinkode som inneholder verken loslashkker eller rekursjon

En annen maringte aring forstaring koden paring intuitivt er at vi skiller mellom foslashrste iterasjonog resten Foslashrste iterasjon bestaringr av linje 1 og 2 og om vi ikke har kommet tilslutten saring utfoslashrer vi resten av iterasjonene rekursivt

Om man trenger verdier som beregnes i loslashkken kan disse returneres fra funksjo-nen For eksempel kan returverdiene vaeligre de samme variablene som foslashr

Func(vars)1 body2 if condition3 vars = Func(vars)4 return vars

Merk at naring kan ikke lenger kompilatoren uten videre oversette dette til et enkeltgo to-utsagn (saringkalt tail-call optimization) siden vi har kode etter det rekursivekallet

La oss si at vi feks vil summere tallene fra 1 til n i stedet med en loslashkke som

1 s i = 0 12 repeat3 s = s + i4 i = i + 15 while i 6 n

Vi kan skrive om dette til

27

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 35: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Sum(i n s)1 s = s + i2 i = i + 13 if i 6 n4 i n s = Sum(i n s)5 return i n s

Kallet som starter det hele blir Sum(1 n 0) (Her er det naturligvis unoslashdvendigaring sende med alle variablene tilbake siden vi kun trenger s men det illustrerer atoversettelsen her kan gjoslashres ganske mekanisk)

Aring haringndtere andre typer loslashkker er relativt rett frem For eksempel kan du begynnemed aring skrive dem om til aring vaeligre paring repeat-while-formen (selv om du nok ofte vilkunne finne mer naturlige rekursive maringter aring skrive koden paring)

Fra rekursjon til iterasjonSom nevnt over Hvis det rekursive kallet kommer helt til slutt i funksjonen kanvi ofte oversette det direkte til en ekvivalent loslashkke Dersom koden fortsetter etteret rekursivt kall derimot saring maring vi simulere rekursjonen paring noe vis vi maring huskehvilke verdier de lokale variablene hadde foslashr det rekursive kallet og gi dem disseverdiene igjen

Maringten vi gjoslashr dette paring er med en stakk akkurat slik som rekursjon er imple-mentert internt i programmeringsspraringkene (vha en kallstakk) La oss si vi har enrekursiv funksjon som dette

Func( )1 before2 if condition3 Func( )4 after

La oss si at koden baringde foslashr og etter bruker de samme variablene vars Da kanvi fjerne rekursjonen slik der S er en LIFO-stakk

1 repeat2 before3 Push(S vars)4 while condition5 while S is not empty6 vars = Pop(S)7 after

Det rekursive kallet til Func mottar formodentlig andre argumenter enn dem vifaringr inn det kan her bare haringndteres med vanlige tilordninger

28

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon
Page 36: Algoritmer og datastrukturer · [Y 1] Kjennetilbegreperrundtmonotonefunksjoner [Y 2] Kjennetilnotasjonenedxe,bxc,n! oga mod n [Y 3] Vitehvapolynomer er [Y 4] Kjennegrunnleggendepotensregning

Bibliografi

[1] T H Cormen mfl Introduction to Algorithms 3 utg The MIT Press 2009[2] B A Oakley A mind for numbers How to excel at math and science (even if

you flunked algebra) TarcherPerigee 2014

29

  • Problemer og algoritmer
  • Datastrukturer
  • Splitt og hersk
  • Rangering i lineaeligr tid
  • Rotfaste trestrukturer
  • Dynamisk programmering
  • Graringdige algoritmer
  • Traversering av grafer
  • Minimale spenntraeligr
  • Korteste vei fra eacuten til alle
  • Korteste vei fra alle til alle
  • Maksimal flyt
  • NP-kompletthet
  • Noen gjengangere
  • Iterasjonsmetoden
  • Binaeligrsoslashk
  • Ryggsekkproblemet
  • Generell graftraversering
  • Rekursjon og iterasjon