Algorytmy i struktury danych

Podobne dokumenty
Wstęp do programowania

Stwierdzenie 1. Jeżeli ciąg ma granicę, to jest ona określona jednoznacznie (żaden ciąg nie może mieć dwóch różnych granic).

Zasada indukcji matematycznej. Dowody indukcyjne.

I. Podzielność liczb całkowitych

Teoria. a k. Wskaźnik sumowania można oznaczać dowolną literą. Mamy np. a j = a i =

Znajdowanie pozostałych pierwiastków liczby zespolonej, gdy znany jest jeden pierwiastek

Rekursja 2. Materiały pomocnicze do wykładu. wykładowca: dr Magdalena Kacprzak

O liczbach naturalnych, których suma równa się iloczynowi

2 n < 2n + 2 n. 2 n = 2. 2 n 2 +3n+2 > 2 0 = 1 = 2. n+2 n 1 n+1 = 2. n+1

Jarosław Wróblewski Analiza Matematyczna 1A, zima 2014/15. n = Rozwiązanie: Stosując wzór na wartość współczynnika dwumianowego otrzymujemy

Analiza matematyczna. Robert Rałowski

Damian Doroba. Ciągi. 1. Pierwsza z granic powinna wydawać się oczywista. Jako przykład może służyć: lim n = lim n 1 2 = lim.

Kolorowanie Dywanu Sierpińskiego. Andrzej Szablewski, Radosław Peszkowski

EGZAMIN MATURALNY Z INFORMATYKI MAJ 2011 POZIOM ROZSZERZONY WYBRANE: CZĘŚĆ I. Czas pracy: 90 minut. Liczba punktów do uzyskania: 20 WPISUJE ZDAJĄCY

3. Funkcje elementarne

Jarosław Wróblewski Analiza Matematyczna 1A, zima 2012/13. Ciągi.

Fraktale - ciąg g dalszy

5. Zasada indukcji matematycznej. Dowody indukcyjne.

Matematyka. Zakres podstawowy. Nawi zanie do gimnazjum. n/m Rozwi zywanie zada Zadanie domowe Dodatkowe Komunikaty Bie ce materiały

Jarosław Wróblewski Analiza Matematyczna 1, zima 2016/17

Internetowe Kółko Matematyczne 2004/2005

Pierwiastki z liczby zespolonej. Autorzy: Agnieszka Kowalik

201. a 1 a 2 a 3...a n a 2 1 +a 2 2 +a a 2 n n a 4 1 +a 4 2 +a a 4 n n. a1 + a 2 + a a n 204.

Egzamin maturalny z informatyki Poziom rozszerzony część I

EGZAMIN MATURALNY Z INFORMATYKI MAJ 2012 POZIOM PODSTAWOWY CZĘŚĆ I WYBRANE: Czas pracy: 75 minut. Liczba punktów do uzyskania: 20 WPISUJE ZDAJĄCY

a n 7 a jest ciągiem arytmetycznym.

Ciągi liczbowe wykład 3

Relacje rekurencyjne. będzie następująco zdefiniowanym ciągiem:

Wykład 11. a, b G a b = b a,

Wstęp do programowania

Geometrycznie o liczbach

Jarosław Wróblewski Analiza Matematyczna 1A, zima 2014/15. n 4n n 1

Jarosław Wróblewski Analiza Matematyczna 1, zima 2016/ n 333))

zadań z pierwszej klasówki, 10 listopada 2016 r. zestaw A 2a n 9 = 3(a n 2) 2a n 9 = 3 (a n ) jest i ograniczony. Jest wiec a n 12 2a n 9 = g 12

MACIERZE STOCHASTYCZNE

3 Arytmetyka. 3.1 Zbiory liczbowe.

MINIMALIZACJA PUSTYCH PRZEBIEGÓW PRZEZ ŚRODKI TRANSPORTU

( ) WŁASNOŚCI MACIERZY

Prawdopodobieństwo i statystyka

Przykład Obliczenie wskaźnika plastyczności przy skręcaniu

Metody Obliczeniowe w Nauce i Technice laboratorium

a 1, a 2, a 3,..., a n,...

Jarosław Wróblewski Analiza Matematyczna 2B, lato 2015/16

x t 1 (x) o 1 : x s 3 (x) Tym samym S(3) = {id 3,o 1,o 2,s 1,s 2,s 3 }. W zbiorze S(n) definiujemy działanie wzorem

