Rekurencja. Rekurencja zwana także rekursją jest jedną z najważniejszych metod konstruowania rozwiązań i algorytmów.

Podobne dokumenty
Rekurencja. Rekurencja zwana także rekursją jest jedną z najważniejszych metod konstruowania rozwiązań i algorytmów.

Podstawy Informatyki. Inżynieria Ciepła, I rok. Wykład 9 Rekurencja

Rekurencja. Rekurencja zwana także rekursją jest jedną z najważniejszych metod konstruowania rozwiązań i algorytmów.

Wykład 8. Rekurencja. Iterować jest rzeczą ludzką, wykonywać rekursywnie boską. L. Peter Deutsch

Podstawy Informatyki. Metalurgia, I rok. Rekurencja. skomplikowane zadanie. Rekurencja

Podstawy Informatyki. Metalurgia, I rok. Wykład 5 Rekurencja

Rekurencja. Przykład. Rozważmy ciąg

Rekurencja. Przygotowała: Agnieszka Reiter

Rekurencja (rekursja)

ALGORYTMY I STRUKTURY DANYCH

Podstawy programowania. Wykład: 13. Rekurencja. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Wykład 3. Metoda dziel i zwyciężaj

Analiza algorytmów zadania podstawowe

Technologie informacyjne Wykład VII-IX

FUNKCJA REKURENCYJNA. function s(n:integer):integer; begin if (n>1) then s:=n*s(n-1); else s:=1; end;

Algorytmy i struktury danych

Algorytmy i struktury danych. Wykład 4

Algorytmy. wer Wojciech Myszka 30 listopada 2008

Algorytm. a programowanie -

Wstęp do programowania

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Podstawy programowania 2. Temat: Funkcje i procedury rekurencyjne. Przygotował: mgr inż. Tomasz Michno

Luty 2001 Algorytmy (7) 2000/2001

funkcje rekurencyjne Wykład 12. Podstawy programowania (język C) Funkcje rekurencyjne (1) Funkcje rekurencyjne (2)

//warunki początkowe m=500; T=30; c=0.4; t=linspace(0,t,m); y0=[-2.5;2.5];

Zad. 1 Zad. 2 Zad. 3 Zad. 4 Zad. 5 SUMA

Metody algortmiczne (Algorytmy Część IV)

Złożoność obliczeniowa zadania, zestaw 2

Zaawansowane algorytmy i struktury danych

2.8. Algorytmy, schematy, programy

O rekurencji i nie tylko

PoniŜej znajdują się pytania z egzaminów zawodowych teoretycznych. Jest to materiał poglądowy.

Rekurencje. Jeśli algorytm zawiera wywołanie samego siebie, jego czas działania moŝe być określony rekurencją. Przykład: sortowanie przez scalanie:

Zadanie 1. Zmiana systemów. Zadanie 2. Szyfr Cezara. Zadanie 3. Czy liczba jest doskonała. Zadanie 4. Rozkład liczby na czynniki pierwsze Zadanie 5.

REKURENCJA W JĘZYKU HASKELL. Autor: Walczak Michał

Zaawansowane algorytmy i struktury danych

Matematyka Dyskretna. Andrzej Szepietowski. 25 czerwca 2002 roku

Zapisywanie algorytmów w języku programowania

5. Rekurencja. Przykłady

Algorytmika i pseudoprogramowanie

Strategia "dziel i zwyciężaj"

Programowanie dynamiczne

1 Wprowadzenie do algorytmiki

Raport z projektu. Przedmiot: Algorytmy i struktury danych 1 Projekt: Wieża Hanoi Autor: Wojciech Topolski

Informatyka A. Algorytmy

W wielu obliczeniach w matematyce bądź fizyce wykonanie niektórych kroków zależy od spełnienia warunku.

Matematyka dyskretna. Andrzej Łachwa, UJ, a/15

Wstęp do Informatyki zadania ze złożoności obliczeniowej z rozwiązaniami

Obliczenia na stosie. Wykład 9. Obliczenia na stosie. J. Cichoń, P. Kobylański Wstęp do Informatyki i Programowania 266 / 303

ALGORYTMY. 1. Podstawowe definicje Schemat blokowy

Przeglad podstawowych pojęć (3) Podstawy informatyki (3) dr inż. Sebastian Pluta. Instytut Informatyki Teoretycznej i Stosowanej

Podprogramy. Procedury

