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 2 Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 1 / 47 Rekurencja Rekurencja albo rekursja (ang. recursion, z łac. recurrere, przybiec z powrotem) to w matematyce i informatyce (np. programowaniu) odwoływanie sie˛ np. definicji lub funkcji czy procedury do samej siebie. Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 2 / 47 Rekurencja Rekurencja albo rekursja (ang. recursion, z łac. recurrere, przybiec z powrotem) to w matematyce i informatyce (np. programowaniu) odwoływanie sie˛ np. definicji lub funkcji czy procedury do samej siebie. Rekurencyjny - mat. dajacy ˛ sie˛ wyrazić za pomoca˛ wielkości uprzednio znanych; wzór rekurencyjny - wzór pozwalajacy ˛ obliczyć wyrazy ciagu ˛ na podstawie jednego lub kilku wyrazów poprzedzajacych. ˛ <ang. recurrent, fr. recurrent, z łac. recurrens ’powracajacy’>. ˛ [Słownik Wyrazów Obcych, PWN, 1996] Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 2 / 47 Rekurencja Rekurencja polega na rozwiazywaniu ˛ problemu w oparciu o rozwiazania ˛ tego samego problemu dla danych o mniejszych rozmiarach. Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 3 / 47 Rekurencja 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. Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 3 / 47 Rekurencja 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. ˛ Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 3 / 47 Rekurencja 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. Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 3 / 47 Rekurencja 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 2 3 / 47 Czym jest fraktal? “Fraktalem jest wszystko...” Benoit Mandelbrot Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 4 / 47 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). Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 4 / 47 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, toteż dopiero komputery umożliwiły ich głebsze ˛ poznanie. Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 4 / 47 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, toteż dopiero komputery umożliwiły ich głebsze ˛ poznanie. Wielu badaczy twierdzi, że geometria fraktali jest geometria˛ przyrody. Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 4 / 47 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, toteż 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 2 4 / 47 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 2 5 / 47 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 2 6 / 47 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 2 6 / 47 Fraktale - Zbiór Cantora 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 2 7 / 47 Fraktale - Zbiór Cantora 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 2 7 / 47 Fraktale - Zbiór Cantora 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 2 7 / 47 Fraktale - Krzywa Kocha 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 2 8 / 47 Fraktale - Krzywa Kocha 1 Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 9 / 47 Fraktale - Krzywa Kocha 1 2 Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 9 / 47 Fraktale - Krzywa Kocha 3 Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 10 / 47 Fraktale - Krzywa Kocha 3 4 Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 10 / 47 Fraktale - Krzywa Kocha 0) 1) 3) 4) Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. 2) Wykład 2 11 / 47 Fraktale - Wacław Sierpiński 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 2 12 / 47 Fraktale - Trójkat ˛ Sierpińskiego Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 13 / 47 Fraktale - Trójkat ˛ Sierpińskiego Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 14 / 47 Fraktale - Dywan Sierpińskiego Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 15 / 47 Fraktale - 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 2 16 / 47 Inne fraktale Zbiory Julii: 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 2 17 / 47 Inne fraktale Zbiory Mandelbrota: 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 2 18 / 47 Rekurencja - podstawowe informacje Metoda rekurencyjna cyklicznie wywołuje sama˛ siebie, za każdym razem przekazujac ˛ w wywołaniu inne argumenty. Przekazanie argumentu o pewnej wartości powoduje, że metoda kończy działanie bez kolejnego wywołania samej siebie. Sytuacja ta jest nazywana przypadkiem bazowym. Gdy najbardziej ”wewnetrzne” ˛ wywołanie metody 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 2 19 / 47 Funkcja silnia n! = 1 · 2 · . . . · n - wersja iteracyjna 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; Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 20 / 47 Funkcja silnia n! = 1 · 2 · . . . · n - kod C++ #include <iostream> using namespace std; long long silnia(int n){ if (n==0) return 1; int i = 1; long long s = 1; while (i <= n) s = s * i++; return s; } int main () { cout << "Podaj liczbe n = "; int n; cin >>n; long long m = silnia (n); cout << n << "! = " << m << endl; return 0; } Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 21 / 47 Rekurencja - funkcja silnia silnia(n) = Bożena Woźna-Szcześniak (AJD) 1 n ∗ silnia(n − 1) Algorytmy i Struktury Danych. dla n = 0 dla n > 0 Wykład 2 22 / 47 Rekurencja - funkcja silnia silnia(n) = 1 n ∗ silnia(n − 1) dla n = 0 dla n > 0 Jak to wyglada w praktyce dla n = 3 (silnia(3) =?) 1 n = 0? nie, zatem oblicz 3 ∗ silnia(2) 2 n = 0? nie, zatem oblicz 2 ∗ silnia(1) 3 n = 0? nie, zatem oblicz 1 ∗ silnia(0) 4 n = 0? tak, zwróć 1. 5 zwróć 1 ∗ 1 6 zwróć 1 ∗ 1 ∗ 2 7 zwróć 1 ∗ 1 ∗ 2 ∗ 3 8 Zatem silnia(3) = 6 ! Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 22 / 47 Funkcja silnia - wersja rekurencyjna - kod C++ #include <iostream> using namespace std; long long silnia(int n){ if (n==0) return 1; else return n*silnia(n-1); } int main(){ cout << "Podaj liczbe n = "; int n; cin >>n; long long m = silnia (n); cout << n << "! = " << m << endl; return 0; } Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 23 / 47 Liczby trójkatne ˛ Liczby trójkatne ˛ to ciag ˛ liczb: 1, 3, 6, 10, 15, 21, . . . (gdzie trzykropek oznacza, ciag ˛ jest nieskończony). n-ty element ciagu ˛ jest uzyskiwany poprzez dodanie liczby n do poprzedniego elementu ciagu. ˛ A zatem, 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; i tak dalej. 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 2 24 / 47 Liczby trójkatne ˛ Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 25 / 47 Algorytm obliczajacy ˛ n-ta˛ liczbe˛ trójkatn ˛ a˛ Algorytm: triangle (n) 1: if n< 1 then 2: return 0; 3: else 4: if n=1 then 5: return 1; 6: else 7: return n+ triangle(n - 1); 8: end if 9: end if Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 26 / 47 Funkcja triangle - wersja nierekurencyjna - kod C++ #include <iostream> using namespace std; int triangle (int n) { int total = 0; while (n>0) { total = total +n; --n; } return total; } int main(){ cout << "Podaj liczbe n = "; int n; cin >> n; int m = triangle (n); cout << n <<"-ta liczba trojkatna: " << m << endl; } Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 27 / 47 Funkcja triangle - wersja rekurencyjna - kod C++ #include <iostream> using namespace std; int triangle (int n) { if (n< 1) return 0; else if (n==1) return 1; else return n+triangle(n-1); } int main(){ cout << "Podaj liczbe n = "; int n; cin >> n; int m = triangle (n); cout << n <<"-ta liczba trojkatna: " << m << endl; } Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 28 / 47 Rekurencja - obliczanie an n a = pow(a, n) = Bożena Woźna-Szcześniak (AJD) 1 a ∗ pow(a, n − 1) Algorytmy i Struktury Danych. dla n = 0 dla n > 0 Wykład 2 29 / 47 Rekurencja - obliczanie an n a = pow(a, n) = 1 a ∗ pow(a, n − 1) dla n = 0 dla n > 0 Jak to wyglada w praktyce dla a = 2 i n = 3 (pow(2, 3) =?) 1 n = 0? nie, zatem oblicz 2 ∗ pow(2, 2) 2 n = 0? nie, zatem oblicz 2 ∗ pow(2, 1) 3 n = 0? nie, zatem oblicz 2 ∗ pow(2, 0) 4 n = 0? tak, zwróć 1. 5 zwróć 1 ∗ 2 6 zwróć 1 ∗ 2 ∗ 2 7 zwróć 1 ∗ 2 ∗ 2 ∗ 2 8 Zatem pow(2, 3) = 8 ! Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 29 / 47 Funkcja pow - wersja rekurencyjna kod C++ #include <iostream> using namespace std; long long pow(int a, int n){ if (n==0) return 1; else return a*pow(a,n-1); } int main(){ cout << "Podaj liczby a i n = "; int n,a; cin >> a >> n; long long m = pow (a,n); cout << a << "^" << n << "=" << m << endl; } Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 30 / 47 Rekurencja - algorytm Euklidesa Dane: a, b - dwie liczby naturalne Dane wyjściowe: liczba naturalna bed ˛ aca ˛ najwiekszym ˛ wspólnym dzielnikiem liczb a i b. Rozwiazanie ˛ rekurencyjne: a NWD(a, b) = 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 2 31 / 47 Rekurencja - algorytm Euklidesa NWD(a, b) = a NWD(b, a mod b) dla b = 0 dla b > 0 Przykład: NWD(1071, 1029) = NWD(1029, 1071mod1029 = 42) = NWD(1029, 42) = NWD(42, 1029mod42 = 21) = NWD(42, 21) = NWD(21, 42mod21 = 0). Stad: ˛ NWD(1071, 1029) = 21. Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 32 / 47 Funkcja NWD - kod C++ #include <iostream> using namespace std; long long NWD(int a, int b){ if (b==0) return a; else return NWD(b,a%b); } int main(){ cout << "Podaj liczby a i b = "; int a,b; cin >> a >> b; long long m = NWD(a,b); cout << "NWD(" << a << "," << b << ")=" << m; cout << endl; } Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 33 / 47 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. Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 34 / 47 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, . . . Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 34 / 47 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 2 34 / 47 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 2 35 / 47 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 2 36 / 47 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 2 36 / 47 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 2 37 / 47 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 2 37 / 47 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. Φ= Bożena Woźna-Szcześniak (AJD) a+b a = a b Algorytmy i Struktury Danych. Wykład 2 38 / 47 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+b a = 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 2 38 / 47 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 2 39 / 47 Ciag ˛ Fibonacciego - algorytm rekurencyjny Ciag ˛ Fibonacciego definiujemy rekurencyjnie w sposób nastepuj ˛ acy: ˛ F0 = 0 F1 = 1 Fn = Fn−1 + Fn−2 , dla n ≥ 2 Require: Liczba n {F0 , . . . , Fn−1 , Fn } Algorytm: FIB (n) 1: if n < 2 then 2: return n; 3: else 4: return FIB(n − 2) + FIB(n − 1); 5: end if Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 40 / 47 Ciag ˛ Fibonacciego - definicja rekurencyjna Definicja: F0 = 0, F1 = 1, Fn = Fn−1 + Fn−2 dla n ≥ 2 F5 F3 F4 F3 F2 F1 F0 F2 F1 Bożena Woźna-Szcześniak (AJD) F2 F1 F1 F1 F0 F0 Algorytmy i Struktury Danych. Wykład 2 41 / 47 Funkcja Fibonacci - kod C++ #include <iostream> using namespace std; long long Fibonacci(int n){ if (n < 2) return n; else return Fibonacci(n-2) + Fibonacci(n-1); } int main(){ cout << "Podaj liczbe n = "; int n; cin >> n; for (int i=0; i<=n ; i++) cout << Fibonacci(i) << "\t"; cout << endl; return 0; } Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 42 / 47 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 2 43 / 47 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 2 44 / 47 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) Algorytmy i Struktury Danych. Wykład 2 45 / 47 Funkcja Fibonacci - kod C++ #include <iostream> using namespace std; long long Fibonacci(int n){ if (n < 2) return n; else { long long f0=0,f1=1,m; for(int i=2; i<=n ; i++){ m = f0 + f1; f0 = f1; f1 = m; } return m; } } int main(){ cout << "Podaj liczbe n = "; int n; cin >> n; for (int i=0; i<=n ; i++) cout << Fibonacci(i) << "\t"; cout << endl; return 0; } Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 46 / 47 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 2 47 / 47 Przykład rekurencji bez końca Algorytm: StadDoWiecznosci (n) 1: if n=1 then 2: return 1; 3: else 4: if (n mod 2)=0 then 5: return StadDoWiecznosci(n-2)*n; 6: else 7: return StadDoWiecznosci(n-1)*n; 8: end if 9: end if Bożena Woźna-Szcześniak (AJD) Algorytmy i Struktury Danych. Wykład 2 48 / 47