Dr Aleksander Klosow
Transkrypt
Dr Aleksander Klosow
Dr Aleksander Klosow PWSZ Legnica, 2003 www.strony.wp.pl/wp/klosov/ Algorytmy i Struktury Danych Wykład 3 REKURENCJA www.nist.gov/dads/ POJĘCIE REKURENCJI rekursja, (ang.) recursion Rekurencja występuję wtedy, gdy definiując pewien obiekt musimy się posłużyć pojęciem tego samego obiektu ! • • • • Odbicie w 2 lustrach Kamera filmująca sprzężony monitor Funkcja odwołująca się w trakcie swojego wykonania do samej siebie Algorytm wykorzystujący do rozwiązania części swojego zadania taki sam algorytm SILA REKURENCJI 1. Możliwość definiowania nieskończonego zbioru obiektów lub działań za pomocą skończonego wyrażenia 2. Jeżeli dane wejściowe są zdefiniowane rekurencyjnie PRZYKŁAD na dobry początek 0! = 1 n! = n(n-1)! unsigned long int silnia(int n) { if(n==0) return 1; else return n*silnia(n-1); }; main(){ cout << silnia(5);} DEFINICJA ALGORYTMU REKURENCYJNEGO P - algorytm rozwiązujący zadanie Si - instrukcje podstawowe algorytmu ℜ - złożenie instrukcji algorytmu P ≡ ℜ [Si, P] - podstawowa definicja algorytmu rekurencyjnego P ≡ if warunek then ℜ [Si, P] } - typowe schematy algorytmów rekurencyjnych P ≡ ℜ [Si, if warunek then P] ETAPY PROJEKTOWANIA 1. Rozbić duży problem na mniejsze powtarzające się fragmenty 2. Określić warunek stopu algorytmu 3. Wybrać właściwy schemat rekurencji ! Powody niepowodzenia: 1. Źle określone warunki stopu 2. Niewłaściwa dekompozycja problemu 0! = 1 n! = n(n-1)! = n • (n-1) • (n-2) • (n-3)...2 • 1 WYKONANIE ALGORYTMU REKURENCYJNEGO W PAMIĘCI n return silnia(5) ------------------------------------ 5 5*silnia(4) silnia(4) ------------------------------------ 4 4*silnia(3) silnia(3) ------------------------------------ 3 3*silnia(2) silnia(2) ------------------------------------ 2 2*silnia(1) silnia(1) ------------------------------------ 1 1*silnia(0) silnia(0) ------------------------------------ 0 1 REKURENCYJNE TYPY DANYCH pascal (Delphi) type osoba = record c typedef struct osoba { imie : String[10]; char imie[10]; matka : osoba; osoba matka; ojciec : osoba; osoba ojciec; end } ZALETY REKURENCJI 1. Krótki opis algorytmu, mało kodu programu, czytelność 2. Lepsza dla danych rekurencyjnych 3. 'Elegancja' w stylu programowania WADY REKURENCJI Wada 1: REDUNDANCJA OBLICZEŃ int fib(int n) { if(n<2) return 1; else return fib(n-1)+fib(n-2); } fib(4) fib(3) fib(2) fib(2) fib(1) fib(1) fib(0) fib(1) fib(0) Function Fib(n:integer):integer; begin if n<2 then Fib:=1 else Fib:=Fib(n-1)+Fib(n-2) end WADY REKURENCJI Wada 2: ZAJĘTOŚĆ PAMIĘCI Funkcja Ackermanna int A(int n, int p) { if(n==0) return 1; if((p==0) && (n>=1)) if(n==1) return 2; else return n+2; if((p>=1)&&(n>=1)) return A(A(n-1,p),p-1); } Co zwróci funkcja przy n=1, p=1 ? Co zwróci funkcja przy n=2, p=4 ? Liczba wywołań funkcji Ackermanna: A(1,4) ⇒ 2 A(2,4) ⇒ 4 A(3,4) ⇒ 65536 TYPY REKURENCJI Naturalna P ≡ ℜ [Si, P] Z parametrem P ≡ if (par>0) then ℜ [Si, P, par-1] Bezpośrednia P ≡ ℜ [..., P] Pośrednia P ≡ ℜ [..., T], T = ℑ[..., P] Terminalna P ≡ ℜ [Si, P] Nie terminalna P ≡ ℜ [Si, P, Sj] Wielokrotna P ≡ ℜ [Si, P1, P2] Zagnieżdżona P ≡ ℜ [Si, P1(P2)] KIEDY NIE STOSOWAĆ REKURENCJE Reguła 1: Kiedy rozwiązanie iteracyjne jest bardziej czytelne i zrozumiałe Lub inaczej: Kiedy można zastosować derekursywację rozwiązania rekurencyjnego DEREKURSYWACJA Proces przekształcenia algorytmu rekurencyjnego na algorytm iteracyjny Schemat dla rekurencji terminalnej P1(x) // -- program rekurencyjny { if(Warunek(x)) Instrukcja1(x) else { Instrukcja2(x); P1(F(x)); // -- rekurencja } } P2(x) // -- program iteracyjny { while(!Warunek(x)) { Instrukcja2(x); x=F(x); } Instrukcja1(x); } DEREKURSYWACJA, c.d. Schemat dla rekurencji nie terminalnej P1() // -- program rekurencyjny { if(Warunek(x)) { A(x); P1(); // -- rekurencja B(x); } else C(x); } P2(x) // -- program iteracyjny { int N=0; // -- liczba iteracji while(Warunek(x)) { A(x); N++; // -- analogicznie N=N+1 } C(x); while(N--!=0) B(x); } KIEDY STOSOWAĆ REKURENCJĘ 1. Do pewnej klasy zadań gier komputerowych 2. Do pewnej klasy zadań graficznych 3. Do pewnej klasy zadań "Algorytmy z powrotami" • Wieża Hanoi • Krzywe Hilberta • Problem skoczka szachowego