operacje porównania, a jeśli jest to konieczne ze względu na złe uporządkowanie porównywanych liczb zmieniamy ich kolejność, czyli przestawiamy je.

Sortowanie danych. Jolanta Bachan. Podstawy programowania

Algorytm selekcji Hoare a. Łukasz Miemus

Technologie Informatyczne Wykład VII

Wstęp do programowania. Drzewa podstawowe techniki. Piotr Chrząstowski-Wachtel

Podstawowe algorytmy i ich implementacje w C. Wykład 9

Wstęp do Programowania potok funkcyjny

1. Nagłówek funkcji: int funkcja(void); wskazuje na to, że ta funkcja. 2. Schemat blokowy przedstawia algorytm obliczania

1.1. Uzupełnij poniższą tabelę: i wynik(i)

Optymalizacja. Przeszukiwanie lokalne

Rekurencja/rekursja. Iluzja istnienia wielu kopii tego samego algorytmu (aktywacji) Tylko jedna aktywacja jest aktywna w danej chwili

Podstawy programowania 2. Temat: Drzewa binarne. Przygotował: mgr inż. Tomasz Michno

Klasa 2 INFORMATYKA. dla szkół ponadgimnazjalnych zakres rozszerzony. Założone osiągnięcia ucznia wymagania edukacyjne na. poszczególne oceny

ALGORYTMY. 1. Podstawowe definicje Schemat blokowy

Analiza algorytmów zadania podstawowe

Programowanie dynamiczne

WYKŁAD 9. Algorytmy sortowania elementów zbioru (tablic) Programy: c4_1.c... c4_3.c. Tomasz Zieliński

3. Podaj elementy składowe jakie powinna uwzględniać definicja informatyki.

Wstęp do programowania. Listy. Piotr Chrząstowski-Wachtel

Instrukcje pętli przykłady. Odgadywanie hasła. 1) Program pyta o hasło i podaje adres, gdy hasło poprawne lub komunikat o błędnym haśle.

Informatyka wprowadzenie do algorytmów (II) dr hab. inż. Mikołaj Morzy

Macierze. Rozdział Działania na macierzach

Programowanie w VB Proste algorytmy sortowania

Zadanie 1. Test (6 pkt) Zaznacz znakiem X w odpowiedniej kolumnie P lub F, która odpowiedź jest prawdziwa, a która fałszywa.

Całka nieoznaczona, podstawowe wiadomości

Matematyka dyskretna dla informatyków

Matematyka dyskretna

Programowanie Funkcyjne. Marcin Kubica Świder,

Temat 20. Techniki algorytmiczne

Ciągi i rekurencja, komputer dla matematyka. warsztaty towarzyszące konferencji Informatyka realnie prowadzą: Hanna Basaj Jan Aleksander Wierzbicki

12. Rekurencja. UWAGA Trzeba bardzo dokładnie ustalić <warunek>, żeby mieć pewność, że ciąg wywołań się zakończy.

Algorytmy w teorii liczb

Zadania do samodzielnego rozwiązania

PRÓBNY EGZAMIN MATURALNY Z INFORMATYKI STYCZEŃ POZIOM ROZSZERZONY Część I

Wstęp do programowania. Dziel i rządź. Piotr Chrząstowski-Wachtel

EGZAMIN MATURALNY 2012 INFORMATYKA

Rozdział 5. Macierze. a 11 a a 1m a 21 a a 2m... a n1 a n2... a nm

Algorytmy sortujące i wyszukujące

Obrazy rekurencyjne. Zastosowanie rekurencji w algorytmice. AUTOR: Martin Śniegoń

PROGRAMOWANIE W PYTHONIE OD PIERWSZYCH KROKÓW

Pętla for. Matematyka dla ciekawych świata -19- Scilab. for i=1:10... end. for k=4:-1:1... end. k=3 k=4. k=1. k=2

ZADANIE 1. Ważenie (14 pkt)

Pendolinem z równaniami, nierównościami i układami

Znajdowanie największego i najmniejszego elementu w zbiorze n liczb całkowitych

Algorytmy i Struktury Danych

WYKŁAD 8. Funkcje i algorytmy rekurencyjne Proste przykłady. Programy: c3_1.c..., c3_6.c. Tomasz Zieliński

INFORMATYKA W SZKOLE. Podyplomowe Studia Pedagogiczne. Dr inż. Grażyna KRUPIŃSKA. D-10 pokój 227

Transkrypt:

