Ladda ner presentationen
Presentation laddar. Vänta.
1
Algoritmer och datastrukturer,förel. 10
Algoritmer och datastrukturer Rekursiva funktioner Föreläsning 10 (Weiss kap. 7) Induktion och rekursion Rekursiva funktioner och processer Weiss (7.4, utgår) Fibonaccital Exempel: Balansering av mobil (kod se lab 5) Exempel: Tornen i Hanoi Tröskel - rekursion handlar om att våga lita på att något fungerar, och sedan bygga lösningen på att det fungerar rekursion <--> induktion Lökmodellen! ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
2
Ex. Räkna personer i en grupp – utan global överblick
Algoritmer och datastrukturer,förel. 10 Ex. Räkna personer i en grupp – utan global överblick :-) Rekursionsantagande: Denna grupp klarar att räkna sig själv. höger :-0 #? SCB :-) N :-| ? :-o :-) N-1 :-| ? :-o N-2 :-) 2 ? :-o :-| :-) 1 :-| :-( ….. Varje person exekverar följande rekursiva algoritm: 1. Om ingen står till vänster så ropa 1 åt höger 2. Annars, fråga grannen till vänster hur många de är. Om svaret är K så ropa K+1 åt höger. Varje person kan bara se och kommunicera med sina grannar Rekursiv metod: Basfall: Konstruera lösningen för ”det enkla fallet”. Rekursionssteg: Bryt ner problemet i ett antal likartade mindre delproblem. Gör ett rekursionsantagande: att metoden kan lösa delproblemen. Konstruera lösningen för hela problemet med hjälp av lösningarna för delproblemen med stöd av rekursionsantagandet. Ändligt, diskret antal steg mot basfallet, inga cykler. ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
3
Induktiva definitioner och rekursion
Algoritmer och datastrukturer,förel. 10 Induktiva definitioner och rekursion Ex. Induktiv definition av lista En lista är antingen (1) tom eller (2) ett element följt av en lista Basfall Syntes <-> analys En lista är liksom ett heltal ett diskret objekt. Man kan inte göra induktion över R, det måste gå att nå basfallet i ett ändligt antal steg (hur många gånger kan man halvera ett reellt tal?). Ej cirkeldefinition, snarare spiraldefinition. Rekursiva strukturer -> rekursiv analys. Induktionsfall ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
4
Ex. Summera elementen i en lista - rekursiv process
Algoritmer och datastrukturer,förel. 10 Ex. Summera elementen i en lista - rekursiv process 7 + (3 + (6 + (4 + (2 + (9 + sum( [] )))))) 7 + (3 + (6 + (4 + (2 + sum( [9] ))))) 7 + (3 + (6 + (4 + (2 + 9)))) 7 + (3 + 21) 7 + (3 + (6 + 15)) 7 + (3 + (6 + (4 + 11))) 7 + (3 + (6 + (4 + (2 + (9 + 0))))) 7 + (3 + (6 + (4 + sum( [2,9] )))) 7 + (3 + (6 + sum( [4,2,9] ))) 7 + sum( [3,6,4,2,9] ) 7 + (3 + sum( [6,4,2,9] )) sum( [7,3,6,4,2,9] ) 7 + 24 31 Rekursiv algoritm: 1. Om listan är tom är summan av elementen 0 2. Annars, summera elementen i resten av listan och addera första elementet till resultatet Rekursionshypotes: vi kan summera elementen i en mindre lista ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
5
En rekursiv listsummeringsfunktion
Algoritmer och datastrukturer,förel. 10 En rekursiv listsummeringsfunktion int sum( ListNode l ) { if ( l == null ) return 0; // Basfall else // Rekursionssteg return l.element + sum( l.next ); } int f() { return 1; } int g() { return 1 + f(); } int h() { return 1 + g(); } int hrec(int n) { if (n == 0) return 1; else return 1 + hrec(n-1); } int h() { return hrec(3); I båda fallen har varje instans sina egna variabler = aktiveringspost Rekursionsantagande: Algoritmen kan summera elementen i en kortare lista. ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
6
Iterativa och rekursiva processer
Algoritmer och datastrukturer,förel. 10 Iterativa och rekursiva processer Iterativ process En iterativ process (loop) har konstant minnesbehov (i princip) Rekursiv process En rekursiv process har variabelt minnesbehov oftast används en stack Anropsstack och aktiveringsposter Lokala funktionsvariabler lagras i aktiveringsposter, en per funktionsanrop När en funktion anropas (aktiveras) läggs en aktiveringspost på anropsstacken. Den frigörs vid retur. Detta gäller alla funktioner, inte bara rekursiva Detta sköts automatiskt! Rekursion = Iteration + Stack Funktioner returnerar i omvänd ordning till anropsordningen. Alltså behöves en stack! ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
7
En iterativ listsummeringsfunktion
Algoritmer och datastrukturer,förel. 10 En iterativ listsummeringsfunktion int sum( ListNode l ) { int s = 0; while ( l != null ) { s = s + l.element; l = l.next; } return s; } ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
8
En rekursiv process kräver minne
Algoritmer och datastrukturer,förel. 10 En rekursiv process kräver minne sum( [7,3,6,4,2,9] ) 7 + sum( [3,6,4,2,9] ) 7 + (3 + sum( [6,4,2,9] )) 7 + (3 + (6 + sum( [4,2,9] ))) 7 + (3 + (6 + (4 + sum( [2,9] )))) Maximalt minnesbehov 7 + (3 + (6 + (4 + (2+ sum( [9] ))))) 7 + (3 + (6 + (4 + (2 + (9 + sum( [] )))))) 7 + (3 + (6 + (4 + (2 + (9 + 0))))) 7 + (3 + (6 + (4 + (2 + 9))))) 7 + (3 + (6 + (4 + 11)))) Papper-och-penna-modell 7 + (3 + (6 + 15))) 7 + (3 + 21) 7 + 24 31 ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
9
Algoritmer och datastrukturer,förel. 10
Två exempel i Weiss Summering av tal rekursivt (Fig. 7.1) Utskrift av heltal i valfri bas (Fig ) Förutsättning: vi kan bara skriva ut ett ASCII-tecken åt gången. ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
10
Algoritmer och datastrukturer,förel. 10
Summering av serie 1 //Evaluate the sum of the first n integers 4 public static long s( int n ) 5 { 6 if ( n == 1 ) return 1; 8 else return s( n - 1 ) + n; 10 } Figure 7.1 Recursive evaluation of the sum of the first N integers Koda formeln rakt av. Fler exempel I Weiss: Ruler Fraktaler ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
11
Rekursiv utskrift av heltal i decimal form
Algoritmer och datastrukturer,förel. 10 Rekursiv utskrift av heltal i decimal form kvot (/10) rest (%10) 7 3 6 4 Skriv först ut detta tal rekursivt Skriv därefter ut detta ensiffriga tal Division med 10 om talet skall skrivas ut decimalt i bas 10. Lätt att generalisera till andra baser. Basfall: Om talet är ensiffrigt kan det skrivas ut direkt ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
12
Utskrift av heltal i decimal form
Algoritmer och datastrukturer,förel. 10 Utskrift av heltal i decimal form 1 // Print n in base 10,recursively. 2 // Precondition: n >= 0. 3 public static void printDecimal( long n ) 4 { 5 if ( n >= 10 ) printDecimal( n / 10 ); 7 System.out.print( (char)(’0’ + (n % 10))); 8 } Figure 7.2 Recursive routine for printing N in decimal form ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
13
Stackens roll vid rekursion
Algoritmer och datastrukturer,förel. 10 Stackens roll vid rekursion 15 S( 5 ) Anropsstacken 5 N S( N - 1 ) + N 1 + N 1 N 10 + N 3 + N 4 N S( N - 1 ) + N 2 N S( N - 1 ) + N 6 + N 3 N S( N - 1 ) + N ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
14
Förgreningsrekursion
Algoritmer och datastrukturer,förel. 10 Förgreningsrekursion m1 m2 Exempel: En Mobil är antingen 1. en fisk eller 2. på formen m m3 Mobil l2 l1 stång snöre m1 m2 m3 Första strukturen som inte är linjär Filsystem, aritmetiska uttryck, ... Förgrenad uppbyggnad kräver ”förgrenad analys” Kan vara svårt att se fallen i början lätt att hitta fler fall än vad som behövs ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
15
Är min mobil balanserad?
Algoritmer och datastrukturer,förel. 10 Är min mobil balanserad? Balanserad m1 m2 m3 Obalanserade m3 m2 m5 m4 m1 m2 Mobilen skall var i balans på alla nivåer Hävstångsprincipen – moment Rita en figur på tavlan! Vad är basfallet? Hur löser man det? Vad är rekursionssteget? Hur ser rekursionsantagandet ut? ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
16
Algoritmer och datastrukturer,förel. 10
Vad väger en mobil? 1. vikt( ) = m 2. vikt( ) = vikt( M1 ) + vikt( M2 ) m M1 M2 Rekursionsantagande: Denna metod kan räkna ut vikterna hos M1 och M2 Ideal mobil: pinnarna och snörena väger ingenting Det gäller att ta sig ner till vikterna ”löven” ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
17
När är en mobil balanserad?
Algoritmer och datastrukturer,förel. 10 När är en mobil balanserad? 1. En fisk är alltid balanserad 2. En mobil på formen är balanserad om M1 M2 l2 l1 och både M1 och M2 är balanserade Att sätta samman lösningen kan vara lite komplicerat Vi använder en annan rekursiv funktion i en rekursiv funktion Mångförgrenad rekursion Kod finns i lab 5 RAST Rekursionsantagande: Denna metod kan avgöra om M1 och M2 är balanserade ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
18
Algoritmer och datastrukturer,förel. 10
Fibonaccitalen Två vanliga sätt att definiera Fibonaccitalen induktivt ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
19
Algoritmer och datastrukturer,förel. 10
Lite kuriosa om Fibonaccital ”Gyllene snittet” b a Grankvist a = 1 b Granpinne Vinkelförhållandet mellan bladen på en växt sett upifrån ger optimalt ljusgenomsläpp Omsändningsintervall i Ethernet ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
20
Rekursiv beräkning av Fibonaccital
Algoritmer och datastrukturer,förel. 10 Rekursiv beräkning av Fibonaccital 1 // Compute the Nth Fibonacci Number. 2 // Bad algorithm. 3 long fib( int n ) 4 { 5 if ( n <= 1 ) return 1; 7 else return fib( n - 1 ) + fib( n - 2 ); 9 } Figure Recursive routine for Fibonacci Numbers: A bad idea. Vi kodar den matematiska definitionen rakt av Rekursiva funktioner analyseras med induktion ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
21
Algoritmer och datastrukturer,förel. 10
Problem med Fib fib(5) fib(3) fib(4) fib(1) fib(2) fib(2) fib(3) fib(0) fib(1) fib(0) fib(1) fib(1) fib(2) fib(0) fib(1) - Hur många funktionsanrop genererar anropet fib(N)? Man kan visa att det blir 1ms/anrop: fib(100) tar ca år! (1.126e15 ms) 1 mikrosekund/anrop: fib(100) tar 35 år fib(120) tar år ...:-) ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
22
Iterativ beräkning av Fibonaccital
Algoritmer och datastrukturer,förel. 10 Iterativ beräkning av Fibonaccital currentFib previousFib currentFib 1 1 2 3 5 8 ... 1 2 5 3 1 8 + 5 2 3 1 1 long FibIter( int N ) { long PreviousFib = 0, CurrentFib = 1; for ( int I = 0; I < N; i++ ) { CurrentFib += PreviousFib; PreviousFib = CurrentFib - PreviousFib; } return CurrentFib; previousFib ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
23
Skriv ut de N minsta Fibonaccitalen iterativt med loop
Algoritmer och datastrukturer,förel. 10 Skriv ut de N minsta Fibonaccitalen iterativt med loop void fibIterPrint( int n ) { long previousFib = 0, currentFib = 1; for ( int i = n; i > 0; i-- ) { System.out.println( currentFib ); long nextFib = previousFib + currentFib; previousFib = currentFib; currentFib = nextFib; } Övning: Variabeln nextFib är överflödig, eliminera den! ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
24
Returnera det N:te Fibonaccitalet iterativt med loop
Algoritmer och datastrukturer,förel. 10 Returnera det N:te Fibonaccitalet iterativt med loop long fibIter( int n ) { long previousFib = 0, currentFib = 1; for ( int i = n; i > 0; i-- ) { long nextFib = previousFib + currentFib; previousFib = currentFib; currentFib = nextFib; } return currentFib; ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
25
Fibonaccital med iterativ rekursion s.k. ”svansrekursion”
Algoritmer och datastrukturer,förel. 10 Fibonaccital med iterativ rekursion s.k. ”svansrekursion” void fibIterRekPrint(long previousFib,long currentFib,int n) { if ( n == 0) return; else { System.out.println( currentFib ); fibIterRekPrint( currentFib, previousFib + currentFib, n - 1 ); } } void fibPrint( int n ) { fibIterRekPrint(0,1,n); } Denna typ av rekursion kan av en optimerande kompilator automatiskt översättas till en loop Svansrekursion I princip samma metod som föregående Parametrarna är ett ”tillstånd” som successivt bearbetas i varje anrop Obs, ingen vidare beräkning sker med funktionsresultatet ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
26
Returnera det N:te Fibonaccitalet iterativ rekursion
Algoritmer och datastrukturer,förel. 10 Returnera det N:te Fibonaccitalet iterativ rekursion long fibIterRek( long previousFib, long currentFib, int n ) { if ( n == 0) return currentFib; else return fibIterRek( currentFib, previousFib + currentFib, n - 1 ); } long fib( int n ) { return fibIterRek( 0, 1, n ); } ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
27
Algoritmer och datastrukturer,förel. 10
Tornen i Hanoi N st. ringar av olika diametrar är uppträdda på en pinne Ingen ring ligger ovanpå en mindre ring Problem Flytta alla ringarna från pinne A till pinne B Regler Högst en ring får flyttas åt gången En ring får bara läggas ovanpå en större ring A B C Den vanliga formuleringen lär härstamma från medeltiden... Det finns en elegant iterativ lösning! ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
28
Flytta två ringar från A till C via B
Algoritmer och datastrukturer,förel. 10 Flytta två ringar från A till C via B Vilken pinne som helst får användas som mellanstation Ok, de två längst upp är båda mindre än resten Vi har löst ett problem av storlek 2 A B C ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
29
Flytta en ring från A till B
Algoritmer och datastrukturer,förel. 10 Flytta en ring från A till B A B C Återstår att lösa ett exakt likadant problem av storlek 2 kan vi redan! ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
30
Flytta två ringar från C till B via A
Algoritmer och datastrukturer,förel. 10 Flytta två ringar från C till B via A Voila! A B C ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
31
Flytta N ringar från A till B via C
Algoritmer och datastrukturer,förel. 10 Flytta N ringar från A till B via C A B C N { } N - 1 } N Övriga ringar Rekursions- antagande: Metoden kan flytta en stapel av höjd N-1 på korrekt sätt Generalisera: vi tittar på de N översta ringarna fungerar det så bör det fungera för allihop N är ju godtyckligt valt! De N-1 översta är mindre än resten - vi kan alltså lägga på dem Move(A,B,C,N) ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
32
Algoritmer och datastrukturer,förel. 10
Implementering Programmet skall skriva ut en ”arbetsbetsinstruktion” enligt följande modell: Number of rings? 3 Do the following moves: A --> B A --> C B --> C A --> B C --> A C --> B A --> B Lägg på bilden med 3-fallet igen! Jobba vidare med detta i labben Demo: hanoi ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
33
En rekursiv algoritm för Hanois torn
Algoritmer och datastrukturer,förel. 10 En rekursiv algoritm för Hanois torn 1 void move( char a, char b, char c, int n ) { if ( n > 0 ) { // move n - 1 rings from a to c via b move( a, c, b, n - 1 ); System.out.println( a + " --> " + b ); // move n - 1 rings from c to b via a move( c, b, a, n - 1 ); } 11 } 12 void hanoi( int n ) { move( 'A', 'B', 'C', n ); 14 } from to via Enkelt basfall! Sätt ihop lösn. för N mha 2 lösn. för N-1 + ”lite till” A, B, och C ”byter roller” vilka pinnar A,B,C syftar på saknar betydelse Skilj på variablerna A, B och C och tecknen ’A’, ’B’ och ’C’ Det behövs en ”startrutin” Vad har Move för komplexitet? Hur visar man det? ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
34
Tidskomplexiteten hos Hanoi
Algoritmer och datastrukturer,förel. 10 Tidskomplexiteten hos Hanoi Definition: Låt T(N) vara antalet ringförflyttningar som utförs av anropet move( X, Y, Z, N) för att flytta en stapel av N ringar från X till Y via Z. Sats: För alla gäller att d.v.s. Bevis: Induktion över N. Låt P(X) vara påståendet: Visa att P(N) gäller för varje OBS! Ej överlappande beräkningar här. Ett exempel på analys av en rekursiv funktion 1 mikros./flyttning. Hur många klarar vi på en sekund? Först: 20 tar 1 sek. 21 tar 2 sek. 26 tar 1 min. 32 tar 1 tim. 64 tar ? 128 tar ? N = 64 => år! N = 128 => 10^25 år! (jfr Avogadros tal: 6x10^23) ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
35
Algoritmer och datastrukturer,förel. 10
Bevis av satsen Vi gör induktion över N. Basfall: Visa att P(0) håller, d.v.s. Om move anropas med N = 0 är villkoret på rad 2 falskt och funktionen terminerar direkt, vilket stämmer eftersom ingenting skall flyttas om vi inte har några ringar alls! Generell egenskap: Visa P(0), P(1), P(2), ... ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
36
Algoritmer och datastrukturer,förel. 10
Induktionssteg: Visa att P(N) håller för godtyckligt N > 0, d.v.s. Först anropas move(A,C,B,N-1) (rad 4) Induktionsantagandet gäller för varje k < N och speciellt för N - 1, d.v.s. Därefter flyttas en ring från A till B (rad 6) Sist anropas move(C,B,A,N-1) (rad 9) Av induktionsantagandet följer att detta ger ytterligare förflyttningar Det totala antalet förflyttningar, T(N), blir således Induktionsantagande: Antag P(k) är sant för alla k < N Antagandet är mer generellt än nödvändigt men det visar på tekniken ©Uno Holmer, Chalmers, LET375, d2+I2, 12/13, lp 4
Liknande presentationer
© 2024 SlidePlayer.se Inc.
All rights reserved.