Föreläsning 5. Rekursion

Relevanta dokument
Föreläsning 5. Rekursion

Algoritmer och datastrukturer H I HÅKAN S T R Ö M B E R G N I C K L A S B R A N D E F E L T

Föreläsning 13. Dynamisk programmering

Föreläsning 7 Innehåll. Rekursion. Rekursiv problemlösning. Rekursiv problemlösning Mönster för rekursiv algoritm. Rekursion. Rekursivt tänkande:

Metodanrop - primitiva typer. Föreläsning 4. Metodanrop - referenstyper. Metodanrop - primitiva typer

Sökning och sortering

Föreläsning 13. Dynamisk programmering

Rekursion. Koffman & Wolfgang kapitel 5

Programmering för språkteknologer II, HT2014. Rum

Algoritmanalys. Inledning. Informationsteknologi Malin Källén, Tom Smedsaas 1 september 2016

SCB :-0. Uno Holmer, Chalmers, höger 2 Ex. Induktiv definition av lista. // Basfall

Föreläsning 6 Innehåll. Rekursion. Rekursiv problemlösning Mönster för rekursiv algoritm. Rekursiv problemlösning. Rekursion. Rekursivt tänkande:

Algoritmanalys. Genomsnittligen behövs n/2 jämförelser vilket är proportionellt mot n, vi säger att vi har en O(n) algoritm.

Introduktion till algoritmer - Lektion 4 Matematikgymnasiet, Läsåret Lektion 4

Teoretisk del. Facit Tentamen TDDC (6)

Föreläsning 6. Rekursion och backtracking

Datastrukturer, algoritmer och programkonstruktion (DVA104, VT 2015) Föreläsning 6

Föreläsning 6. Rekursion och backtracking

Föreläsning 13. Rekursion

Tentamen TEN1 HI

Föreläsning 11: Rekursion

Rekursion. Att tänka rekursivt Att programmera rekursivt i Java Exempel. Programmeringsmetodik -Java 254

Teoretisk del. Facit Tentamen TDDC (6)

Tommy Färnqvist, IDA, Linköpings universitet. 2 Rekursion i C Implementation av rekursion Svansrekursion En till övning...

Föreläsning 1. Abstrakta datatyper, listor och effektivitet

Magnus Nielsen, IDA, Linköpings universitet

DD1361 Programmeringsparadigm. Carina Edlund

Rekursion och induktion för algoritmkonstruktion

Algoritmer, datastrukturer och komplexitet

Programkonstruktion och Datastrukturer

Tentamen TEN1 HI

Asymptotisk komplexitetsanalys

Föreläsning 9. Sortering

Föreläsning 12. Söndra och härska

Algoritmer, datastrukturer och komplexitet

Introduktion till algoritmer - Lektion 1 Matematikgymnasiet, Läsåret Lektion 1

Tentamen, Algoritmer och datastrukturer

public static void mystery(int n) { if (n > 0){ mystery(n-1); System.out.print(n * 4); mystery(n-1); } }

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 5 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Tommy Färnqvist, IDA, Linköpings universitet

Repetition i Python 3. Exemplen fac. Exemplen fac motivering. Exemplen fac i Python

Rekursion och induktion för algoritmkonstruktion

Föreläsning 5: Kardinalitet. Funktioners tillväxt

Procedurer och villkor

TDDI16 Datastrukturer och algoritmer. Algoritmanalys

Föreläsning 1, vecka 7: Rekursion

Medan ni väntar. 2. Skriv metoden. 3. Skriv metoden. Naturligtvis rekursivt och utan användning av Javas standardmetoder.

Föreläsning 11 Datastrukturer (DAT037)

Föreläsning 3-4 Innehåll. Diskutera. Metod. Programexempel med metod

String [] argv. Dagens Agenda. Mer om arrayer. Mer om arrayer forts. String [] argv. argv är variabelnamnet. Arrayer och Strängar fortsättning

Tommy Färnqvist, IDA, Linköpings universitet

Procedurer och villkor. Rekursiva procedurer. Exempel: n-fakultet

Föreläsning 9 Innehåll

Föreläsning 4. Kö Implementerad med array Implementerad med länkad lista Djup kontra bredd Bredden först mha kö

6 Rekursion. 6.1 Rekursionens fyra principer. 6.2 Några vanliga användningsområden för rekursion. Problem löses genom:

Algoritmer, datastrukturer och komplexitet

Det är principer och idéer som är viktiga. Skriv så att du övertygar rättaren om att du har förstått dessa även om detaljer kan vara felaktiga.

Föreläsning 3-4 Innehåll

Föreläsning REPETITION & EXTENTA

Quicksort. Koffman & Wolfgang kapitel 8, avsnitt 9

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

