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 13. Dynamisk programmering

Rekursion. Koffman & Wolfgang kapitel 5

Sökning och sortering

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

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

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

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

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

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

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

Föreläsning 11: Rekursion

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

Föreläsning 13. Rekursion

Rekursion och induktion för algoritmkonstruktion

Föreläsning 6. Rekursion och backtracking

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

Föreläsning 1, vecka 7: Rekursion

Föreläsning 8 Innehåll

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.

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

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

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)

Rekursion och induktion för algoritmkonstruktion

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

DD1361 Programmeringsparadigm. Carina Edlund

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

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

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

TDDI16 Datastrukturer och algoritmer. Algoritmanalys

Tommy Färnqvist, IDA, Linköpings universitet

Teoretisk del. Facit Tentamen TDDC (6)

TENTAMEN PROGRAMMERINGSMETODIK MOMENT 2 - JAVA, 4P

Magnus Nielsen, IDA, Linköpings universitet

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

Tentamen TEN1 HI

Tentamen, Algoritmer och datastrukturer

Föreläsning 6. Rekursion och backtracking

Tommy Färnqvist, IDA, Linköpings universitet

Datastrukturer. föreläsning 2

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

Datastrukturer D. Föreläsning 2

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

Programkonstruktion och Datastrukturer

Algoritmer, datastrukturer och komplexitet

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.

Övning 2. (Länkade) Listor, noder

Föreläsning 9 Innehåll

Tentamen i Algoritmer & Datastrukturer i Java

Algoritmer, datastrukturer och komplexitet

Procedurer och villkor

Quicksort. Koffman & Wolfgang kapitel 8, avsnitt 9

Föreläsning 9. Sortering

Rekursion och induktion för algoritmkonstruktion

Föreläsning 2 Datastrukturer (DAT037)

Algoritmer. Två gränssnitt

Tommy Färnqvist, IDA, Linköpings universitet

Asymptotisk komplexitetsanalys

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

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:

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

Algoritmer, datastrukturer och komplexitet

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

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

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

Lösningsförslag till exempeltenta 1

Teoretisk del. Facit Tentamen TDDC (6)

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

Tildatenta Lösningsskiss

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

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

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

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

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

Föreläsning 6: Introduktion av listor

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

Abstrakta datatyper. Primitiva vektorer. Deklarera en vektor

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

Föreläsning REPETITION & EXTENTA

Lösningsförslag för tentamen i Datastrukturer (DAT037) från

Föreläsning 3-4 Innehåll

Våra enkla funktioner eller procedurer

Träd, binära träd och sökträd. Koffman & Wolfgang kapitel 6, avsnitt 1 4

Programmering för Språkteknologer II. Innehåll. Associativa datastrukturer. Associativa datastrukturer. Binär sökning.

Några svar till TDDC70/91 Datastrukturer och algoritmer

Föreläsning 9: Talteori

Sätt att skriva ut binärträd

BEGREPP HITTILLS FÖRELÄSNING 2 SAMMANSATTA UTTRYCK - SCHEME DATORSPRÅK

Föreläsning Datastrukturer (DAT036)

Tentamen TEN1 HI

Lösningar Datastrukturer TDA

F11 - Rekursion. ID1004 Objektorienterad programmering Fredrik Kilander

Laboration 13, Arrayer och objekt

DELPROV 1 I DATAVETENSKAP

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)

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 exakt 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 Men vad är rekursion? För att förstå rekursion måste man förstå rekursion Vi menar här främst att en metod anropar sig själv

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); 1, 1, 2, 3, 5, 8, 13, 21,

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 (och ett register). 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 kan bevisas 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 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 inte gör blir den svansrekursiva lösningen ineffektivare och kräver mer minne än den iterativa pga overheaden vid funktionsanrop (trots samma ordo). Fibonaci svansrekursivt: 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)/2 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 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 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: 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 nu

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 m=2 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 n=3 djupet först!