Algorytmy i Struktury Danych.

Transkrypt

Algorytmy i Struktury Danych.
Algorytmy i Struktury Danych.
Rekurencja
dr hab. Bożena Woźna-Szcześniak
[email protected]
Jan Długosz University, Poland
Wykład 3
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
1 / 61
Rekurencja I
Rekurencja polega na rozwiazywaniu
˛
problemu w oparciu o
rozwiazania
˛
tego samego problemu dla danych o mniejszych
rozmiarach.
W informatyce rekurencja jest technika˛ programistyczna,
˛
polegajac
˛ a˛ na wywoływaniu funkcji wewnatrz
˛ niej samej.
Rekurencja jest jedna˛ z najbardziej interesujacych
˛
technik
programistycznych i to w dodatku technika˛ zaskakujaco
˛
efektywna.
˛
Rekurencyjny opis obliczeń jest na ogół bardziej zwarty niż opis
tych samych obliczeń bez użycia rekurencji. Taki opis jest
stosowany np. przy opisie fraktali.
Niektóre rozwiazania
˛
rekurencyjne moga˛ być nieefektywne. W
takich przypadkach można je zastapić
˛ rozwiazaniami
˛
wykorzystujacymi
˛
zwyczajna˛ petle lub stos.
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
2 / 61
Rekurencja II
Funkcja rekurencyjna cyklicznie wywołuje sama˛ siebie, za każdym
razem przekazujac
˛ w wywołaniu inne argumenty.
Przekazanie argumentu o pewnej wartości powoduje, że funkcja
kończy działanie bez kolejnego wywołania samej siebie. Sytuacja
ta jest nazywana przypadkiem bazowym.
Gdy najbardziej ”wewnetrzne”
˛
wywołanie funkcji zostaje
zakończone, rozpoczyna sie˛ proces zakańczania kolejnych
wywołań, który w końcu doprowadza do zakonczenia
poczatkowego wywołania.
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
3 / 61
Indukcja matematyczna
Programowanie rekurencyjne jest bezpośrednio zwiazana
˛
z
indukcja˛ matematyczna˛ - technika dowodzenia własności funkcji
dyskretnych.
Udowodnienie, że pewne twierdzenie odwołujace
˛ sie˛ do liczby
całkowitej N jest prawdziwe dla nieskończenie wielu wartości N
przy pomocy indukcji matematycznej składa sie˛ z dwóch etapów:
Przypadek bazowy - udowadniamy, że twierdzenie jest prawdziwa
dla jakiejś określonej wartości (zwykle 0 lub 1).
Krok indukcyjny - główna cz˛eścia˛ dowodu. Zazwyczaj zakładamy,
że twierdzenie jest prawdziwe dla wszystkich liczb całkowitych
dodatnich mniejszych niż N, a nastepnie
˛
wykorzystujac
˛ ten fakt,
udowodniamy, że jest prawdziwe dla N.
Taki dowód jest wystarczajacy,
˛ aby wykazać, że twierdzenie jest
prawdziwe dla wszystkich N.
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
4 / 61
Rozważane problemy rekurencyjne
Funkcja silnia - Hello word dla rekurencji :)
Algorytm Euklidesa
Liczba trójkatna
˛
Potegi
˛ liczby naturalnej a
Ciag
˛ Fibonacciego
Wieże Hanoi
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
5 / 61
Funkcja silnia n! = 1 · 2 · . . . · n
Algorytm iteracyjny:
long long factorial(int n)
{
if (n==0) return 1;
int i = 1;
long long s = 1;
while (i <= n)
s *= i++;
return s;
}
Require: Liczba n
1: i = 1;
2: silnia = 1;
3: while i <= n do
4:
silnia = silnia * i;
5:
i= i+1;
6: end while
7: return silnia;
Złożoność czasowa: Θ(n).
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
6 / 61
Funkcja silnia - wersja rekurencyjna
silnia(n) =
1
n ∗ silnia(n − 1)
dla n = 0 Przypadek bazowy
dla n > 0 Krok redukcji
Ślad obliczeń:
Kod C++:
long long silnia(int n)
{
if (n==0) return 1;
return n*silnia(n-1);
}
Bożena Woźna-Szcześniak (AJD)
silnia(4)
silnia(3)
silnia(2)
silnia(1)
silnia(0)
return 1
return 1*1 = 1
return 2*1 = 2
return 3*2 = 6
return 4*6 = 24
Algorytmy i Struktury Danych.
Wykład 3
7 / 61
Czasowa złożoność obliczeniowa
T (n) - czas potrzebny do wykonania funkcji silnia (n) dla
dowolnego wejścia o rozmiarze n.
Przypadek bazowy: T (0) = 1 (jednostkowy czas pracy, gdy
algorytm działa na wejściu wielkości 1);
Krok indukcyjny: Dla wejścia o rozmiarze n, algorytm wykonuje
prace˛ jednostkowa˛ realizujac
˛ operacje porównania, mnożenia (tj.
n ∗ silnia(n − 1)) oraz zwrotu wartości, a nastepnie
˛
wywołuje sam
siebie dla wejścia o rozmiarze n − 1. Zatem otrzymujemy
nastepuj
˛ ace
˛ równanie:
T (n) = T (n − 1) + 1 dla n > 0.
Jeśli rozwiniemy rekurencje˛ otrzymujemy:
T (0) = 1, T (1) = T (0) + 1 = 1 + 1 = 2
T (2) = T (1) + 1 = 2 + 1 = 3, T (3) = T (2) + 1 = 3 + 1 = 4
T (4) = T (3) + 1 = 4 + 1 = 5, . . ., T (n) = n + 1
Zatem T (n) = Θ(n).
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
8 / 61
Najwiekszy
˛
Wspólny Dzielnik - Algorytm Euklidesa
Wejście: dwie liczby naturalne a, b.
Wyjście: najwiekszy
˛
wspólny dzielnik
liczb a i b.
Rozwiazanie
˛
rekurencyjne:
NWD(a, b) =
a
NWD(b, a mod b)
Bożena Woźna-Szcześniak (AJD)
dla b = 0
dla b > 0
Algorytmy i Struktury Danych.
Euklides z
Aleksandrii ok.
365-300 p.n.e.
Wykład 3
9 / 61
Najwiekszy
˛
Wspólny Dzielnik - kod C++
//wersja rekurencyjna
long long NWD(int a, int b)
{
if (b==0) return a;
else return NWD(b,a%b);
}
//wersja iteracyjna
long long NWD2(int a, int b)
{
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
Bożena Woźna-Szcześniak (AJD)
Ślad obliczeń
nwd(1440, 408)
nwd(408, 216)
nwd(216, 192)
nwd(192, 24)
nwd(24, 0)
return 24
return 24
return 24
return 24
return 24
Algorytmy i Struktury Danych.
Wykład 3
10 / 61
Złożoność czasowa NWD
Twerdzenie: Gabriel Lamé, 1844
Dla n ≥ 1, niech u i v bed
˛ a˛ liczbami całkowitymi takimi, że u > v > 0
oraz algorytm euklidesa zastosowany do u i v wymaga dokładnie n
dzieleń oraz u jest najmniejsza˛ możliwa˛ wartościa˛ spełniajacych
˛
te
warunki. Wówczas u = F (n + 2) oraz v = F (n + 1), gdzie F (k ) jest
liczba˛ Fibonacciego a .
Ponadto, liczba kroków algorytmu Euklidesa nie przekracza wartości 5
razy ilość cyfr w mniejszej liczbie.
a
(D. Knuth. The Art of Computer Programming, Tom. 2, Addison-Wesley,
1998., str. 343)
Ograniczenie
5 może być dalej zmniejszone do ln(10)/lnφ , gdzie
√
1+ 5
(φ = 2 = 1.618033988749894848204586834365638117720 . . .)
jest złotym podziałem.
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
11 / 61
Złożoność czasowa NWD
Przykład: Niech a = 3 a b = 2.
Algorytm NWD wykonał 2 obroty, aby obliczyć NWD z a i b:
NWD(3, 2) = NWD(2, 1) = NWD(1, 0) = 1
Ograniczenie zgodne z Tw. Gabriel Lamé: 5 ∗ 1 = 5
Ulepszone ograniczenie: 1 · ln(10)/ln(1.62) = 4, 77
Przykład: Niech a = 8 a b = 5.
Algorytm NWD wykonał 4 obroty, aby obliczyć NWD z a i b:
NWD(8, 5) = NWD(5, 3) = NWD(3, 2) = NWD(2, 1) =
NWD(1, 0) = 1
Ograniczenie zgodne z Tw. Gabriel Lamé: 5 ∗ 1 = 5
Ulepszone ograniczenie: 1 · ln(10)/ln(1.62) = 4, 77
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
12 / 61
Złożoność czasowa NWD
Przykład: Niech a = 55 a b = 34.
Algorytm NWD wykonał 8 obrotów, aby obliczyć NWD z a i b:
NWD(55, 34) = NWD(34, 21) = NWD(21, 13) = NWD(13, 8) =
NWD(8, 5) = NWD(5, 3) = NWD(3, 2) = NWD(2, 1) =
NWD(1, 0) = 1
Ograniczenie zgodne z Tw. Gabriel Lamé: 5 ∗ 2 = 10
Ulepszone ograniczenie: 2 · ln(10)/ln(1.62) = 2 · 4, 77 = 9, 54
Niech a = 89 a b = 55.
Algorytm NWD wykonał 9 obrotów, aby obliczyć NWD z a i b:
NWD(89, 55) = NWD(55, 34) = NWD(34, 21) = NWD(21, 13) =
NWD(13, 8) = NWD(8, 5) = NWD(5, 3) = NWD(3, 2) = NWD(2, 1)
= NWD(1, 0) = 1.
Ograniczenie zgodne z Tw. Gabriel Lamé: 5 ∗ 2 = 10
Ulepszone ograniczenie: 2 · ln(10)/ln(1.62) = 2 · 4, 77 = 9, 54
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
13 / 61
Złożoność czasowa NWD
Przykład: Niech a = 144 a b = 55.
Algorytm NWD wykonał 9 obrotów, aby obliczyć NWD z a i b:
NWD(144, 55) = NWD(55, 34) = NWD(34, 21) = NWD(21, 13) =
NWD(13, 8) = NWD(8, 5) = NWD(5, 3) = NWD(3, 2) =
NWD(2, 1) = NWD(1, 0) = 1
Ograniczenie zgodne z Tw. Gabriel Lamé: 5 ∗ 2 = 10
Ulepszone ograniczenie: 2 · ln(10)/ln(1.62) = 2 · 4, 77 = 9, 54
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
14 / 61
Liczby trójkatne
˛
Liczby trójkatne:
˛
1, 3, 6, 10, 15, 21, itd..
n-ty element ciagu
˛ otrzymujemy poprzez dodanie liczby n do
poprzedniego elementu ciagu,
˛
tj.:
drugi element ciagu
˛ to 2 plus wartość pierwszego elementu (czyli
1), co daje 3.
trzeci element ciagu
˛ to 3 plus 3 (wartość drugiego elementu), co
daje 6;
itd.
Liczby trójkatne
˛
można przedstawić za pomoca˛ odpowiedniej
ilości obiektów (kulek, pudełek, itp.) rozmieszczonych w formie
trójkata:
˛
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
15 / 61
Algorytm obliczajacy
˛ n-ta˛ liczbe˛ trójkatn
˛ a˛
Algorytm: triangle (n)
1: if n< 1 then
2:
return 0;
3: end if
4: if n==1 then
5:
return 1;
6: else
7:
return n+ triangle(n - 1);
8: end if
Bożena Woźna-Szcześniak (AJD)
//wersja rekurencyjna
int triangle (int n)
{
if (n<1) return 0;
if (n==1) return 1;
else
return n+triangle(n-1);
}
//wersja iteracyjna
int triangle2 (int n) {
int total = 0;
while (n>0) {
total += n--;
}
return total;
}
Algorytmy i Struktury Danych.
Wykład 3
16 / 61
Algorytm obliczajacy
˛ n-ta˛ liczbe˛ trójkatn
˛ a˛
Algorytm: triangle (n)
1: if n< 1 then
2:
return 0;
3: end if
4: if n==1 then
5:
return 1;
6: else
7:
return n+ triangle(n - 1);
8: end if
Bożena Woźna-Szcześniak (AJD)
Ślad obliczeń
triangle(4)
triangle(3)
triangle(2)
triangle(1)
return 1
return 2+1=3
return 3+3=6
return 4+6=10
Algorytmy i Struktury Danych.
Wykład 3
17 / 61
Czasowa złożoność obliczeniowa
T (n) - czas potrzebny do wykonania funkcji triangle (n) dla
dowolnego wejścia o rozmiarze n.
Przypadek bazowy: T (1) = 1 (jednostkowy czas pracy, gdy
algorytm działa na wejściu wielkości 1);
Krok indukcyjny: Dla wejścia o rozmiarze n, algorytm wykonuje
prace˛ jednostkowa˛ realizujac
˛ operacje porównania, dodawania (tj.
n + triangle(n − 1)) oraz zwrotu wartości, a nastepnie
˛
wywołuje
sam siebie dla wejścia o rozmiarze n − 1. Zatem otrzymujemy
nastepuj
˛ ace
˛ równanie:
T (n) = T (n − 1) + 1 dla n > 0.
Jeśli rozwiniemy rekurencje˛ otrzymujemy:
T (0) = 1, T (1) = T (0) + 1 = 1 + 1 = 2
T (2) = T (1) + 1 = 2 + 1 = 3, T (3) = T (2) + 1 = 3 + 1 = 4
T (4) = T (3) + 1 = 4 + 1 = 5, . . ., T (n) = n + 1
Zatem T (n) = Θ(n).
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
18 / 61
Rekurencja - obliczanie an
an = pow(a, n) =
1
a ∗ pow(a, n − 1)
dla n = 0
dla n > 0
Ślad obliczeń
long long pow(int a, int n)
{
if (n==0) return 1;
else return a*pow(a,n-1);
}
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
pow(2,3)
pow(2,2)
pow(2,1)
pow(2,0)
return 1.
return 2*1 = 2
return 2*2 = 4
return 2*4 =8
Wykład 3
19 / 61
Czasowa złożoność obliczeniowa
T (n) - czas potrzebny do wykonania funkcji pow(a,n) dla
dowolnego wejścia o rozmiarze n.
Przypadek bazowy: T (0) = 1 (jednostkowy czas pracy, gdy
algorytm działa na wejściu wielkości 1);
Krok indukcyjny: Dla wejścia o rozmiarze n, algorytm wykonuje
prace˛ jednostkowa˛ realizujac
˛ operacje porównania, mnożenia (tj.
a ∗ pow(a, n − 1)) oraz zwrotu wartości, a nastepnie
˛
wywołuje
sam siebie dla wejścia o rozmiarze n − 1. Zatem otrzymujemy
nastepuj
˛ ace
˛ równanie:
T (n) = T (n − 1) + 1 dla n > 0.
Jeśli rozwiniemy rekurencje˛ otrzymujemy:
T (0) = 1, T (1) = T (0) + 1 = 1 + 1 = 2
T (2) = T (1) + 1 = 2 + 1 = 3, T (3) = T (2) + 1 = 3 + 1 = 4
T (4) = T (3) + 1 = 4 + 1 = 5, . . ., T (n) = n + 1
Zatem T (n) = Θ(n).
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
20 / 61
Ciag
˛ Fibonacciego
Liczby naturalne tworzace
˛ ciag
˛ o takiej własności, że kolejny
wyraz (z wyjatkiem
˛
dwóch pierwszych) jest suma˛ dwóch
poprzednich nazywa sie˛ liczbami Fibonacciego.
Poczatkowe
˛
wartości tego ciagu
˛ to:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, . . .
Ciag
˛ Fibonacciego zawdziecza
˛
swoja˛ nazwe˛ włoskiemu
matematykowi z Pizy, Leonardowi, który pod nazwiskiem
Fibonacci wydał w 1202 roku słynna˛ ksieg
˛ e˛ Liber Abaci
zawierajac
˛ a˛ opis tego ciagu
˛ jako rozwiazanie
˛
zadania o
rozmnażaniu sie˛ królików. Ojciec Leonarda nosił przydomek
Bonacci, stad
˛ syn został Fibonaccim (filius Bonacci - syn
dobrotliwego).
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
21 / 61
Ciag
˛ Fibonacciego - rozmnażanie królików
Zadanie Fibonacciego: Ile par królików może spłodzić jedna
para w ciagu
˛ roku, jeśli:
każda para rodzi nowa˛ pare˛ w ciagu
˛ miesiaca,
˛
para staje sie˛ płodna po miesiacu,
˛
króliki nie umieraja.
˛
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
22 / 61
Ciag
˛ Fibonacciego - rozmnażanie królików
Na poczatku
˛
– 1 para:
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
23 / 61
Ciag
˛ Fibonacciego - rozmnażanie królików
Na poczatku
˛
– 1 para:
W pierwszym miesiacu
˛ – ta sama 1 para (po 1 miesiacu
˛ króliki sa˛
zdolne do rozrodu):
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
23 / 61
Ciag
˛ Fibonacciego - rozmnażanie królików
Drugi miesiac
˛ - para wydała na świat nowa˛ pare˛ królików. Sa˛ wiec
˛
- 2 pary królików
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
24 / 61
Ciag
˛ Fibonacciego - rozmnażanie królików
Trzeci miesiac
˛ - stara para (w pionie) wydała na świat kolejna˛ pare˛
królików. Para młoda (po prawej) nie jest jeszcze płodna. Sa˛ teraz
– 3 pary królików
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
25 / 61
Ciag
˛ Fibonacciego - rozmnażanie królików
Czwarty miesiac
˛ - para środkowa wydała na świat kolejna˛ pare˛
królików. Para po prawej wydała na świat 1 pare,
˛ a para po lewej
jeszcze nie jest gotowa do rozrodu. Zatem mamy - 5 par królików.
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
26 / 61
Ciag
˛ Fibonacciego - Złoty podział
W wyniku podzielenia każdej z liczb ciagu
˛ przez jej poprzednik
otrzymuje sie˛ iloraz oscylujacy
˛ wokół 1, 618 - liczby złotego
podziału. W miare˛ zwiekszania
˛
sie˛ liczb zmniejszaja˛ sie˛
odchylenia od tej wartości. Dokładna wartość granicy jest złota˛
liczba:
˛
√
5+1
= 1, 6180339887498948482...
Φ=
2
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
27 / 61
Ciag
˛ Fibonacciego - Złoty podział
W wyniku podzielenia każdej z liczb ciagu
˛ przez jej poprzednik
otrzymuje sie˛ iloraz oscylujacy
˛ wokół 1, 618 - liczby złotego
podziału. W miare˛ zwiekszania
˛
sie˛ liczb zmniejszaja˛ sie˛
odchylenia od tej wartości. Dokładna wartość granicy jest złota˛
liczba:
˛
√
5+1
= 1, 6180339887498948482...
Φ=
2
... 233/144 = 1.61805555556
144/89 = 1.61797752809
89/55 = 1.61818181818
55/34 = 1.61764705882
34/21 = 1.61904761905
21/13 = 1.61538461538 ...
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
27 / 61
Ciag
˛ Fibonacciego - Złoty podział
W wyniku podzielenia każdej z liczb ciagu
˛ przez jej nastepnik
˛
otrzymuje sie˛ iloraz oscylujacy
˛ wokół 0, 618 - liczby złotego
podziału. W miare˛ zwiekszania
˛
sie˛ liczb zmniejszaja˛ sie˛
odchylenia od tej wartości. Dokładna wartość granicy jest złota˛
liczba:
˛
√
5−1
= 0, 618033989...
Φ=
2
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
28 / 61
Ciag
˛ Fibonacciego - Złoty podział
W wyniku podzielenia każdej z liczb ciagu
˛ przez jej nastepnik
˛
otrzymuje sie˛ iloraz oscylujacy
˛ wokół 0, 618 - liczby złotego
podziału. W miare˛ zwiekszania
˛
sie˛ liczb zmniejszaja˛ sie˛
odchylenia od tej wartości. Dokładna wartość granicy jest złota˛
liczba:
˛
√
5−1
= 0, 618033989...
Φ=
2
... 144/233 = 0.618025751073
89/144 = 0.618055555556
55/89 = 0.61797752809
34/55 = 0.618181818182
21/34 = 0.617647058824
13/21 = 0.619047619048 ...
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
28 / 61
Ciag
˛ Fibonacciego - Złoty podział
Złoty podział (łac. sectio aurea), podział harmoniczny, złota
proporcja, boska proporcja (łac. divina proportio) - podział
odcinka na dwie cz˛eści tak, by stosunek długości dłuższej z nich
do krótszej był taki sam, jak całego odcinka do cz˛eści dłuższej.
Φ=
a
a+b
=
a
b
Złotymi proporcjami wyznaczonymi na podstawie ciagu
˛
Fibonacciego posługiwał sie˛ w swoim malarstwie Leonardo da
Vinci i Botticelli.
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
29 / 61
Ciag
˛ Fibonacciego - gdzie go można znaleźć ?
Ciag
˛ Fibonacciego można odnaleźć w wielu aspektach przyrody,
ciag
˛ taki opisuje np. liczbe˛ pedów
˛
rośliny jednostajnie
przyrastajacej
˛ w latach.
W słoneczniku możemy zaobserwować dwa układy linii
spiralnych, wychodzacych
˛
ze środka. Liczba linii rozwijajacych
˛
sie˛
zgodnie z ruchem wskazówek zegara wynosi 55 i tylko 34
skreconych
˛
w przeciwna˛ strone.
˛
Takie same spirale można zaobserwować na wielu innych
roślinach (np. kalafior, ananas). Liczby spiral wystepuj
˛ acych
˛
w
tych roślinach sa˛ kolejnymi liczbami Fibonacciego.
Źródło: http://www.math.edu.pl/liczby-fibonacciego
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
30 / 61
Ciag
˛ Fibonacciego - spirala

 0
1
F (n) =

f (n − 1) + f (n − 2)
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
if n = 0
if n = 1
if n ≥ 2
Wykład 3
31 / 61
Ciag
˛ Fibonacciego - algorytm rekurencyjny
Definicja rekurencyjna:
F (0) = 0, F (1) = 1
F (n) = F (n − 1) + F (n − 2), dla n ≥ 2
Algorytm: FIB (n)
1: if n == 0 or n == 1 then
2:
return n;
3: end if
4: return FIB(n − 2) + FIB(n − 1);
Złożoność obliczeniowa:
Równanie opisujace
˛ zachowanie algorytmu:
T (n) = T (n − 1) + T (n − 2) + Θ(1) dla n √> 1 oraz T (0) = T (1) = 1.
Rozwiazanie
˛
T (n) = Θ(φn ), gdzie φ = 1+2 5 ≈ 1, 6
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
32 / 61
Ciag
˛ Fibonacciego - drzewo wywołań
F (5)
F (4)
F (2)
F (1)
F (3)
F (3)
F (0)
F (2)
F (1)
Bożena Woźna-Szcześniak (AJD)
F (1)
F (2)
F (1)
F (1)
F (0)
F (0)
Algorytmy i Struktury Danych.
Wykład 3
33 / 61
Efektywność rekurencyjnego wykonania funkcji
Fibonacciego
n
6
10
15
20
25
30
Bożena Woźna-Szcześniak (AJD)
Liczba dodawań
12
88
986
10 945
121 392
1 346 268
Liczba wywołań
25
177
1 973
21 891
242 785
2 692 537
Algorytmy i Struktury Danych.
Wykład 3
34 / 61
Ciag
˛ Fibonacciego - algorytm iteracyjny
Require: Liczba n
{F0 , . . . , Fn−1 , Fn }
Algorytm: FIB (n)
1: if n < 2 then
2:
return n;
3: else
4:
f 0 = 0;
5:
f 1 = 1;
6:
for i = 2 → n do
7:
m = f 0 + f 1;
8:
f 0 = f 1;
9:
f 1 = m;
10:
end for
11: end if
12: return m;
Bożena Woźna-Szcześniak (AJD)
Złożoność obliczeniowa: Θ(n)
Algorytmy i Struktury Danych.
Wykład 3
35 / 61
Efektywność iteracyjnego wykonania funkcji
Fibonacciego
n
6
10
15
20
25
30
Liczba przypisań
algorytm iteracyjny
15
27
42
57
72
87
Bożena Woźna-Szcześniak (AJD)
Liczba wywołań
algorytm rekurencyjny
25
177
1 973
21 891
242 785
2 692 537
Algorytmy i Struktury Danych.
Wykład 3
36 / 61
Wieże Hanoi
Definicja problemu
Dane: trzy pale A, B i C oraz N krażków
˛
o różnych średnicach.
Warunki poczatkowe:
˛
Na jeden z pali, np. na A, nałożono krażki
˛
tak, że krażek
˛
mniejszy nie leży pod wiekszym. Pale B i C sa
puste.
Problem: Przenieść wszystkie krażki z pala A na C przy
założeniu, że:
można używać B jako pomocnicze miejsce przechowywania.
nie można kłaść krażków
˛
wiekszych na mniejsze.
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
37 / 61
Wieże Hanoi - rozwiazanie
˛
rekurencyjne
Ślad wykonania
/* Przenosi n dyskow na lewo (
gdy left = true)
lub prawo (gdy left = false)
Wywolanie: moves(n, true); */
void moves(int n, bool left){
if (n == 0) return;
moves(n-1, !left);
if (left) cout<<n<< " left" <<
endl;
else cout<<n<< " right"<<endl;
moves(n-1, !left);
}
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
moves(2, true)
moves(1, false)
moves(0, false)
return;
1 right
moves(0, true)
return;
2 left
moves(1, false)
moves(0, true)
return;
1 right
moves (0,false)
return;
Wykład 3
38 / 61
Wieże Hanoi - wykonanie dla n = 2, 3, 4
1. 1 right
2. 2 left
3. 1 right
Bożena Woźna-Szcześniak (AJD)
1.
2.
3.
4.
5.
6.
7.
1
2
1
3
1
2
1
left
right
left
left
left
right
left
Algorytmy i Struktury Danych.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
1
2
1
3
1
2
1
4
1
right
left
right
right
right
left
right
left
right
2 left
1 right
3 right
1 right
2 left
1 right
Wykład 3
39 / 61
Złożoność obliczeniowa Wież Hanoi
T(n) - czas potrzebny do wykonania funkcji Hanoi(n) dla
dowolnego wejścia o rozmiarze n.
Algorytm rekurencyjny realizujacy
˛ problem Wież Hanoi (czyli
przeniesienie n krażków
˛
z jednego palika na drugi z zachowaniem
pewnych zasad) implikuje, że T (n) musi spełniać nastepuj
˛ ace
˛
równanie:
T (n) = 2 · T (n − 1) + 1 dla n > 1 oraz T (1) = 1
Przykładowo: T (1) = 1, T (2) = 3, T (3) = 7, T (4) = 15.
W ogólności: T (n) = 2n − 1 = Θ(2n )
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
40 / 61
Wieże Hanoi - algorytm iteracyjny
Niech A oznacza pal źródłowy, B pal pomocniczy, C pal docelowy oraz
n bedzie
˛
liczba˛ dysków.
1
numOfMoves= pow(2,n)- 1.
2
if (n%2 == 0) then
zamień miejscami pale $B$ i $C$.
3
for i = 1 to numOfMoves
if (i%3 == 1) then
przenieś górny dysk
if i%3 == 2 then
przenieś górny dysk
if i%3 == 0 then
przenieś górny dysk
endfor
do
z A na C
z A na B
z B na C
Złóżoność obliczeniowa: Θ(2n )
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
41 / 61
Pułapki rekursji - brakujacy
˛ przypadek bazowy
Ślad wykonania
double H(int n) {
return H(n-1) + 1.0/n;
}
Bożena Woźna-Szcześniak (AJD)
H(4), H(3), H(2), H(1), H(0), (-1),
...
Funkcja raz wywołana bedzie
˛
wywoływać siebie w
nieskończoność.
Algorytmy i Struktury Danych.
Wykład 3
42 / 61
Pułapki rekursji - brak gwarancji konwergencji
Ślad wykonania
H(4), H(4), H(4), H(4), . . .
double H(int n) {
H(1) ⇒ return 1.0
if (n == 1) return 1.0;
return H(n) + 1.0/n;
Funkcja wywołana dla n = 1 zwróci
}
wartość 1 i zakończy sie, w
każdym innym przypadku bedzie
˛
wywoływać siebie w
nieskończoność.
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
43 / 61
Pułapki rekursji - wadliwy warunek bazowy
Ślad wykonania
long H (int n){
if (n == 1) return 1;
else
if (n % 2 == 0)
return H(n-2)*n;
else
return H(n-1)*n;
}
Bożena Woźna-Szcześniak (AJD)
H(1) ⇒ return 1
H(5), H(4), H(2), H(0), . . .
H(6), H(4), H(2), H(0), . . .
Funkcja wywołana dla n = 1 zwróci
wartość 1 i zakończy sie, w
każdym innym przypadku bedzie
˛
wywoływać siebie w
nieskończoność.
Algorytmy i Struktury Danych.
Wykład 3
44 / 61
Pułapki rekursji - nadmierne wymagania pamieciowe
˛
double H(int n) {
if (n == 0)
return 0.0;
return H(n-1) + 1.0/n;
}
Funkcja rekurencyjna H
poprawnie oblicza n-ta˛ liczbe˛
harmoniczna.
˛ Jednakże, nie
można jej używać dla dużych n,
gdyż głebokość
˛
rekurencji jest
proporcjonalna do n, a to
powoduje przepełnienie stosu
programu już przy n = 261897.
Bożena Woźna-Szcześniak (AJD)
double H1(int n) {
double suma = 0.0;
while (n!=0){
suma+= 1.0/n;
n--;
}
return suma;
}
Funkcja nierekurencyjna H1
również poprawnie oblicza n-ta˛
liczbe˛ harmoniczna˛ imożna ja˛
stosować dla dużych n.
Przykładowo, dla
n = 500000000 Uzyskaliśmy
wartość 20.6073 w czasie 1
sek.
Algorytmy i Struktury Danych.
Wykład 3
45 / 61
Fraktale
Fraktale,
czyli jak piekna
˛
może być
matematyka i rekurencja !
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
46 / 61
Zbiory Julii - Gaston Julia 1893 - 1978
F (0) = p; F (n + 1) = F (n)2 + c;
gdzie:
p - punkt płaszczyzny
c - liczba zespolona bed
˛ aca
˛ parametrem zbioru.
Dla różnych c otrzymujemy różne zbiory.
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
47 / 61
Zbiory Mandelbrota (fraktalne żółwie)
F (0) = (0, 0); F (n + 1) = F (n)2 + c;
gdzie:
c - liczba zespolona bed
˛ aca
˛ parametrem zbioru.
Dla różnych c otrzymujemy różne zbiory.
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
48 / 61
Fraktale
Najstarsze fraktale wymyślili
matematycy na poczatku
˛
XX-wieku,
w wyniku zmagań z definicja˛ wymiaru
i krzywej.
Najwybitniejszym twórca˛ fraktali jest
amerykański matematyk i informatyk
polskiego pochodzenia - Benoit
Mandelbrot. Na miedzynarodowym
˛
kongresie matematyków w
Warszawie w roku 1983 stwierdził, że
jest jeszcze za wcześnie na
Źródło: http://en.
formułowanie ścisłej definicji fraktala wikipedia.org/wiki/
ponieważ nie znamy dostatecznie
Benoit_Mandelbrot
głeboko
˛
istoty tego pojecia.
˛
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
49 / 61
Czym jest fraktal?
“Fraktalem jest wszystko...”
Benoit Mandelbrot
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
50 / 61
Czym jest fraktal?
“Fraktalem jest wszystko...”
Benoit Mandelbrot
Fraktal jest figura˛ geometryczna˛ o złożonej strukturze, nie bed
˛ aca
˛
krzywa,
˛ powierzchnia˛ ani bryła˛ w rozumieniu klasycznej
matematyki; charakteryzuje ja˛ ułamkowy wymiar (stad
˛ nazwa
fraktal -ang. ’fraction’ ułamek, łac. ’fractus’ złamany).
Fraktale sa˛ bardzo skomplikowane. Dopiero komputery umożliwiły
ich głebsze
˛
poznanie.
Wielu badaczy twierdzi, że geometria fraktali jest geometria˛
przyrody.
Fraktale dały poczatek
˛
nowej geometrii zwanej geometria˛
fraktalna,
˛ która pozwala modelować wiele obiektów i zjawisk
wystepuj
˛ acych
˛
w przyrodzie i nie tylko ...
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
50 / 61
Cechy fraktali
Fraktale maja˛ ceche˛ samopodobieństwa.
Nie sa˛ określone wzorem matematycznym, tylko zależnościa˛
rekurencyjna.
˛
Sa˛ obiektami których wymiar nie jest liczba˛ całkowita.
˛
Każdy fraktal można w nieskończoność przybliżać.
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
51 / 61
Cechy fraktali
Fraktale maja˛ ceche˛ samopodobieństwa.
Nie sa˛ określone wzorem matematycznym, tylko zależnościa˛
rekurencyjna.
˛
Sa˛ obiektami których wymiar nie jest liczba˛ całkowita.
˛
Każdy fraktal można w nieskończoność przybliżać.
Kalafior
Bożena Woźna-Szcześniak (AJD)
Brokuł
Algorytmy i Struktury Danych.
Drzewo
Wykład 3
51 / 61
Zbiór Georga Cantora (1845 - 1918)
Pierwsze fraktale powstały na przełomie XIX i XX wieku. Ich
twórcami byli matematycy: Georg Cantor, David Hilbert, Helge
von Koch oraz Wacław Sierpiński.
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
52 / 61
Zbiór Georga Cantora (1845 - 1918)
Pierwsze fraktale powstały na przełomie XIX i XX wieku. Ich
twórcami byli matematycy: Georg Cantor, David Hilbert, Helge
von Koch oraz Wacław Sierpiński.
W roku 1883 Georg Cantor zaproponował prosta˛ konstrukcje,
˛ w
wyniku której otrzymuje sie˛ zbiór nazwany jego imieniem.
Konstrukacja: Odcinek [0, 1] dzielimy na trzy równe cz˛eści i
usuwamy środkowa.
˛ Z pozostałymi dwoma odcinkami
postepujemy
˛
analogicznie. W konsekwencji takiego postepowania
˛
w granicy nieskończonej ilości kroków powstaje zbiór punktów
Cantora.
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
52 / 61
Krzywa Kocha - Helge von Koch (1870 - 1924)
W 1904 roku szwedzki matematyk Helge von Koch zaproponował
konstrukcje˛ nazywana˛ potocznie płatkiem śniegu.
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
53 / 61
Krzywa Kocha
1
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
54 / 61
Krzywa Kocha
1
2
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
54 / 61
Krzywa Kocha
3
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
55 / 61
Krzywa Kocha
3
4
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
55 / 61
Krzywa Kocha
0)
1)
3)
4)
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
2)
Wykład 3
56 / 61
Dywan Sierpińskiego
W 1916 roku Wacław Sierpiński
(14.03.1882- 21.10.1969) rozszerzył
zbiór Cantora na dwa wymiary.
Kwadrat jednostkowy dzielimy na
dziewieć
˛ i wyrzucamy środkowy.
Postepujemy
˛
tak z każdym nowo
powstałym kwadratem. Powstały
fraktal nazywany dywanem
Sierpińskiego.
Analogicznie można postapić
˛ z
trójkatem,
˛
którego boki dzielimy na
dwie cz˛eści i powstałe punkty
łaczymy
˛
co doprowadzi do powstania
kolejnego trójkata,
˛ który usuwamy. Z
pozostałymi trzema postepujemy
˛
podobnie, itd.
Bożena Woźna-Szcześniak (AJD)
Źródło:http:
//www.gap-system.
org/~history/
Biographies/
Sierpinski.html
Algorytmy i Struktury Danych.
Wykład 3
57 / 61
Dywan Sierpińskiego
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
58 / 61
Trójkat
˛ Sierpińskiego
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
59 / 61
Trójkat
˛ Sierpińskiego
Bożena Woźna-Szcześniak (AJD)
Algorytmy i Struktury Danych.
Wykład 3
60 / 61
Krzywa Hilberta
Krzywa Hilberta - to przykład krzywej, która wypełnia całkowicie
płaszczyzne,
˛ tzn. przechodzi przez wszystkie punkty płaszczyzny.
Konstrukcja tej krzywej została podana przez Davida Hilberta w
1891 jako wariant krzywej Peano.
n=1
n=2
Bożena Woźna-Szcześniak (AJD)
n=3
Algorytmy i Struktury Danych.
n=4
n=5
Wykład 3
61 / 61

Podobne dokumenty