Hitta k största bland n element. Föreläsning 13 Innehåll. Histogramproblemet

Lösningsförslag till exempeltenta 1

Föreläsning 9 Innehåll. Söndra och härska. Fibonaccitalen. Söndra och härska. Divide and conquer teknik för att konstruera rekursiva algoritmer.

3. Toppkvinnor på hög Låt lådan och de två kvinnornas famnar utgöra stackarna L, K1 respektive K2. Från början finns alla kort i L.

Föreläsning 7. Träd och binära sökträd

Algoritmer. Två gränssnitt

if (n==null) { return null; } else { return new Node(n.data, copy(n.next));

Föreläsning 6: Introduktion av listor

Föreläsning 2 Datastrukturer (DAT037)

FÖRELÄSNING 2, TDDC74, VT2018 BEGREPP PROBLEMLÖSNING MED HJÄLP AV FALLANALYS PROBLEMLÖSNING MED HJÄLP AV REKURSION

Föreläsning 2. Stackar, köer och listor TDDC91,TDDE22,725G97: DALG. Innehåll. 1 ADT stack. 1.1 Tillämpningar

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Inlämningsuppgiften. Föreläsning 9 Innehåll. Träd. Datastrukturer i kursen

Tentamen i Algoritmer & Datastrukturer i Java

Objektorienterad programmering E. Algoritmer. Telefonboken, påminnelse (och litet tillägg), 1. Telefonboken, påminnelse (och litet tillägg), 2

Tommy Färnqvist, IDA, Linköpings universitet

Programmera i C Varför programmera i C när det finns språk som Simula och Pascal??

Grundläggande programmering, STS 1, VT Sven Sandberg. Föreläsning 12

Datastrukturer i kursen. Föreläsning 8 Innehåll. Träd rekursiv definition. Träd

Föreläsning 4 Datastrukturer (DAT037)

Tildatenta Lösningsskiss

LÖSNINGSFÖRSLAG Programmeringsteknik För Ing. - Java, 5p

Programkonstruktion och. Datastrukturer

Länkade listor kan ingå som en del av språket, dock ej i C Länkade listor är ett alternativ till:

Dagens föreläsning Programmering i Lisp. - Bindning av variabler (avs 14.6) fria variabler statisk/lexikalisk och dynamisk bindning

Att förstå hur man konstruerar modulära program Att kunna skapa nya funktioner Att förstå hur data skickas mellan funktioner

Tentamen i TDP004 Objektorienterad Programmering Lösningsförslag

Abstrakta datatyper. Primitiva vektorer. Deklarera en vektor

Skriv i mån av plats dina lösningar direkt i tentamen. Skriv ditt kodnummer längst upp på varje blad.

Det finns en referensbok (Java) hos tentavakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Exempel: Förel Rekursion III Nr 14. Uno Holmer, Chalmers,

Tentamen i Grundläggande Programvaruutveckling, TDA548

Föreläsning 9: Talteori

Linjärt minne. Sammanhängande minne är ej flexibelt. Effektivt

Föreläsning 8: Exempel och problemlösning

Föreläsning 8 Innehåll

Föreläsning 6: Metoder och fält (arrays)

Universitetet i Linköping Institutionen för datavetenskap Anders Haraldsson

Transkript:

Föreläsning 5 Rekursion

Föreläsning 5 Algoritm Rekursion Rekursionsträd Funktionsanrop på stacken Binär sökning Problemlösning (möjliga vägar) Läsanvisningar och uppgifter

Algoritm En algoritm är ett begränsat antal instruktioner/steg för att lösa en uppgift, som från givna indata med säkerhet leder till korrekta utdata. Precision - varje steg är noggrant bestämt Determinism -resultatet av varje steg är entydigt Ändlig - når målet efter ett ändligt antal steg

Exempel Problem: Hitta det största av tre heltal Algoritm: 1. Kalla talen a, b och c 2. Sätt x = a 3. Om b > x sätt x = b 4. Om c > x sätt x = c 5. Svar: x

Frågor Terminerar algoritmen Fungerar den för alla giltiga indata (gränsvärden) Producerar den korrekt resultat Är den tillräckligt effektiv, går den att effektivisera?

Rekursion Rekursion är en mycket mäktig problemlösnings-strategi Det är ofta det enklaste sättet att lösa ett problem och kräver ofta mycket mindre kod än alternativen (iteration) Däremot är det inte säkert att lösningen blir effektiv och specifikt brukar den kunna kräva mycket minne För den ovane känns rekursion ofta krångligt men när man fått grepp om tekniken är den oumbärlig

Rekursivt definierad talföljd Innan vi tittar på rekursion för problemlösning värmer vi upp med en rekursivt definierad talföljd Fibonacci-följden: f n = f n-1 + f n-2, n=3,4,5, f 1 = f 2 = 1 (termineringsvillkor viktigt!) static int fib(int n){ if(n==1 n==2) return 1; else return fib(n-1)+fib(n-2); }

Rekursionsträd f(4)=f(3)+f(2) f(3)=f(2)+f(1) f(2)=1 f(2)=1 f(1)=1 static int fib(int n){ if(n==1 n==2) return 1; else return fib(n-1)+fib(n-2); } Observera att vi får räkna ut f(2) två gånger

Minneshantering i JVM JVM organiserar datat till en körande java-applikation i följande områden: stackar (en per tråd), en heap, och ett metodområde (egentligen har vi också register men låt oss förenkla något). I stacken sparar tråden lokala variabler, parametrar, och metodanrop. Endast primitiva typer och referenser finns här inga objekt Det finns bara en heap. Här bor alla objekt som skapas. Metodområdet består av alla klass-variabler som programmet använder och delas av alla trådar. Innehåller precis som stacken endast primitiva datatyper och referenser.

Stacken vid funktionsanrop När en funktion anropas så skapas utrymme på stacken för de lokala variablerna, parametrarna och återhoppsadressen

Rekursivt-iterativt Det är bevisat matematiskt att alla problem som kan lösas rekursivt också kan lösas iterativt Att hitta den iterativa lösningen kan däremot vara svårt. Fibbonaci: Rekursivt: static int fib(int n){ if(n==1 n==2) return 1; else return fib(n-1)+fib(n-2); }//O(2 n ) Iterativt: static int fib(int nfinal) { int fn=1,fnminus1=1,fnminus2=1; for(int n=3;n<=nfinal;n++) { fn=fnminus1+fnminus2; fnminus2=fnminus1; fnminus1=fn; } return fn; }//O(n) Varje värde beräknas en gång! Ännu bättre: f n 1 5 2 O(1) n 1 2 5 5 n

Svansrekursivt Endast ett rekursivt anrop och detta kommer sist. Smarta kompilatorer kan automatiskt omvandla svansrekursion till iteration och därmed spara utrymme på stacken. Om kompilatorn inte gör detta kommer den svansrekursiva lösningen antagligen vara ineffektivare och ta mer minne än den iterativa trots att de har samma ordo pga overheaden vid funktionsanrop. Fibonaci: static int fib(int n)//wrapper, kräver n>2 { return fn(1,1,3,n); } static int fn(int fnminus1,int fnminus2,int n,int nfinal) { if(n==nfinal) return fnminus1+fnminus2; else return fn(fnminus1+fnminus2,fnminus1,n+1,nfinal); }

Fakultet Nu ska vi titta på ett av de mest klassiska av problem att lösa rekursivt nämligen fakultet: Definition: n! = 1 2 (n-1) n Exempel 5! = 1 2 3 4 5 Den rekursiva lösningen får vi genom att observera att 5! = 5 4! eller n!=n (n-1)! Rekursivt: int fak(int n) { if(n==0) return 1; else return n*fak(n-1); }//O(n) Iterativt: int fak(int nfinal) { int fakn=1; for(int n=2;n<=nfinal;n++) fakn*=n; return fakn; }//O(n)

Linjär sökning i array Vi söker efter ett objekt i en array med n element genom att börja med första elementet och jobba oss framåt I genomsnitt krävs (1+n)/ jämförelser om objektet finns. Om objektet inte finns krävs alltid n jämförelser Linjär sökning är O(n)

Algoritm för rekursiv linjär sökning Om arrayen är tom return -1 annars om första elementet matchar returnera första elementets index annars returnera resultatet av en sökning av arrayen exklusive första elementet

Kod //Wrapper public static int linearsearch(object[] array, Object target){ return linearsearch(array,target, 0); } private static int linearsearch(object[] array, Object target, int position){ if(position== array.length) return -1; else if(target.equals(array[position])) return position; else return linearsearch(array, target, position+1); }

Binär sökning Bygger på att vi letar i ett sorterat material. Algoritm: if the array is empty return 1 else if the middle element matches the target return the subscript of the middle element else if the target is less than the middle element search the array elements before the middleelement and return the result else search the array elements after the middle element and return the result

private static int binarysearch(object[] items, Comparable<Object> target, int first, int last) { if (first > last) { return -1; // Base case for unsuccessful search. } else { int middle = (first + last) / 2; // Next probe index. int compresult = target.compareto(items[middle]); if (compresult == 0) { return middle; // Base case for successful search. } else if (compresult < 0) { return binarysearch(items, target, first, middle - 1); } else { return binarysearch(items, target, middle + 1, last); } } } public static int binarysearch(object[] items, Comparable<Object> target) { return binarysearch(items, target, 0, items.length - 1); }

Analys av binär sökning Låt oss analysera värsta fallet då objektet vi söker saknas. T(1) = 1 (egentligen 6 men vi struntar här i sådana skillnader eftersom vi endast är intresserade av ordo) T(n) = 1 + T(n/2) (halverar materialet vid varje steg) Detta ger: Jmf: T(1) = 1 1+log 2 1 = 1 T(2) = 1 + T(1) = 2 1+log 2 2 = 2 T(4) = 1 + T(2) = 3 1+log 2 4 = 3 T(8) = 1 + T(4) = 4 1+log 2 8 = 4 En dubbling av sökmaterialet ger en ökning med 1 T(n) = O(log(n)) log(2 n )=nlog(2) log(2 n+1 )=(n+1)log(2)

Största gemensamma delaren Greatest common divisor: gcd(78,21)=3 Fås enklast med Euklides algoritm: gcd(78,21) 78 = 3 21 + 15 ger gcd(21,15) 21 = 1 15 + 6 ger gcd(15,6) 15 = 2 6 + 3 ger gcd(6,3) 6 = 2 3 + 0 ger gcd(3,0) och då är svaret 3! Algoritm gcd(a,b) Om b ==0 return a annars return gcd(b,a%b) Skriv kod och testa!

Antal möjliga vägar Hur många unika vägar finns det från övre högra hörnet till nedre vänstra hörnet om vi bara får gå väst och syd?

Lösning Vi löser problemet genom att gå alla vägar och räkna hur många det blir. Låt m vara antal rader och n vara antal kolumner Vid varje vägval kan vi då välja att gå väst och därmed minska n med ett eller gå syd och minska m med ett När m och n är noll är vi framme och har därmed hittat en väg n = 6 m = 5

Algoritm antalvägar(m,n) Om m = 0 och n = = 0 returnera 1 annars antal = 0 om m > 0 antal = antalvägar(m-1,n) om n > 0 antal = antal + antalvägar(m,n-1) returnera antal Skriv kod

static int numberroads(int m, int n){ if(n==0 && m==0) return 1; else{ int numberroads = 0; if(m>0) numberroads = numberroads(m-1,n); if(n>0) numberroads += numberroads(m,n-1); return numberroads; } }

Rekursionsträd antalvägar(m,n) Om m = 0 och n = = 0 returnera 1 annars antal = 0 om m > 0 antal = antalvägar(m-1,n) om n > 0 antal = antal + antalvägar(m,n-1) returnera antal djupet först!

Läsanvisning och uppgifter KW 5.1, 5.2, 5.3 Uppgifter: Obs extra viktigt att göra många uppgifter på rekursion! Avsnitt 5.3: NB 16 (1p), 17 (2p), 18 (2p), 19

Uppgifter NB 16 (1p) Skriv en rekursiv static metod som hittar största värdet i en array av ints. Skriv en rekursiv static metod som beräknar x n där n är ett positivt heltal. Skriv en iterativ metod som löser samma uppgift. Skriv en metod som beräknar roten ur ett tal större eller lika med 1 med tre decimalers noggrannhet med hjälp av den rekursiva algoritmen nedan. e styr noggrannheten och a kan sättas till 1 initialt. a om a ROT( n, a, e) 2 a n ROT( n,, e) 2a 2 n e annars

NB 17 (2p) Myntmaskinen En maskin har en display på vilken den visar uppnådd poäng. Från början visar displayen 1 poäng. Genom att stoppa mynt i maskinen kan poängen förändras: Genom en 10-öring multipliceras poängen på displayen med 3 Genom en 5-öring adderas 4 till poängen på displayen. Skriv ett program som tar emot den poäng som ska uppnås. Programmet ska sedan beräkna lägsta belopp som krävs för att uppnå poängen. Observera att man inte kan nå målet för alla slutpoäng. En exempelkörning Vilken poäng ska uppnås: 109 Poängen kan nås med 45 öre Tips: Försök inte lösa uppgiften baklänges för det är svårare. Räkna istället upp poängen mot det givna målet.

NB 18 (2p) Skriv en rekursiv statisk metod som tar en textsträng med ett tal i binär form och returnerar motsvarande heltal. Använd en wrapper-metod om det behövs. Exempel: 1011 ska returnera 11. Skriv också en metod som tar en int och returnerar en sträng med det binära talet. Även här behöver du antagligen en wrapper-metod.

NB 19 En robot ska flytta om 5 paket så att de ligger i bokstavsordning. Den har två funktioner: byta plats på de två paketen längst till vänster (b) lägga paketet längst till höger längst till vänster (f) Skriv ett program som läser in en godtycklig ordning och tar reda på minsta antal drag roboten behöver och tillhörande dragordning. Ex: Ordning: BECAD Tar 7 steg: bsssbsb