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