Rekurencja Rekurencja zwana także rekursją jest jedną z najważniejszych metod konstruowania rozwiązań i algorytmów. Zgodnie ze znaczeniem informatycznym algorytm rekurencyjny to taki który korzysta z samego siebie, a program rekurencyjny to taki który wywołuje sam siebie. Cechy algorytmów rekurencyjnych: - zakończenie algorytmu jest jasno określone - złożony problem zostaje rozłożony na problem elementarny, który umiemy rozwiązać, i na problem o mniejszym stopniu komplikacji, niż ten z którym mieliśmy do czynienia na początku Przeszukiwanie liniowe Mając tablicę n liczb całkowitych tab[1], tab[2],..., tab[n] stwierdzić czy w tablicy tab występuje liczba x, podana jako parametr. Rozwiązanie: 1) Wziąć pierwszy niezbadany element tablicy n-elementowej 2) Jeśli aktualnie analizowany element tablicy jest równy x to wypisać znaleziono x i zakończyć 3) W przeciwnym wypadku zbadać pozostałą n-1 elementową część tablicy korzystając z tego samego algorytmu

4) W przypadku zbadania całej tablicy i nie znalezienia elementu x wypisać nie znaleziono x i zakonczyc. Schematycznie zapisany program, który rekurencyjnie realizuje to zadanie: lewy, prawy granice obszaru poszukiwań tab przeszukiwana tablica x poszukiwana liczba funkcja szukaj (tab, lewy, prawy, x) Jeśli (lewy >prawy) to Wypisz Element x nie został znaleziony w przeciwnym wypadku Jeśli ( tab[lewy] = x ) to Wypisz Znalazłem element x na pozycji lewy KONIEC w przeciwnym przypadku szukaj(tab, lewy+1, prawy, x) wywołanie programu przez samego siebie Zakończenie powyższego algorytmu/programu jest jasno określone: - element znaleziony lub - przekroczenie zakresu tablicy

Złożony problem zostaje rozbity na problem elementarny i na analogiczny problem tylko o mniejszym stopniu skomplikowania: - z tablicy o rozmiarze n schodzimy do tablicy o rozmiarze n-1 Podstawowe błędy przy konstruowaniu programów rekurencyjnych: - złe określenie warunku zakończenia programu - niewłaściwa, nieefektywna metoda rozwiązania problemu Typowym przykładem zastosowania rekurencji jest liczenie n! zdefiniowanej jako: n! = n*(n-1)! gdy n>=1 n! = 1 gdy n=0 Program rekurencyjny liczący wielkość n! może wyglądać następująco: funkcja silnia(n) Jeśli (n = 0) to silnia=1 w przeciwnym wypadku silnia=n*silnia(n-1) wywołanie samego siebie

Schemat obliczeń dla n=3 - pionowe strzałki w dół oznaczają wywołania rekurencyjne, tzn. zagłębianie się programu z poziomu 1 na poziom 2 itd. w celu dotarcia do przypadku elementarnego 0! - poziome strzałki oznaczają obliczanie wyników cząstkowych - ukośne strzałki prezentują proces przekazywania wyniku cząstkowego z jednego poziomu na drugi Schemat Hornera Schemat Hornera to bardzo powszechna metoda stosowana do rozwiązywania wielu zadań min. do znajdowania reprezentacji liczby w innych systemach liczenia.

Rozważmy zadanie liczenia wartości wielomianu stopnia n: y = W n (x) = a 0 *x n + a 1 *x n-1 + a 2 *x n-2 +... + a n-1 *x + a n Najprostsze rozwiązanie iteracyjne polega na konstruowaniu wyrazów, które następnie dodajemy zgodnie ze wzorem przy czym przyjmujemy, że współczynniki tworzą wektor a(0), a(1),..., a(n).

Wielomian W n (x) można też zapisać inaczej zgodnie ze schematem Hornera: Y = W n (x) = = (a 0 *x n-1 + a 1 *x n-2 + a 2 *x n-3 +... + a n-1 )*x +a n = = W n-1 (x)*x + a n = = ((a 0 *x n-2 + a 1 *x n-3 + a 2 *x n-4 +... + a n-2 )*x+ a n-1 )*x +a n = = (W n-2 (x)*x + a n-1 )*x + a n = = (...(( a 0 *x+ a 1 )*x + a 2 )*x +... + a n-1 )*x +a n = = (...(( W 1 (x)*x + a 2 )*x +... + a n-1 )*x +a n Algorytm napisany zgodnie z tym schematem wyglądałby nieco inaczej niż poprzednia wersja.

Algorytm mimo tego, że zawiera wyrażenie y=y*x+a(i) nie jest w pełni algorytmem rekurencyjnym. Pełny zapis rekurencyjny: a 0 gdy n=0 W n (x) = W n-1 (x)*x + a n gdy n 1 1) Wartość wielomianu stopnia n, W n (x) jest liczona z wyrażenia zawierającego wielomian o jeden stopień mniejszy W n-1 (x). 2) Dla n=0 podana jest wartość definiowanej wielkości a 0 i jest to warunek zakończenia rekurencji, dzięki któremu ciąg kolejnych odwołań do wielkości W k (x) ma swój koniec. Schemat rekurencji dla wielomianu W n (x) jest podobny do schematu dla silni ( n! ).