Podstawowe cechy podzielności liczb.

UKŁADY RÓWNAŃ LINOWYCH

RÓWNANIA RÓŻNICZKOWE WYKŁAD 11

Jarosław Wróblewski Analiza Matematyczna A1, zima 2011/12. Kresy zbiorów. x Z M R

Egzaminy. na wyższe uczelnie zadania

Twierdzenie Cayleya-Hamiltona

Analiza algorytmów to dział informatyki zajmujcy si szukaniem najefektywniejszych, poprawnych algorytmów dla danych problemów komputerowych

1.3. Największa liczba naturalna (bez znaku) zapisana w dwóch bajtach to a) b) 210 c) d) 32767

ZADANIA Z TOPOLOGII I. PRZESTRZENIE METRYCZNE. II. ZBIORY OTWARTE I DOMKNIĘTE.

Analiza I.1, zima wzorcowe rozwiązania

Metody badania zbieżności/rozbieżności ciągów liczbowych

Algorytmy I Struktury Danych Prowadząca: dr Hab. inż. Małgorzata Sterna. Sprawozdanie do Ćwiczenia 3 Algorytmy grafowe ( )

MATEMATYKA (poziom podstawowy) przykładowy arkusz maturalny wraz ze schematem oceniania dla klasy II Liceum

