Snåla algoritmer Backtracking

Slides:



Advertisements
Liknande presentationer
Anders Sjögren Lagringsklasser •en variabel i C har två attribut –type( int, float, char..... ) –lagringsklass( auto, extern, register, static ) •lagringsklassens.
Advertisements

Funktioner och programorganisation
2D1311 Programmeringsteknik med PBL
Algoritmer och data strukturer -Länkade listor
Föreläsning 3 Repetition Operatorer Styrstrukturer Deklaration och anrop av metoder.
För utveckling av verksamhet, produkter och livskvalitet. Rekursiva algoritmer, en annan sort tänkande -Hur -När -Bra/Dåligt (kap 7)
OOP Objekt-orienterad programmering
Datastrukturer och algoritmer Föreläsning 11. Datastrukturer och algoritmer VT08 Innehåll  Mängd  Lexikon  Heap  Kapitel , , 14.4.
För utveckling av verksamhet, produkter och livskvalitet. Algoritmer och datastructurer - Lite mer rekursivitet -Sorterrings algoritmer -- Kapitel 8 Algoritmer.
Algoritmer och datastrukturer
Programmeringsteknik för K och Media
Växjö 22 april -04Språk & logik: Parsning med kontextfria grammatiker1 DAB760:Språk och logik: 22 aprilParsning Leif Grönqvist
Föreläsning 10 Länkade lista Stack och Kö Att arbeta med listor
Föreläsning 2 Primitiva datatyper Variabler och konstanter Tilldelning Inläsning Operatorer Villkorssatsen if Slingor: while och for.
Föreläsning 11 Arrayer.
OOP F4:1 Marie Olsson OOP Objekt-orienterad programmering Föreläsning 4 Metoder klass-metoder instans-metoder.
PROCESSPROGRAMMERING
Jonny Karlsson INTRODUKTION TILL PROGRAMMERING Föreläsning 6 ( ) INNEHÅLL: -Mera om tabeller.
Föreläsning 4 Kö Implementerad med array Implementerad med länkad lista Djup kontra bredd Bredden först mha kö.
Föreläsning 2 Kort Översikt Över Javaspråket. Källkodsformat Unicode används åäöμψζ tillåtna Inte alla miljöer klarar av det Källkod Bytekod Java VM för.
1 ITK:P1 Föreläsning 7 Algoritmer och datastrukturer DSV Marie Olsson.
Vektorer (klassen Vector) Sortering
Jonny Karlsson PROCESSPROGRAMMERING Föreläsning 8 ( ) Innehåll: Trådprogrammering i Java - Avbrott (”interrupts”) - Metoden join() -
OOP F6:1 Stefan Möller OOP Objekt-orienterad programmering Föreläsning 6 Mer om klasser och objekt Hantera många objekt ArrayList toString() – metoden.
Jonny Karlsson INTRODUKTION TILL PROGRAMMERING Föreläsning 3 ( ) INNEHÅLL: -Jämförelseoperatorer -Villkorssatser -Logiska operatorer.
Rekursiva algoritmer Hur När Bra/Dåligt (kap 7).
Jonny Karlsson INTRODUKTION TILL PROGRAMMERING Föreläsning 7 ( ) INNEHÅLL: -Metoder -Lokala variabler -Mera om klasser: -Nyckelorden.
Riktade listor i C och Java Lösning till gruppövning 1.
1 Föreläsning 6 Programmeringsteknik och Matlab 2D1312/2D1305 Metoder & parametrar Array API och klassen ArrayList.
Namnrum, räckvidd och rekursion Linda Mannila
F. Drewes, Inst. f. datavetenskap1 Föreläsning 11: Funktionella språk Funktioner och variabler i matematiken Funktionella språk LISP, ML och.
Föreläsning 10 Stränghantering.
Föreläsning 1 Reserverade ord Javas API Identifierare Litteraler Variabler Kompilering och interpretering.
Jonny Karlsson INTRODUKTION TILL PROGRAMMERING Föreläsning 3 ( ) INNEHÅLL: -Tabeller -Villkorssatser -Repetitionssatser.
William Sandqvist C-programmering ID120V Stack och Kö William Sandqvist
För utveckling av verksamhet, produkter och livskvalitet. Stack och Kö - Implementering - Tilllämpningar.
Föreläsning 12 Om slutprovet. Repetition –deklaration av variabler –skapande av objekt (instansiering) –Vektorer och Vector-klassen –Klasser –Instans-/klassvariabler.
Datastrukturer och algoritmer
Stack och Kö -Implementering -Tilllämpningar -- Kapitel 16, 11.
Rekursion. En metoddefinition som innehåller ett anrop av sig själv kallas rekursiv.
1 Mönstermatchning och rekursion Nr 4. 2 Förenklad notation val fnname = fn name => expression Förenklas till fun fnname name = expression Exempel fun.
OOP F13:1 Marie Olsson OOP Objekt-orienterad programmering Föreläsning 13 Repetition variabler, selektion och iteration.
OOP F2:1 Stefan Möller OOP Objekt-orienterad programmering Föreläsning 2 Deklaration och tilldelning Programsatser Tilldelning Input/Output Selektion.
Köer -- Kapitel 16. Principen med en kö Köer är FIFO datastrukturer  First In – First Out  enqueue() Lägg till data i kön (först)  dequeue() Hämta.
För utveckling av verksamhet, produkter och livskvalitet. Algoritmer och datastrukturer - En annan sort tänkande, rekursiva metoder -Datastrukturen träd,
Logikprogrammering 23/10 Binära träd In- och uthantering David Hjelm.
ITM1 Kapitel 8 Datastrukturer Grundläggande datavetenskap, 4p Utgående från boken Computer Science av: J. Glenn Brookshear.
Föreläsning 3 Villkorssatsen if Slingor: while och for Felsökning.
TILLÄMPAD DATALOGI (TILDA) Övningsgrupp 2 Marcus Hjelm
OOP F5:1 Stefan Möller OOP Objekt-orienterad programmering Föreläsning 5 Klasser och objekt Skapa objekt - new Referenser Konstruktorer Inkapsling.
Övning2 programmeringsteknik och Matlab 2D1312/ 2D1305
© Anders Broberg, Ulrika Hägglund, Lena Kallin Westin, 2003 Datastrukturer och algoritmer Föreläsning 13 Sortering.
TILLÄMPAD DATALOGI (TILDA) Övning 2
Föreläsning 14 Logik med tillämpningar Innehåll u Cuts och negation u Input/output u Extralogiska predikat u Interaktiva program, failure-drivna.
För utveckling av verksamhet, produkter och livskvalitet. Algoritmer och Datastrukturer -- Kap 21,14 Prioritets Köer (Priority Queues ), Graph.
1 Föreläsning 2 Reserverade ord Javas API Identifierare Litteraler Variabler Kompilering och interpretering.
OOP&M - teori1 OOP&M – Föreläsning 5 kap 8-13 Operatorer,typkonvertering, booleska operatorer, if och else.
OOP&M - teori1 OOP – Föreläsning 7 (Sista oop I) Konstruktioner för att hantera upprepningar Kapitel 11.
Malmö högskola Rolf Axelsson 2003/2004 DA7235, 4 poäng Fält som returvärde Sortera fält Söka i fält Tvådimensionella fält Fält och spelplan Föreläsning.
Selektion jämförande och logiska operatorer
Algoritmer och loopar Algoritmer, beräkningsbarhet
För utveckling av verksamhet, produkter och livskvalitet. Algoritmer och datastructurer - En annan sort tänkande, rekursiva metoder -Datastrukturen träd.
Algoritmer och datastrukturer Föreläsning 8 Tidskomplexitet (Weiss kap
Föreläsning 3: Booleans, if, switch
Föreläsning 11: Rekursion
Föreläsning 8: Exempel och problemlösning
Föreläsning 12: Exempel och problemlösning
Algoritmer och datastrukturer,förel. 10
Algoritmer och datastrukturer, förel. 1
Repetitionsföreläsning 1: Lite rekursion & problemlösning
Presentationens avskrift:

Algoritmer och datastrukturer Backtracking Dynamisk programmering Föreläsning 12 (Weiss kap. 7.6-7) Snåla algoritmer Backtracking Exempel: Kappsäcksproblemet, labyrintsökning Dynamisk programmering © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Exempel: Kappsäcksproblemet Kan man ur en grupp föremål F1,…,FN med vikterna V1,…,VN välja ut en delgrupp som väger exakt M kilo? Exempel: Man kan packa till alla totalvikter upp till 21 kilo utom till vikterna 1, 4, 17 och 20 föremål F1 F2 F3 F4 F5 vikt 3 7 2 3 6 Analogt problem: Kila under en byrå med träbitar av olika tjocklek. © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

löser ibland inte problemet alls Snåla algoritmer En snål (eng. greedy) algoritm väljer den för tillfället optimala lösningen utan hänsyn till framtida konsekvenser. Exempel: En snål strategi för kappsäcksproblemet vore att prova vikterna i avtagande följd. Metoden löser inte problemet givet uppsättningen på föregående bild för t.ex. totalvikten 11kg. Varför inte? Problemet kan dock lösas med en snål algoritm om vikterna är tvåpotenser 1, 2, 4, 8, 16, … Om Vikterna är 1,2,4,8,...,$2^n$ kan vi packa upp till totalvikterna 1,...,2n+1-1. Dessutom kan man använda en snål algoritm (detta har med optimalitet att göra) analogt: Ta klossarna i avtagande ordning Tag 7 (skippa sen 6) + 3 = 10 och sen är det kört … skulle hoppat över 7 och tagit 6 + 3 + 2 i stället Snåla algoritmer löser ibland inte problemet alls löser inte alltid problemet optimalt (Weiss coin) © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Rekursiv algoritmidé Kappsäcksproblemet kan lösas rekursivt: Antag att vi skall packa upp till M kilo med föremål ur samlingen F1,…,FN Fallanalys: (1-3 är basfallen) 1. Om kappsäcken väger M kilo har vi löst problemet. 2. Om kappsäcken väger mer än M kilo har vi misslyckats. 3. Om det finns mer plats men inte fler föremål har vi misslyckats. återstår två fall: (rekursionssteget) 4. Vi tar med FN och försöker packa resterande utrymme med F1,…,FN-1 5. Vi slänger FN och försöker packa resterande utrymme med F1,…,FN-1 Systematiskt steg för steg uttömmande sökning kombinatorisk explosion N! fall vad krymper mot noll? Hitta måttet! Exakt M kilo är målet Vad gör vi rekursion över? (samtidigt över kvarvarande utrymme och antal föremål) basfallen kanske inte uppenbara? säcken står på en våg - vet inte vad föremålen väger © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Förenkla problemet genom att bara betrakta vikterna V1,…,VN Låt S beteckna packningens vikt Generalisering: Definiera predikatet packa(S, M, V1,…,VN ) som är sant om det finns en delvektor i V1,…,VN vars summa är M - S och falskt annars Problemet är att avgöra om det finns en delvektor i V1,…,VN vars summa är M. ej konsekutiv delvektor M = Mål S = Summa (readn gjort) M – S = kvar att göra Spec S = 0 vid starten så packa(0,M,V1…VN) är ett specialfall av ovanst. © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Definiera packa(S, M, V1,…,VN ) rekursivt: Basfallen: 1. Returnera sant om S = M 2. Returnera falskt om S > M 3. Returnera falskt om S < M och N = 0 Rekursionssteg: S < M och N > 0. Lös problemet för utrymmet M - S och vikterna V1,…,VN Rekursionsantagande: Antag att packa(X, M, V1,…,VN-1 ) löser problemet för ett godtyckligt X  S samt vikterna V1,…,VN-1 Svårt rekursionsantagande M - X <= M - S det är denna differens som krymper eller # vikter Tavlan först! OBS, det finns material på papper här… rita roten i beslutsträdet och visa vilka parametrar som krymper rita upp trädet för Packa(0,9,(2,7,3)) © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Med stöd av rekursionsantagandet kan vi anta att: packa(S + VN, M, V1,…,VN-1 ) löser problemet för fallet då VN tas med och att packa(S, M, V1,…,VN-1 ) löser problemet för fallet då VN slängs Alltså: returnera SANT för S och V1,…,VN om packa(S + VN, M, V1,…,VN-1 ) eller packa(S, M, V1,…,VN-1 ) returnerar SANT. X är här S + Vn >= S ok enl. ant. © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Implementering i Java Vad händer om vi vänder på anropen? boolean packa( int S, int M, int[] V, int N ) { if ( S == M ) return true; else if ( S > M || N == 0 ) return false; else return packa( S + V[ N - 1 ], M, V, N - 1 ) || packa( S, M, V, N - 1 ); } Vad händer om vi vänder på anropen? Samma resultat, olika ber.ordning © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Vilka vikter löste problemet? En vikt får bara skrivas ut när vi vet att den bidrar till lösningen. boolean packa( int S, int M, int[] V, int N ) { if ( S == M ) return true; else if ( S > M || N == 0 ) return false; else if( packa( S + V[ N - 1 ], M, V, N - 1 ) ) { System.out.print( V[ N - 1 ] ); } else return packa( S, M, V, N - 1 ); } Rek. funktion med sidoeffekt. Det som skrivits kan ej göras ogjort © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Backtracking Att lösa ett problem genom att rekursivt prova alla möjligheter. I varje rekursionssteg väljs den bästa dellösningen. Exempel Labyrint Tic-Tac-Toe se Weiss 7.7 © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Exempel: Labyrintsökning Givet: En rektangulär labyrint L med ickecykliska gångar En position (cell) i labyrinten är antingen ”golv” eller ”vägg” (svart) Gångarna har bredden 1 Förflyttning sker stegvis en cell i taget vågrätt eller lodrätt 1 2 3 4 5 6 7 8 9 10 Förväxla ej med formuleringen I inl. uppg. 6 © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Tre olika sökproblem Resultat 1. Finns det en utväg från (x,y)? Ja/Nej 2. Skriv ut en utväg från (x,y) en väg 3. Skriv ut den kortaste utvägen från (x,y) optimal väg Jfr vägnät + bärbuske © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Genom att ta ett steg kommer vi in i en dellabyrint. (Man backar bara till en cell för att prova en annan riktning.) Ett steg uppåt från (5,6) tar oss till dellabyrinten (L1) Ett steg nedåt från (5,6) tar oss till dellabyrinten (L2) 1 2 3 4 5 6 7 8 9 10 5 6 7 8 9 4 1 2 3 10 © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Divide & Conquer Problemet att hitta ut från (5,6) i L kan delas upp rekursivt i delproblemen att hitta ut via (4,6) i L1 eller via (6,6) i L2, eftersom vi kan nå L1 och L2 i ett steg 1. Det finns en väg ur L om det finns en väg ur L1, eller en väg ur L2 2. Skriv ut en väg via L1, eller en via L2 3. Skriv ut den kortaste av vägarna via L1 resp. L2 Basfall: a) Återvändsgränd b) Ute Rekursionsantagande: Sökalgoritmen kan avgöra problemet för dellabyrinterna De tre problemen Om labyrinten innehåller cykler leder ett steg inte alltid tillen mindre dellabyrint. Man får en dellabyrint som innehåller cykeln och som inte krymper vidare. Ickevälgrundat. Nix rekursion! © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Pseudoalgoritm Datatyp för labyrinter boolean finnsUtväg( pos, labyrint ) { om pos är utanför labyrinten returnera SANT annars för varje riktning r { p' = steg( pos, r ) om ärTillåtetSteg från pos till p' och finnsUtväg( p', labyrint ) } returnera FALSKT Datatyp för labyrinter Hjälpfunktioner ges av pseudoalg. © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Klassen Labyrint Behövs datatyper för Labyrinten Positioner Riktningar public class labyrint { public Labyrint( String filnamn ); public void hittaUt (Position startPos ) { ... } private boolean ärUtanför( Position p ) { ... } private Position steg( Position p, Riktning r ) { ... } private boolean ärTillåtetSteg( Position gPos,Position pos, Riktning rikt ) { ... } private boolean sök ( Position gPos, Position pos ) { ... } private boolean ärGolv( Position p ) { ... } private char[][] labyrinten; private int bredd, höjd; } Behövs datatyper för Labyrinten Positioner Riktningar Inför typnamnen först - vänta med def. Ops från pseudoalg. Jag använder ÅÄÖ på bilderna bara © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Datatyper för positioner och riktningar public class Position { public Position( int rad, int kolumn ) { this.rad = rad; this.kolumn = kolumn; } public boolean equals( Position rhs ) { return ( rad == rhs.rad && kolumn == rhs.kolumn ); } public int rad, kolumn; }; public enum Riktning { VÄNSTER, UPP, HÖGER, NER } © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Tre användbara operationer boolean ärUtanför( Position pos ); // avgör om pos är utanför labyrinten eller ej Position steg( Position pos, Riktning riktning ); // returnerar positionen man kommer till // genom ett steg från pos i angiven riktning bool tillåtetSteg( Position gPos, Position pos, Riktning riktning ); // avgör om ett steg från pos i angiven riktning // leder utanför labyrinten, eller till en annan // golvposition än gPos gPos x<--/--x Pos © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Ett steg i rätt riktning…? gPos vi gick härifrån ... Nix backa! sök rikt pos ...och hit steg(pos,rikt) kan vi gå dit? © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Metoden ärUtanför boolean ärUtanför( Position p ) { return p.rad < 0 || p.rad >= höjd || p.kolumn < 0 || p.kolumn >= bredd; } © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Metoden steg Position steg( Position p, Riktning r ) { switch ( r ) { case VÄNSTER: return new Position( p.rad, p.kolumn - 1 ); case HÖGER: return new Position( p.rad, p.kolumn + 1 ); case NER: return new Position( p.rad + 1, p.kolumn ); case UPP: return new Position( p.rad - 1, p.kolumn ); } © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Metoden ärTillåtetSteg boolean ärTillåtetSteg( Position gPos, Position pos, Riktning rikt ) { Position nyPos = steg( pos, rikt ); return ärUtanför( nyPos ) || ( labyrinten[nyPos.rad][nypos.kolumn] == golv && ! nyPos.equals( gPos ) ); } © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Metoden hittaUt Varför Startpos två gånger? void hittaUt( Position startPos ) { if ( sök( startPos, startPos ) ) System.out.print( "det finns en utväg” ); else System.out.print( ”det finns ingen utväg” ); } Varför Startpos två gånger? © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Metoden Sök boolean sök( Position gPos, Position pos ) { if ( ärUtanför( pos ) ) return true; else { for ( Riktning riktning : Riktning.values() ) { if ( ärTillåtetSteg( gPos, pos, riktning ) && sök( pos, steg( pos, riktning ) ) ) } return false; // inlåst!? © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Hur skriver man ut vägen? När kan man tidigast skriva ut information om vägen? Hur räknar man ut den kortaste vägen? © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Metoden hittaUtväg Varför Startpos två gånger? void hittaUtväg( Position startPos ) { if ( ! sökUtväg( startPos, startPos ) ) System.out.print( ”det finns ingen utväg” ); } Varför Startpos två gånger? ! sök… - annars skrivs den ut © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Metoden sökUtväg Konsekvens: vägen skrivs ut baklänges SLUTA HÄR boolean sökUtväg( Position gPos, Position pos ) { if ( ärUtanför( pos ) ) return true; else { for ( Riktning riktning : Riktning.values() ) { if ( ärTillåtetSteg( gPos, pos, riktning ) && sökUtväg( pos, steg( pos, riktning ) ) ) { } return false; // inlåst!? System.out.print( riktning ); Konsekvens: vägen skrivs ut baklänges SLUTA HÄR © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Hur skriver man ut vägen rättvänd? Lägg riktningarna på en stack istället för att skriva ut dem under sökningen Skriv ut innehållet i stacken när sökningen är klar Alt. Lägg dem i en kö på väg ner i rekursionen. Skriv ut kön i basfallet. OBS Denna metod fungerar inte för att hitta den kortaste vägen © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Metoden hittaRättUtväg void hittaRättUtväg( Position startPos ) { Stack<Riktning> vägen; if ( sökRättVäg( startPos, startPos, vägen ) ) while ( ! vägen.isEmpty() ) { skrivRiktning( vägen.peek() ); vägen.pop(); } else System.out.print( ”det finns ingen utväg” ); © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Metoden sökRättVäg boolean sökRättVäg( Position gPos, Position pos, Stack<Riktning> vägen ) { if ( ärUtanför( pos ) ) return true; else { for ( Riktning riktning : Riktning.values() ) { if ( ärTillåtetSteg( gPos, pos, rikt ) && sökRättVäg( pos, steg( pos, rikt ), vägen ) ) vägen.push( rikt ); } return false; © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Hur finner man den kortaste vägen? Inför en speciell datatyp för vägar Operationer: returnera vägens längd: längd() lägg till en riktning: add skriv ut vägen: print() Man kan inte skriva förrän man vet vilken som är kortast Vägar måste kunna hanteras som värden Flera vägar kan behöva jämföras © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Klassen Väg Man måste inte använda en kö, men det är praktiskt class Väg { public Väg() { längden = Integer.MAX_VALUE; // Antag ”oändligt” lång vägen = new LinkedList(); } public int längd() { return längden; } public Väg add( Riktning r ) { ... } // Ger en ny väg inkl. r public void print() { ... } private LinkedList<Riktning> vägen; // FIFO-kö private int längden; }; Man måste inte använda en kö, men det är praktiskt © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Metoden hittaKortasteVägen void hittaKortasteVägen( Position startPos ) { Väg kortasteVägen = sökKortasteVägen( startPos, startPos, new Väg() ); if ( kortasteVägen.längd() < Integer.MAX_VALUE ) kortasteVägen.print(); else System.out.print( ”det finns ingen utväg” ); } © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Metoden sökKortasteVägen Väg sökKortasteVägen( Position gPos, Position pos, Väg vägen ) { if ( ärUtanför( pos ) ) return vägen; else { Väg kortast, aktuell; for ( Riktning riktning : Riktning.values() ) { if ( ärTillåtetSteg( gPos, pos, rikt ) ) { aktuell = sökKortasteVägen( pos, steg( pos, rikt ), vägen.add( rikt ) ); if ( aktuell.längd() < kortast.längd() ) kortast = aktuell; } return kortast; Alla riktningar analyseras Här är det riktig backtracking! © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Dynamisk programmering Problemet En rekursiv D&C-algoritm som löser många överlappande delproblem blir orimligt ineffektiv Dynamisk programmering Lösningarna på delproblemen sätts successivt in i en tabell. Inget delproblem löses flera gånger. Metoden kräver extra minne men kan i gengäld bli avsevärt effektivare än en naiv D&C-algoritm. Exempel: se Weiss 7.6 Det finns ofta ett minimeringsvillkor med i bilden t.ex. kappsäck med bivillkoret att så få vikter som möjligt skall användas Se Coin change © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Ex. fibonaccital med dynamisk programmering Hämta värdet från tabellen om n  7 Komplettera tabellen om n > 7 1 2 3 5 4 8 13 6 21 7 fibTable Det finns ofta ett minimeringsvillkor med i bilden t.ex. kappsäck med bivillkoret att så få vikter som möjligt skall användas Se Coin change Tekniken kallas memoization © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Implementering i Java public class MemoizingFib { private long[] fibTable; int highFibIndex; public MemoizingFib(int size) { fibTable = new long[size]; fibTable[0] = fibTable[1] = 1; highFibIndex = 1; } public long fib(int n) { if ( n >= fibTable.length ) // allocate a bigger table and copy elements if ( n > highFibIndex ) { fibTable[n] = fib(n-1) + fib(n-2); highFibIndex = n; } return fibTable[n]; } I lata funktionella språk kan man använda en lat oändlig lista som definieras ömsesidigt rekursivt med funktionen public static void main(String[] args) { MemoizingFib mf = new MemoizingFib(100); for ( int n = 0; n < 100; n++ ) System.out.println(mf.fib(n)); } © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/

Komplexitet trade off: tid - minne T(N) = tidsåtgång M(N) = minnesbehov för beräkning av det N:te fibonaccitalet Iterativ fib Naiv rekursiv fib Memoiserande fib WC T(N) = O(N) M(N) = O(1) T(N) = O(2N) M(N) = O(N) AC T(N) = O(1) M(N) är O(N) för rekursiv fib eftersom stacken når djupet max N antalet anrop är exponentiellt, men rekursionsdjupet är aldrig större än N. © Uno Holmer, Chalmers, 2019-01-01 www.cse.chalmers.se/~holmer/