W schemacie rekurencyjnym wyróżniamy dwa etapy: 1) Wywołania rekurencyjne, które kończy skorzystanie z warunku zakończenia rekurencji. 2) Powrót do kolejnych wywołań, obejmujący wykonywanie właściwych obliczeń lub tylko wstawianie wyników z niższych poziomów. Realizacja algorytmu rekurencyjnego wymaga zapisania go w postaci procedury, która może wywoływać samą siebie. Procedura często zawiera parametr określający poziom rekurencji czyli stopień zagłębiania się wywołań.

Rekurencja Wieże Hanoi Mamy trzy paliki A,B,C i pewną liczbę ( n ) krążków różnej wielkości z otworami. Krążki są nanizane na palik A w kolejności od największego do najmniejszego, największy znajduje się na dole. Naszym zadaniem jest przenieść wszystkie krążki z palika A na palik B, z wykorzystaniem jeśli to konieczne palika C, w taki sposób, że: - pojedynczy ruch polega na przeniesieniu jednego krążka między dwoma palikami - w żadnej chwili większy krążek nie może leżeć na krążku mniejszym Rozwiązania: n=1 Na paliku A znajduje się jeden krążek, który przenosimy jednym ruchem na palik B.

n=2 Na paliku A są dwa krążki : krążek górny przenosimy na palik C, krążek dolny na B i krążek z C przenosimy na B - trzy ruchy.

n=3 Uproszczony zapis rozwiązania: 1. Przenieś n-1 górnych krążków z palika A na palik C, używając B. 2. Przenieś największy krążek z palika A na palik B. 3. Przenieś wszystkie krążki z palika C na palik B, używając A. Krok 2. Jest trywialny, a wykonalność kroków 1. i 3. wynika z faktu, że cały czas dysponujemy trzema palikami bo krążkiem największym nie należy się przejmować, gdyż dowolny inny krążek może być położony na nim. Zapis rekurencyjny: Krok 1. Jeśli n = 1 to przenieś krążek z palika początkowego ( A ) na palik docelowy ( B ) i zakończ algorytm dla n = 1. Krok 2. { Liczba krążków na paliku początkowym ( A ) jest większa od 1, n>1} 2a. Stosując ten algorytm przenieś n-1 krążków z palika początkowego (A) na palik pośredni (C), używając palika docelowego (B). 2b. Przenieś pozostały krążek z palika początkowego (A) na palik docelowy (B).

2c. Stosując ten algorytm, przenieś n-1 krążków z palika pośredniego ( C ) na docelowy ( B ), używając początkowego ( A ). W krokach 1 i 2b wykonujemy takie samo przeniesienia. Dlatego oznaczamy ogólnie przeniesienie krążka z palika X na palik Y jako (X Y), a przeniesienie k krążków z X na Y oznaczając (k,x,y,z). Przy czym X,Y,Z oznaczają paliki: X- początkowy, Y docelowy, Z pośredni. Możemy wtedy zapisać najbardziej ogólną wersję rekurencyjną dla wież Hanoi (n,a,b,c). Krok 1. Jeśli n=0, to nic nie rób i zakończ algorytm dla tego przypadku. Krok 2. { Gdy liczba krążków na paliku A jest większa od 0, n>0 }. 2a. Zastosuj ten algorytm dla (n-1,a,c,b). 2b. Przenieś pozostały krążek (A B). 2c. Zastosuj ten algorytm dla (n-1,c,b,a).

Liczby Fibonacciego Zadanie z 1202 roku "Mamy parę nowo narodzonych królików i o każdej parze królików zakładamy, że : 3) nowa para staje się płodna po miesiącu życia 4) każda płodna para rodzi jedną parę nowych królików w miesiącu 5) króliki nigdy nie umierają Ile będzie królików po upływie k miesięcy? " Możemy narysować schemat (M- para młodych, R- para rozmnażająca się): Ze schematu dostajemy ciąg liczb: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 itd.