f '. Funkcja h jest ciągła. Załóżmy, że ciąg (z n ) n 0, z n+1 = h(z n ) jest dobrze określony, tzn. n 0 f ' ( z n

Szeregi liczbowe. 15 stycznia 2012

3. Wzory skróconego mnożenia, działania na wielomianach. Procenty. Elementy kombinatoryki: dwumian Newtona i trójkąt Pascala. (c.d.

Parametryzacja rozwiązań układu równań

Zadania z algebry liniowej - sem. I Liczby zespolone

ma rozkład złożony Poissona z oczekiwaną liczbą szkód równą λ i rozkładem wartości pojedynczej szkody takim, że Pr( Y

Dwumian Newtona. Agnieszka Dąbrowska i Maciej Nieszporski 8 stycznia 2011

Szeregi liczbowe i ich własności. Kryteria zbieżności szeregów. Zbieżność bezwzględna i warunkowa. Mnożenie szeregów.

I kolokwium z Analizy Matematycznej

Analiza numeryczna. Stanisław Lewanowicz. Aproksymacja funkcji

Instrukcja do ćwiczeń laboratoryjnych z przedmiotu: Badania operacyjne. Temat ćwiczenia: Problemy transportowe cd, Problem komiwojażera

MATURA 2014 z WSiP. Zasady oceniania zadań

ALGEBRA LINIOWA Informatyka 2015/2016 Kazimierz Jezuita. ZADANIA - Seria 1. Znaleźć wzór na ogólny wyraz ciągu opisanego relacją rekurencyjną: x

EGZAMIN MATURALNY Z INFORMATYKI

D. Miszczyńska, M.Miszczyński KBO UŁ, Badania operacyjne (wykład 6 _ZP) [1] ZAGADNIENIE PRZYDZIAŁU (ZP) (Assignment Problem)

I. Ciągi liczbowe. , gdzie a n oznacza n-ty wyraz ciągu (a n ) n N. spełniający warunek. a n+1 a n = r, spełniający warunek a n+1 a n

Jarosław Wróblewski Analiza Matematyczna 2B, lato 2015/16

7 Liczby zespolone. 7.1 Działania na liczbach zespolonych. Liczby zespolone to liczby postaci. z = a + bi,

Algorytmy I Struktury Danych Prowadząca: dr Hab. inż. Małgorzata Sterna. Sprawozdanie do Ćwiczenia 1 Algorytmy sortowania (27.02.

ANALIZA MATEMATYCZNA 1 (MAP 1024) LISTY ZADAŃ

2. Nieskończone ciągi liczbowe

Zajęcia nr. 2 notatki

Kongruencje Wykład 4. Kongruencje kwadratowe symbole Legendre a i Jac

Opowieści o indukcji

Elementy rach. macierzowego Materiały pomocnicze do MES Strona 1 z 7. Elementy rachunku macierzowego

LICZBY, RÓWNANIA, NIERÓWNOŚCI; DOWÓD INDUKCYJNY

Funkcja wykładnicza i logarytm

Egzamin maturalny z matematyki CZERWIEC 2011

Wzór Taylora. Matematyka Studium doktoranckie KAE SGH Semestr letni 2008/2009 R. Łochowski

Definicja interpolacji

x R, (1) Ogólnie równanie o jednej niewiadomej x można przedstawić w postaci

Trzeba pokazać, że dla każdego c 0 c Mc 0. ) = oraz det( ) det( ) det( ) jest macierzą idempotentną? Proszę odpowiedzieć w

Statystyka opisowa - dodatek

Projekt współfinansowany przez Unię Europejską ze środków Europejskiego Funduszu Społecznego

Analiza Matematyczna I dla Inżynierii Biomedycznej Lista zadań

W. Guzicki Zadanie o sumach cyfr poziom rozszerzony 1

dna szeregu. ; m., k N ; ó. ; u. x 2n 1 ; e. n n! jest, że

CIĄGI LICZBOWE. Poziom podstawowy

CAŁKA NIEOZNACZONA. F (x) = f(x) dx.

Metrologia: miary dokładności. dr inż. Paweł Zalewski Akademia Morska w Szczecinie

Wektory Funkcje rzeczywiste wielu. Matematyka Studium doktoranckie KAE SGH Semestr letni 2008/2009 R. Łochowski

P π n π. Równanie ogólne płaszczyzny w E 3. Dane: n=[a,b,c] Wówczas: P 0 P=[x-x 0,y-y 0,z-z 0 ] Równanie (1) nazywamy równaniem ogólnym płaszczyzny

Transkrypt:

Algorytmy i struktury daych Wykład 6 Rekurecja Jausz Szwabiński Pla wykładu: Co to jest rekurecja? Przykład silia Rekurecja a idukcja matematycza Rekurecja kotra iteracja Ie przykłady Symbol Newtoa Cecha podzielości przez 3 dla liczby w zapisie dziesiętym Kowersja liczby całkowitej do łańcucha zaków w dowolej bazie Wielomiay Hermite'a Wieża Haoi Typowe błędy Badaie złożoości asymptotyczej Fraktale Trójkąt Sierpińskiego Zbiór Madelbrota

Co to jest rekurecja? rekurecja polega a rozwiązywaiu problemu w oparciu o rozwiązaia tego samego problemu dla daych o miejszych rozmiarach w logice opiera się a założeiu istieia pewego stau początkowego oraz reguły staowiącej podstawę wioskowaia: reguła: każdy ojciec jest starszy od swojego sya; każdy ojciec jest czyimś syem sta początkowy: jestem 20 letim mężczyzą teza: ojciec ojca mojego ojca jest starszy ode mie dowód: 1. mój ojciec jest starszy ode mie 2. mój ojciec jest czyimś syem 3. ojciec mojego ojca jest starszy od mojego ojca 4. ojciec mojego ojca jest czyimś syem 5. ojciec ojca mojego ojca jest starszy od ojca mojego ojca. w iformatyce jest techiką programistyczą polegającą a wywołaiu fukcji wewątrz iej samej w wielu przypadkach techika bardzo efektywa: pozwala a zwięzły opis algorytmu łatwa w implemetacji wymaga określeia przypadku bazowego, tz. wartości argumetu, przy której fukcja kończy działaie bez wywołaia samej siebie Silia

Silia liczby aturalej to iloczy wszystkich liczb aturalych ie większych iż. Formalie defiiuje się ją w astępujący sposób: Wartość 0! określa się osobo: Zwróćmy uwagę, że powyższa defiicja może zostać przepisaa w postaci rekurecyjej: Implemetacja fukcji a podstawie tej defiicji jest bardzo prosta: I [1]: def fac(): if >=1: retur *fac(-1) else: retur 1! = k, 1 k=1 0! = 1! ={ 1, ( 1)!, = 0 1 I [2]: fac(0) Out[2]: 1 I [3]: fac(1) Out[3]: 1 I [4]: fac(2) Out[4]: 2 I [5]: fac(5) Out[5]: 120

I [6]: fac(100) Out[6]: 9332621544394415268169923885626670049071596826438162146859296389521 7599993229915608941463976156518286253697920827223758251185210916864 000000000000000000000000 Warto wspomieć, że w bibliotece mathzajdziemy gotową implemetację sili: I [7]: import math I [8]: math.factorial(100) Out[8]: 9332621544394415268169923885626670049071596826438162146859296389521 7599993229915608941463976156518286253697920827223758251185210916864 000000000000000000000000

Rekurecja a idukcja matematycza Zasada idukcji matematyczej W wersji iezupełej Niech p będzie stwierdzeiem zawierającym liczbę aturalą. Moża dowieść stwierdzeia: dla każdego N jest p zapewiając, że p1 1. jest prawdziwe, 2. dla wszystkich, jeśli jest prawdziwe, to jest prawdziwe. k N p k p k+1 W wersji zupełej Niech q będzie stwierdzeiem zawierającym liczbę aturalą. Moża dowieść stwierdzeia: dla każdego N jest q zapewiając, że q1 1. jest prawdziwe, 2. dla wszystkich, jeśli,,, są prawdziwe, to jest prawdziwe. k N q1 q2 q k q k+1 Przykład suma początkowych liczb aturalych Chcemy dowieść, że Sprawdzamy prawdziwość dla : Zakładamy(hipoteza idukcyja), że prawdziwy jest wzór Sprawdzamy jego prawdziwość dla : ( + 1) 1 + 2 + 3 + 4 + + = 2 = 1 ( + 1) 1(1 + 1) 2 = = = 1 2 2 2 1 + 2 + 3 + + k = = k + 1 k(k + 1) 2 k(k + 1) 2 1 + 2 + + k + (k + 1) = + (k + 1) =( + 1) (k + 1) = k 2 (k + 1)(k + 2) 2 W zasady idukcji matematyczej wyika, że wzór jest prawdziwy dla wszystkich. Twierdzeie o defiowaiu rekurecyjym Niech będzie zbiorem wszystkich ciągów skończoych o wyrazach z iepustego zbioru, a N < = {m N: m < } ozacza zbiór liczb aturalych miejszych od wybraej liczby N. Dla daej fukcji f: U X istieje jeda i tylko jeda fukcja g:n X, która dla każdej liczby aturalej spełia k N gdzie U ozacza zawężeie fukcji. g(k) = f (g N<k ) X

Rekurecja kotra iteracja Niewątpliwą zaletą rekurecji jest przejrzystość programów, które z iej korzystają. Rekurecja jest podstawową techiką wykorzystywaą w fukcyjych językach programowaia (p. Haskell, Lisp). Chociaż dla pewych problemów staowi oa aturaly wybór, powio stosować się ją z umiarem. Dla ilustracji rozważmy iteracyją wersję fukcji silia: I [9]: def fac_iter(): sil = 1 if >1: for i i rage(2,+1): sil = sil*i retur sil I [10]: fac_iter(0) Out[10]: 1 I [11]: fac_iter(2) Out[11]: 2 I [12]: fac_iter(5) Out[12]: 120 I [13]: fac_iter(100) Out[13]: 9332621544394415268169923885626670049071596826438162146859296389521 7599993229915608941463976156518286253697920827223758251185210916864 000000000000000000000000 Porówajmy teraz czasy wykoaia obu wersji fukcji silia:

I [14]: %%timeit fac(120) 10000 loops, best of 3: 33.1 µs per loop I [15]: %%timeit fac_iter(120) 100000 loops, best of 3: 15 µs per loop Wprawdzie w tym kokretym przykładzie ie staowi to dla as jakiegoś większego problemu, ale metoda rekurecyja jest woliejsza od iteracyjej. Rekurecja potrafi dramatyczie zwiększyć złożoość obliczeiową wykoywaego programu, jeżeli rozwiązyway problem ie ma rekurecyjego charakteru. Ie wady: rekurecja zwiększa zapotrzebowaie programu a pamięć operacyją kompletie iezależe rozwiązywaie problemów (iektóre wartości wyliczae są wielokrotie) Ie przykłady Symbol Newtoa Mimo wspomiaych wad stosowaie rekurecji jest czasami kuszące ze względu a dużą przejrzystość kodu. Poiżej omówioych zostaie kilka przykładów, w których moża zastosować rekurecję. ( ) = Jedym z takich przykładów jest symbol Newtoa: k! k!( k)! Symbol te pojawia się we wzorze dwumieym Netwoa jako współczyik w tym wyrazie rozwiięcia tej potęgi sumy dwóch składików: x k y k (x + y ) = ( ) k=0 Stąd jego druga azwa: współczyik dwumiey Newtoa. Podaa powyżej defiicja jest rówoważa wzorowi rekurecyjemu: ( ) ={ k k 1, ( 1) + ( 1), k 1 k k {0, } 0 < k < k

I [16]: def biom(,k): if k==0: retur 1 if ==k: retur 1 else: retur biom(-1,k-1) + biom(-1,k) I [17]: biom(7,2) #powio być 21 Out[17]: 21 I [18]: biom(9,3) #84 Out[18]: 84 Sprawdźmy wyik: I [19]: fac(9)/(fac(3)*fac(9-3)) Out[19]: 84.0 Cecha podzielości przez 3 dla liczby w zapisie dziesiętym Cecha podzielości pozwala a stwierdzeie, czy daa liczba jest podziela bez reszty przez ią bez uciekaia się do dzieleia. W przypadku podzielości przez 3 cecha ma astępującą postać: liczba jest podziela przez 3, jeśli suma cyfr tej liczby jest podziela przez 3 Zauważmy, że regułę tę moża stosować rekurecyjie aż do osiągięcia liczby jedocyfrowej, której podzielość moża określić bardzo prosto, p.: 104628 1 + 0 + 4 + 6 + 2 + 8 = 21 2 + 1 = 3 Aby zaimplemetować sprawdzaie podzielości przez 3 metodą rekursywą, musimy ajpierw umieć rozbić dowolą liczbę a jej cyfry i zsumować je. W tym celu przekształcamy liczbę a łańcuch zaków:

I [20]: umber = 2456 s = str(umber) prit(s) 2456 Następie z łańcucha tworzymy listę: I [21]: l = list(s) prit(l) ['2', '4', '5', '6'] Listę zaków kowertujemy a listę liczb całkowitych: I [22]: figs = [it(i) for i i l] prit(figs) [2, 4, 5, 6] I w ostatim kroku sumujemy elemety tej listy: I [23]: sum(figs) Out[23]: 17 Korzystając z poleceia mapw Pythoie możemy powyższe kroki zapisać jedym poleceiem: I [24]: sum(map(it, str(umber))) Out[24]: 17 Możemy teraz zaimplemetować aszą fukcję:

I [25]: def divisible_by_3(umber): ret = False if umber i (3,6,9): ret = True if umber > 9: ret = divisible_by_3(sum(map(it, str(umber)))) retur ret I [26]: divisible_by_3(3) Out[26]: True I [27]: divisible_by_3(4) Out[27]: False I [28]: divisible_by_3(10) Out[28]: False I [29]: divisible_by_3(12) Out[29]: True I [30]: divisible_by_3(104628) Out[30]: True Kowersja liczby całkowitej do łańcucha zaków w dowolej reprezetacji Załóżmy teraz, że aszym zadaiem jest kowersja liczby całkowitej do łańcucha zaków w dowolej reprezetacji (od biarej do szesastkowej). Dla przykładu możemy chcieć zaprezetować liczbę 10 jako apis "10" w reprezetacji dziesiętej, lub jako "1010" w reprezetacji dwójkowej. Dla ustaleia uwagi załóżmy, że iteresuje as reprezetacja dziesięta. Jeśli zdefiiujemy łańcuch zaków odpowiadający wszystkim cyfrom w tej reprezetacji,

I [31]: covstrig = "0123456789" to bardzo łatwo będzie am przekowertować dowolą liczbę miejszą od 10. Jeśli aszą liczbą będzie p. 9, to odpowiadający jej zak otrzymamy po prostu jako I [32]: covstrig[9] Out[32]: '9' Aby przekowertować większą liczbę, p. 769, musimy ją zatem rozbić ajpierw a trzy cyfry a astępie każdą z cyfr zamieić a odpowiedi zak i połączyć zaki ze sobą. Wykorzystamy w tym celu dzieleie całkowite. Zauważmy, że dzieląc całkowicie 769 przez 10, otrzymamy 76 i resztę z dzieleia 9 dzieląc całkowicie 76 przez 10, otrzymamy 7 i resztę z dzieleia 6 dzieląc całkowicie 7 przez 10, otrzymamy 0 i resztę z dzieleia 7 Zauważmy, że reszty z dzieleia to są cyfry składające się a rozważaą liczbę. Każdą z ich możemy zamieić a zak jak w powyższym przykładzie. Rekurecyja wersja tego algorytmu będzie miała astępującą implemetację: I [33]: def tostr(,base): covertstrig = "0123456789ABCDEF" if < base: retur covertstrig[] else: retur tostr(//base,base) + covertstrig[%base]

I [34]: prit(tostr(1453,10)) 1453 I [35]: prit(tostr(1453,2)) 10110101101 I [36]: prit(tostr(1453,8)) 2655 I [37]: prit(tostr(1453,16)) 5AD Wielomiay Hermite'a Wielomiay Hermite'a to przykład wielomiaów ortogoalych, używaych między iymi w mechaice kwatowej. Są oe rozwiązaiem rówaia rekurecyjego: (x) = 2x (x) 2 (x) H +1 H H 1 przy warukach początkowych: (x) = 1 H0 (x) = 2x H1 Kilka pierwszych wielomiaów powyższego ciągu ma postać: Poiżej "aiwa" implemetacja: H2(x) = 4x 2 2 H3(x) = 8x 3 12x (x) = 16 48 + 12 H4 x 4 x 2 I [38]: def hermite(,x): if(==0): f = 1e0 elif(==1): f = 2*x else: f = 2*x*hermite(-1,x)-2*(-1)*hermite(-2,x) retur f

I [39]: x = 10 for i i rage(0,5): prit(hermite(i,x)) 1.0 20 398.0 7880.0 155212.0 I [40]: def h2(x): retur 4*x**2-2 def h3(x): retur 8*x**3-12*x def h4(x): retur 16*x**4-48*x**2 +12 I [41]: prit(h2(x)) prit(h3(x)) prit(h4(x)) 398 7880 155212

Wieża Haoi W prezetowaych do tej pory przykładach mieliśmy do czyieia z zagadieiami, które były zdefiiowae w sposób rekurecyjy. Dlatego zastosowaie rekurecji do ich implemetacji było bardzo aturale. Metoda ta sprawdza się jedak rówież w bardziej skomplikowaych problemach, które a pierwszy rzut oka ie zawsze wydają się rekurecyje. Przykładem takiego zagadieia może być wieża Haoi, zagadka wymyśloa w Azji i sprowadzoa do Europy przez fracuskiego matematyka Edouarda Lucasa w 1883 roku. Rozwiązaie zagadki polega a przeiesieiu wieży z jedego słupa a drugi krążek po krążku. Podczas przekładaia moża posługiwać się trzecim słupem (buforem), jedak przy założeiu, że ie wolo kłaść krążka o większej średicy a miejszy ai przekładać kilku krążków jedocześie. Jest to przykład zadaia, którego złożoość obliczeiowa wzrasta iezwykle szybko w miarę zwiększaia parametru wejściowego. Rozwiązaie dla 4 krążków zilustrowae jest a poiższym rysuku: Ogólie dla Dla = 64 krążków ajmiejsza liczba wymagaych ruchów wyosi L() = 2 1 daje to a przykład 2 64 1 = 18446744073709551615 584942417355 Zakładając, że ręczie moża wykoać 1 ruch a sekudę, przeiesieie wieży zajęłoby lat. Oczywiście komputery wykoują dużo więcej operacji w ciągu sekudy. Chcąc rozwiązać zagadkę a komputerze, zauważmy, że problem da się zapisać w postaci stosukowo prostego algorytmu rekurecyjego. Niech będzie liczbą krążków, atomiast koleje słupy ozaczoe są literami A, B i C. Wówczas: 1 A B C 1. przeieś (rekurecyjie) krążków ze słupka a słupek posługując się słupkiem, 2. przeieś jede krążek ze słupka A a słupek C, 3. przeieś (rekurecyjie) krążków ze słupka a słupek posługując się słupkiem. 1 B C A

Przykładowa implemetacja w Pythoie mogłaby wyglądać tak: I [42]: def movetower(,a, C, B): if >= 1: movetower(-1,a,b,c) movedisk(a,c) movetower(-1,b,c,a) I [43]: def movedisk(fp,tp): prit("movig disk from",fp,"to",tp) I [44]: movetower(3,"a","b","c") movig disk from A to B movig disk from A to C movig disk from B to C movig disk from A to B movig disk from C to A movig disk from C to B movig disk from A to B I [45]: movetower(4,"a","b","c") movig disk from A to C movig disk from A to B movig disk from C to B movig disk from A to C movig disk from B to A movig disk from B to C movig disk from A to C movig disk from A to B movig disk from C to B movig disk from C to A movig disk from B to A movig disk from C to B movig disk from A to C movig disk from A to B movig disk from C to B

Typowe błędy Brak przypadku bazowego Załóżmy, że aszym celem jest obliczeie liczby harmoiczej H, Defiicję tę da się zapisać w postaci rekurecyjej: I [1]: def H(): retur H(-1) + 1/ 1 1 = 1 + + + + = 2 3 H 1 ={ H 1, H 1 + 1 = 1 > 1 1 k=1 k Błędem tutaj jest ieuwzględieie przypadku bazowego. Defiicja fukcji jest formalie poprawa, ale będzie oa wykoywać się w ieskończoość: H4 H3 H2 H1 H0 H 1 Brak gwaracji kowergecji I [3]: def F(): if ==1: retur 1.0 retur F() + 1/ Błąd w rekurecyjym wywołaiu fukcji powoduje, że waruek bazowy osiągięty zostaie tylko w przypadku, gdy. W pozostałych przypadkach = 1 F6 F6 F6 Wadliwy waruek bazowy I [2]: def G(): if ==1: retur 1 elif %2==0: #parzyste retur G(-2)* else: retur G(-1)*

Podobie jak poprzedio, istieje tylko jeda możliwość trafieia w waruek brzegowy przypadkach ślad wywołań fukcji jest astępujący: = 1. W iych dla dla parzystych ieparzystych G6 G4 G2 G0 G 2 G5 G4 G2 G0 G 2 Nadmiere wymagaia pamięciowe Wróćmy do przykładu z liczbą harmoiczą. Poprawie zdefiiowaa fukcja ma postać: I [4]: def H(): if ==0: retur 0.0 retur H(-1) + 1/ I [5]: H(2) Out[5]: 1.5 I [6]: H(10) Out[6]: 2.9289682539682538 poprawie oblicza tą liczbę harmoiczą głębokość rekurecji jest proporcjoala do dla dużych może astąpić przepełieie stosu

I [7]: H(300000) ------------------------------------------------------------------- -------- RutimeError Traceback (most recet ca ll last) <ipytho-iput-7-a505d7cbfcd5> i <module>() ----> 1 H(300000) <ipytho-iput-4-e9d88043c7dc> i H() 2 if ==0: 3 retur 0.0 ----> 4 retur H(-1) + 1/... last 1 frames repeated, from the frame below... <ipytho-iput-4-e9d88043c7dc> i H() 2 if ==0: 3 retur 0.0 ----> 4 retur H(-1) + 1/ RutimeError: maximum recursio depth exceeded i compariso I [8]: import sys sys.setrecursiolimit(300000) I [ ]: H(300000) Wyik działaia tego poleceia (a moim komputerze) będzie taki:

W takich sytuacjach z reguły lepiej sprawdza się algorytm iteracyjy: I [2]: def H_iter(): suma = 0 while >0: suma = suma + 1/ = - 1 retur suma I [3]: H_iter(2) Out[3]: 1.5 I [4]: H_iter(10) Out[4]: 2.9289682539682538 I [5]: H_iter(300000) Out[5]: 13.188755085205598 Badaie złożoości asymptotyczej Wróćmy do defiicji fukcji silia, I [ ]: def fac(): if >=1: retur *fac(-1) else: retur 1

T() T(0) = 1 rówy 1) czas potrzeby do wykoaia fukcji rekurecyjej, p. silia, dla dowolego jedostkowy czas pracy (zakładamy, że dla wejścia o rozmiarze 1 czas pracy jest T() = T( 1) + 1, > 0 Rozwijając ostati wzór, otrzymamy: Zatem T(0) T(1) T(2) T(3) T() = = = = = 1 T(0) + 1 = 2 T(1) + 1 = 2 + 1 = 3 T(2) + 1 = 3 + 1 = 4 + 1 T() = O()

Fraktale potoczie obiekt samopodoby albo "ieskończeie subtely" (tz. ukazujący subtele detale awet w wielokrotym powiększeiu) ze względu a olbrzymią różorodość uika się formalych defiicji z reguły za fraktal uzaje się zbiór, który posiada wszystkie poiższe charakterystyki albo przyajmiej ich większość: ma ietrywialą strukturę w każdej skali, struktura ta ie daje się łatwo opisać w języku tradycyjej geometrii euklidesowej, jest samopodoby, jeśli ie w sesie dokładym, to przybliżoym lub stochastyczym, jego wymiar Hausdorffa jest większy iż jego wymiar topologiczy, ma względie prostą defiicję rekurecyją, ma aturaly ( poszarpay, kłębiasty itp.) wygląd ajstarsze fraktale pojawiły się a początku XX w

Trójkąt Sierpińskiego Trójkąt Sierpińskiego to jede z ajprostszych fraktali (zaych długo przed powstaiem tego pojęcia). Kostrukcja tego zbioru podaa była w 1915 przez polskiego matematyka Wacława Sierpińskiego: 1. W trójkącie rówoboczym połącz środki boków, dzieląc go a cztery miejsze trójkąty. 2. Usuń środkowy z powstałych trójkątów. 3. Powtórz kroki 1 3 dla pozostałych trójkątów. Tym razem ie tylko będziemy chcieli zaimplemetować rekurecyją metodę tworzeia trójkąta Sierpińskiego, ale zilustrować cały proces a ekraie. W tym celu użyjemy prostego modułu turtle, który udostępia arzędzia do rysowaia i przesuwaia obiektu zwaego żółwiem a ekraie. Dokumetację do modułu moża zaleźć pod adresem https://docs.pytho.org/3.0/library/turtle.html (https://docs.pytho.org/3.0/library/turtle.html). Jego użycie jest dość proste: I [46]: import turtle w = turtle.scree() alex = turtle.turtle() alex.forward(50) alex.left(90) alex.forward(30) w.exitoclick() # Allows us to use turtles # Creates a playgroud for turtles # Create a turtle, assig to alex # Tell alex to move forward by 50 uits # Tell alex to tur by 90 degrees # Complete the secod side of a rectagle # Wait for user to close widow Wiele cech żółwia i plaszy, a której się porusza, możemy zmieiać, p.:

I [47]: import turtle w = turtle.scree() w.bgcolor("lightgree") w.title("hello, Tess!") tess = turtle.turtle() tess.color("blue") tess.pesize(3) # Set the widow backgroud color # Set the widow title # Tell tess to chage her color # Tell tess to set her pe width tess.forward(50) tess.left(120) tess.forward(50) w.exitoclick() Możemy przejść teraz do implemetacji właściwego algorytmu:

I [48]: import turtle def drawtriagle(poits,color,myturtle): """ Draw triagle give by poits (helper fuctio)""" myturtle.fillcolor(color) myturtle.up() myturtle.goto(poits[0][0],poits[0][1]) myturtle.dow() myturtle.begi_fill() myturtle.goto(poits[1][0],poits[1][1]) myturtle.goto(poits[2][0],poits[2][1]) myturtle.goto(poits[0][0],poits[0][1]) myturtle.ed_fill() def getmid(p1,p2): """Fid midpoit of triagle's edge (helper fuctio)""" retur ( (p1[0]+p2[0]) / 2, (p1[1] + p2[1]) / 2) def sierpiski(poits,degree,myturtle): """Geerate Sierpiski Triagle with recursio""" colormap = ['blue','red','gree','white','yellow','violet','orage'] drawtriagle(poits,colormap[degree],myturtle) if degree > 0: sierpiski([poits[0], getmid(poits[0], poits[1]), getmid(poits[0], poits[2])], degree-1, myturtle) sierpiski([poits[1], getmid(poits[0], poits[1]), getmid(poits[1], poits[2])], degree-1, myturtle) sierpiski([poits[2], getmid(poits[2], poits[1]), getmid(poits[0], poits[2])], degree-1, myturtle) def mai(): myturtle = turtle.turtle() mywi = turtle.scree() mypoits = [[-100,-50],[0,100],[100,-50]] sierpiski(mypoits,4,myturtle) mywi.exitoclick() mai()

Zbiór Madelbrota podzbiór płaszczyzy zespoloej, którego brzeg jest fraktalem kostrukcja: zbiór tworzą te pukty, dla których ciąg opisay rówaiem rekurecyjym: p C { z 0 z +1 = = 0 z 2 + p ie dąży do ieskończoości: Moża wykazać, że jest to rówoważe z: lim z N z < 2

I [8]: from pylab import * from umpy import NaN def m(a): z = 0 for i rage(1, 100): z = z**2 + a if abs(z) > 2: retur retur NaN X = arage(-2,.5,.002) Y = arage(-1, 1,.002) Z = zeros((le(y), le(x))) for iy, y i eumerate(y): for ix, x i eumerate(x): Z[iy,ix] = m(x + 1j * y) imshow(z, cmap = plt.cm.prism, iterpolatio = 'oe', extet = (X.mi(), X.max(), Y.mi(), Y.max())) xlabel("re(c)") ylabel("im(c)") show()