Wniosek: w kolejnym miesiącu liczba par królików jest równa liczbie par z poprzedniego miesiąca plus liczba par nowo narodzonych (tj. tyle ile było par dwa miesiące wcześniej. Zapis rekurencyjny rozwiązania jest postaci: 1, k = 1, 2 F k = F k-1 + F k-2, k > 2 funkcja fib(k) jeśli k <= 2 to fib=1 w przeciwnym wypadku fib = fib(k-1)+fib(k-2) Schemat obliczeń dla fib(5): Rekurencyjne liczenie ciągu Fibonacciego prowadzi do wielokrotnego powtarzania tych samych obliczeń - zacieniowana część schematu. Efektu tego można uniknąć stosując schemat iteracyjny: 1.Jeśli k=1 lub k=2, to przyjmij Fib = 1 i zakończ 2.W przeciwnym wypadku: a)przyjmij Fib1=1 i Fib2 =1 b)wykonaj k-2 razy następujące instrukcje

Fib=Fib1+Fib2 Fib2=Fib1 Fib1=Fib 3.Wynikiem jest Fib Wartość liczby Fibonacciego F k można dostać dużo prościej:

Myślenie rekurencyjne - przykład 1 Jak narysować rekurencyjnie jednym "pociągnięciem" schemat: Parametry programu: odstęp między liniami równoległymi alpha długość boku rysowanego w pierwszej kolejności lg Podstawowe zadania to odnalezienie schematu rekurencyjnego i warunków zakończenia procesu wywołań rekurencyjnych. Elementarny przypadek rozwiązania:

Procedura w Turbo Pascalu realizująca zadanie: procedure spirala(lg,x,y:integer); begin if(lg>0) then begin Lineto(x+lg,y); Lineto(x+lg,y+lg); Lineto(x+alpha,y+lg); Lineto(x+alpha,y+alpha); spirala(lg-2*alpha,x+alpha,y+alpha); end; end; Przykład - pułapka z nieskończoną ilością wywołań: FUNCTION StadDoWiecznosci(n:Integer):Integer; BEGIN IF (n=1) THEN StadDoWiecznosci:= 1 ELSE IF ( (n mod 2) = 0 ) THEN StadDoWiecznosci:= n*staddowiecznosci(n-2) ELSE StadDoWiecznosci:= n*staddowiecznosci(n-1); END; Pozornie zapis rekurencyjny jest poprawny, ale dla n 2 wszystkie wywołania rekurencyjne kończą się parzystą wartością n (tym samym nie docieramy do przypadku elementarnego n=1 ). Zatem n = n pocz schodzimy stopniowo do n=2, potem n=0, potem n=-2 etc. - wywołania rekurencyjne są nieskończone.

Rekurencja - uwagi końcowe Programy rekurencyjne są zazwyczaj "pamięciożerne", gdyż z każdym wywołaniem wiąże się konieczność zachowania pewnych informacji (w strukturze zwanej stosem). Programy rekurencyjne często ulegają "zawieszeniu" czego przyczyną może być: - "nieskończone pętle" - brak pamięci - nieprawidłowe lub niejasne określenie warunków zakończenia programu Maksymalny poziom zagłębienia rekurencji często jest łatwy do określenia (Funkcja Silnia), ale nie zawsze przybliżone szacunki dają prosty wynik, np. Funkcja MacCarthy'ego FUNCTION MacCarthy(x:Integer):Integer; BEGIN IF x>100 THEN MacCarthy:= x-10 ELSE MacCarthy:= MacCarthy(MacCarthy(x+11)); END; Ilość wywołań funkcji MacCarthy'ego w zależności od x jest trudna do ustalenia bez głębszej analizy kodu programu:

Cechy programów rekurencyjnych: - czytelność i naturalność zapisu - zwięzłość pozwalająca na szybkie wykrycie błędów - "pamięciożerność" i niemożność oszacowania zajętości pamięci Nie należy używać algorytmów rekurencyjnych, gdy: - w miejsce algorytmu rekurencyjnego można podać czytelny i szybki program iteracyjny - algorytm jest niestabilny - może się zapętlić lub dawać nieoczekiwane wyniki - występuje rekurencja skośna tzn. A wywołuje B, B wywołuje A, etc.