Rekurze. Princip a použití rekurze. Převod rekurze na iteraci.

Podobné dokumenty
Dynamické datové struktury III.

Dynamické datové struktury IV.

Úvod do programování 10. hodina

Rekurzivní algoritmy

Stromy. Strom: souvislý graf bez kružnic využití: počítačová grafika seznam objektů efektivní vyhledávání výpočetní stromy rozhodovací stromy

Třídící algoritmy. Insert Sort. Bubble Sort. Select Sort. Shell Sort. Quick Sort. Merge Sort. Heap Sort.

Dynamické datové struktury I.

Rekurze. Pavel Töpfer, 2017 Programování 1-8 1

Prohledávání do šířky = algoritmus vlny

4. Rekurze. BI-EP1 Efektivní programování Martin Kačer

5 Rekurze a zásobník. Rekurzivní volání metody

Algoritmy a datové struktury

DobSort. Úvod do programování. DobSort Implementace 1/3. DobSort Implementace 2/3. DobSort - Příklad. DobSort Implementace 3/3

Dynamické datové struktury II.

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 21.

Rekurze. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 12.

Řešení: PŘENESVĚŽ (N, A, B, C) = přenes N disků z A na B pomocí C

8. Rekurze. doc. Ing. Jiří Vokřínek, Ph.D. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze

Úvod do informatiky. Miroslav Kolařík

Stromy. Jan Hnilica Počítačové modelování 14

Struktura programu v době běhu

Stromy, haldy, prioritní fronty

Reprezentace aritmetického výrazu - binární strom reprezentující aritmetický výraz

1. Převeďte dané číslo do dvojkové, osmičkové a šestnáctkové soustavy: a) b)

5. přednáška - Rozklad problému na podproblémy

Rozklad problému na podproblémy

A4B33ALG 2010/05 ALG 07. Selection sort (Select sort) Insertion sort (Insert sort) Bubble sort deprecated. Quicksort.

Náplň. v Jednoduché příklady na práci s poli v C - Vlastnosti třídění - Způsoby (algoritmy) třídění

NPRG030 Programování I, 2018/19 1 / :03:07

Základní datové struktury III: Stromy, haldy

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 12.

Stromy. Karel Richta a kol. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze Karel Richta a kol.

Časová a prostorová složitost algoritmů

Booleovská algebra. Booleovské binární a unární funkce. Základní zákony.

Programování 3. hodina. RNDr. Jan Lánský, Ph.D. Katedra informatiky a matematiky Fakulta ekonomických studií Vysoká škola finanční a správní 2015

Dynamicky vázané metody. Pozdní vazba, virtuální metody

Základní stavební prvky algoritmu

Rekurze a zásobník. Jak se vypočítá rekurzivní program? volání metody. vyšší adresy. main(){... fa(); //push ret1... } ret1

Prioritní fronta, halda

Binární soubory (datové, typované)

Základy algoritmizace c2005, 2007 Michal Krátký, Jiří Dvorský1/39

ÚLOHY S POLYGONEM. Polygon řetězec úseček, poslední bod je totožný s prvním. 6 bodů: X1, Y1 až X6,Y6 Y1=X6, Y1=Y6 STANOVENÍ PLOCHY JEDNOHO POLYGONU

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

STROMOVE ALGORITMY Prohledavani do sirky (level-order) Po vodorovnejch carach fronta

Čtvrtek 8. prosince. Pascal - opakování základů. Struktura programu:

2 Datové struktury. Pole Seznam Zásobník Fronty FIFO Haldy a prioritní fronty Stromy Hash tabulky Slovníky

Algoritmizace prostorových úloh

Test prvočíselnosti. Úkol: otestovat dané číslo N, zda je prvočíslem

Slepé prohledávání do šířky Algoritmus prohledávání do šířky Při tomto způsobu prohledávání máme jistotu, že vždy nalezneme koncový stav, musíme ale p

Algoritmizace Dynamické programování. Jiří Vyskočil, Marko Genyg-Berezovskyj 2010

Datové struktury 2: Rozptylovací tabulky

Základní pojmy. Úvod do programování. Základní pojmy. Zápis algoritmu. Výraz. Základní pojmy

Adresní vyhledávání (přímý přístup, zřetězené a otevřené rozptylování, rozptylovací funkce)

Lekce 01 Úvod do algoritmizace

Vzdálenost uzlů v neorientovaném grafu

Binární vyhledávací stromy pokročilé partie

Dynamické programování

Stromy. Příklady. Rekurzivní datové struktury. Základní pojmy

Programování: základní konstrukce, příklady, aplikace. IB111 Programování a algoritmizace

Volné stromy. Úvod do programování. Kořenové stromy a seřazené stromy. Volné stromy

Select sort: krok 1: krok 2: krok 3: atd. celkem porovnání. výběr nejmenšího klíče z n prvků vyžaduje 1 porovnání

Konvexní obálka množiny bodů.

Algoritmy výpočetní geometrie

bfs, dfs, fronta, zásobník, prioritní fronta, halda

Zákony hromadění chyb.

IB111 Úvod do programování skrze Python

5. Dynamické programování

Čísla a číselné soustavy.

ALGORITMIZACE 2010/03 STROMY, BINÁRNÍ STROMY VZTAH STROMŮ A REKURZE ZÁSOBNÍK IMPLEMENTUJE REKURZI PROHLEDÁVÁNÍ S NÁVRATEM (BACKTRACK)

TGH05 - aplikace DFS, průchod do šířky

Programování v C++ 1, 16. cvičení

Vyvažování a rotace v BVS, všude se předpokládá AVL strom

Booleovská algebra. Pravdivostní tabulka. Karnaughova mapa. Booleovské n-krychle. Základní zákony. Unární a binární funkce. Podmínky.

Binární vyhledávací strom pomocí směrníků Miroslav Hostaša L06620

bfs, dfs, fronta, zásobník, prioritní fronta, halda

IB108 Sada 1, Příklad 1 Vypracovali: Tomáš Krajča (255676), Martin Milata (256615)

int ii char [16] double dd název adresa / proměnná N = nevyužito xxx xxx xxx N xxx xxx N xxx N

MATURITNÍ TÉMATA Z MATEMATIKY

Zdůvodněte, proč funkce n lg(n) roste alespoň stejně rychle nebo rychleji než než funkce lg(n!). Symbolem lg značíme logaritmus o základu 2.

Rekurze a rychlé třídění

Poslední nenulová číslice faktoriálu

Markov Chain Monte Carlo. Jan Kracík.

ČESKÉ VYSOKÉ UČENÍ TECHNICKÉ V PRAZE

Základy algoritmizace a programování

Funkce pokročilé možnosti. Úvod do programování 2 Tomáš Kühr

Mgr. Tomáš Kotler. I. Cvičný test 2 II. Autorské řešení 6 III. Klíč 15 IV. Záznamový list 17

B3B33ALP - Algoritmy a programování - Zkouška z předmětu B3B33ALP. Marek Boháč bohacm11

Triangulace. Význam triangulace. trojúhelník je základní grafický element aproximace ploch předzpracování pro jiné algoritmy. příklad triangulace

Algoritmizace I. Ak. rok 2015/2016 vbp 1. ze 132

Řídicí struktury. alg3 1

CVIČNÝ TEST 41. OBSAH I. Cvičný test 2. Mgr. Tomáš Kotler. II. Autorské řešení 7 III. Klíč 15 IV. Záznamový list 17

B3B33ALP - Algoritmy a programování - Zkouška z předmětu B3B33ALP. Marek Boháč bohacm11

Algoritmizace řazení Bubble Sort

Iterační výpočty Projekt č. 2

REGRESNÍ ANALÝZA V PROSTŘEDÍ MATLAB

ZŠ ÚnO, Bratří Čapků 1332

3. přednáška. Obsah: Řídící struktury sekvence, if-else, switch, for, while, do-while. Zpracování posloupnosti

ALGORITMIZACE 2010/03 STROMY, BINÁRNÍ STROMY VZTAH STROMŮ A REKURZE ZÁSOBNÍK IMPLEMENTUJE REKURZI PROHLEDÁVÁNÍ S NÁVRATEM (BACKTRACK)

Algoritmizace a programování

Universita Pardubice Fakulta elektrotechniky a informatiky. Mikroprocesorová technika. Semestrální práce

Transkript:

Rekurze. Princip a použití rekurze. Převod rekurze na iteraci. Tomáš Bayer bayertom@natur.cuni.cz Katedra aplikované geoinformatiky a kartografie, Přírodovědecká fakulta UK. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 1 / 86

Obsah přednášky 1 Rekurze a její vlastnosti Výpočet faktoriálu a Fibonacciho čísel rekurzí. Nebezpečí rekurze 2 Příklady použití rekurze Hledání maxima rekurzí Převod čísla mezi polyadickými soustavami Binární hledání Úloha Hanojských věží QuickSort Binární stromy Kartografická generalizace Jednoduchá kresba s využitím rekurze Konstrukce Kochovy vločky rekurzí Vhodnost/nevhodnost rekurze 3 Převod rekurze na iteraci Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 2 / 86

Rekurze a její vlastnosti 1. Rekurze Sebeopakování, realizováno bez použití cyklu. Datový objekt či struktura definována tak, že definice odkazuje na tuto strukturu nebo strukturu podobného charakteru. Tato definice umožňuje opakované volání sama sebe. Rekurzivní algoritmy: Využívají rekurzivní funkce f, které jsou definovány samy sebou. V průběhu vykonávání programu volají samy sebe nebo podobné funkce. Po každém kroku musí dojít ke zjednodušení problému, jinak je postup neefektivní. Důležité je nalezení vztahu mezi problémy řešenými ve dvou po sobě následujících rekurzivních krocích. Proměnné rekurzivních funkcí: Při každém novém volání funkce f dochází k vytvoření nové sady lokálních proměnných. Za běhu programu existuje několik různých sad lokálních proměnných (HW náročnost). Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 3 / 86

2. Vlastnosti rekurze Rekurze a její vlastnosti Podmínka ukončení rekurze: Rekurzivní algoritmus musí obsahovat podmínku, při které dojde k jejímu ukončení, aby nepokračovala do nekonečna. V opačném případě dojde k nekonečné rekurzi!!!. V určitém místě tedy musí dojít k takovému dořešení problému, které nebude rekurzivní. Nevhodná konstrukce podmínky: Nepoužívat složité a nepřehledné podmínky. Vyhnout se kontradikcím a tautologiím (nemění se pravdivostní hodnota výrazu). Dělení rekurze: Přímá rekurze: Funkce opakovaně volá sama sebe: f f. Nepřímá (kruhová) rekurze: Vzájemné cyklické volání několik funkcí: f 1 f 2... f n f 1. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 4 / 86

Rekurze a její vlastnosti 3. Vztah rekurze a iterace Iterace: Opakování bloku příkazů za stanovených podmínek. Podmínka opakování bloku přechází (for, while) nebo ho následuje (do while), není součástí bloku. Rekurze: Opakování bloku, podmínka součástí bloku. Rekurze lze využívat pouze společně s dalšími nástroji: procedury, funkce (nikoliv samostatně). Mezi rekurzí a iterací úzký vztah, vzájemná převoditelnost. Rekurze efektivnější než iterace. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 5 / 86

Rekurze a její vlastnosti 4. Přímá rekurzivní funkce Obecný tvar rekurzivní funkce. nebo f (n) //Rekurzivni funkce: prima rekurze { C n; //Blok prikazu, fce n, nemeni n if (n == P) //Podminka { D; //Blok prikazu: nerekurzivni doreseni } else f(n - 1); //Rekurzivni volani E n; //Blok prikazu, fce n, nemeni n } f(n) = {C n; n? D n : f(n - 1);E n } nebo F = {C, if P then F } Schéma rekurze: Posloupnost rekurzivních volání funkce F nad množinou N. f(n)->f(n-1)->...f(1); Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 6 / 86

Rekurze a její vlastnosti 5. Posloupnost rekurzivních volání Posloupnost rekurzivních volání: //Rekurzivni volanid fn -> C n f(n - 1) C n C n 1 f(n-2) C n C n 1 C n 2 f(n-3)... C n C n 1 C n 2... C 1 f(1) //Konec rek. volani //Nerekurzivni doreseni a zpetny chod C n C n 1 C n 2... C 1 D E 1 C n C n 1 C n 2... C 1 D E 1 E 2... C n C n 1 C n 2... C 1 D E 1 E 2... E n Funkce C, E závislé na n volány n-krát, nerekurzivní dořešení voláno pouze 1x. Možno znázornit i stromem. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 7 / 86

Rekurze a její vlastnosti 6. Vztah rekurze a zásobníku Rekurze implementována vnitřně s využitím zásobníku (Stack). Při každém rekurzivním volání funkce dojde k vytvoření tzv. aktivačního záznamu. Obsah aktivačního záznamu. 1 Návratová hodnota 2 Formální parametry funkce. 3 Návratová hodnota. 4 Lokální proměnné funkce. 5 Pomocné proměnné pro mezivýsledky. Při přetečení zásobníku chyba Stack Overflow. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 8 / 86

Rekurze a její vlastnosti Výpočet faktoriálu a Fibonacciho čísel rekurzí. 7. Výpočet faktoriálu s použitím rekurze: Faktoriál čísla n označujeme jako n!. Pro n > 0 je definován jako { n(n 1)! pro n > 1 n! = 1 pro n = 1 Rekurzivní popis problému: Funkce f pro výpočet faktoriálu čísla n označena jako f (n). S využitím f (n) lze výpočet faktoriálu přepsat do rekurzivního tvaru: f (n) = n f (n 1) Funkce f rekurzivně volá sama sebe nad menší množinou prvků. Dochází tedy ke zjednodušení problému, což je jedním z předpokladů efektivního použití rekurze. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 9 / 86

Rekurze a její vlastnosti Výpočet faktoriálu a Fibonacciho čísel rekurzí. 8. Znázornění průběhu rekurze f (4) =? f (4) = 24 f (4) = 4 f (3) f (4) = 4 6 (funkce vrací 24) (zpětné dosazení) (druhé volání) f (3) = 3 f (2) (třetí volání) f (2) = 2 1 (funkce vrací 2) f (2) = 2 f (1) (čtvrté volání) (zpětné dosazení) f (2) = 2 1 (funkce vrací 2) f (1) = 1 Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 10 / 86

9. Znázornění průběhu rekurze Strom rekurzivního volání funkce n! Rekurze a její vlastnosti Výpočet faktoriálu a Fibonacciho čísel rekurzí. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 11 / 86

Rekurze a její vlastnosti Výpočet faktoriálu a Fibonacciho čísel rekurzí. 10. Zápis zdrojového kódu v jazyce Java Výpočet faktoriálu s použitím rekurze: int f(int n) { if (n > 1) //Ukoncovaci podminka { return n * f(n-1); } else return 1; //Ukonceni rekurze } Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 12 / 86

Rekurze a její vlastnosti 11. Fibonacciho posloupnost Výpočet faktoriálu a Fibonacciho čísel rekurzí. Fibonacciho funkci fib(n) definujeme jako fib(n 1) + fib(n 2) pro n > 1 fib(n) = 1 pro n = 1 1 pro n = 0 (1) Fibonacciho posloupnost: {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89,..} Pomoc ní se dá modelovat množení králíků :-). Výpočet rekurzí velmi neefektivní. Pro n = 4 je člen fib(1) určován celkem 3x, člen fib(0) celkem 2x. Pro n = 5 zřejmě platí, že člen fib(1) bude určován celkem 5x, člen fib(0) celkem třikrát... Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 13 / 86

Rekurze a její vlastnosti 12. Strom rekurzivního volání Výpočet faktoriálu a Fibonacciho čísel rekurzí. Strom rekurzivního volání funkce fib(n). Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 14 / 86

Rekurze a její vlastnosti 13. Výpočet Fibonacciho čísel rekurzí Výpočet faktoriálu a Fibonacciho čísel rekurzí. Zdrojový kód v jazyce Java: int fib(int n) { if (n>1) //Podminka ukonceni rekurze { return fib(n-1)+fib(n-2); } else return 1; //Ukonceni rekurze } Exponenciální růst!!!. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 15 / 86

Rekurze a její vlastnosti Výpočet faktoriálu a Fibonacciho čísel rekurzí. 14. Výpočet Fibonacciho čísel bez použití rekurze Zdrojový kód: int fib(int n) { int fi=1; int fii=1; for (int i=0;i<n;i++) { fi = fi + fii; //Vypocet predchoziho clenu fii = fi - fii; //Vypocet nasledujiciho clenu } return fii; } Postup mnohem efektivnější než s použitím rekurze. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 16 / 86

15. Růst množiny Rekurze a její vlastnosti Nebezpečí rekurze Následující krok rekurze není zjednodušením předchozího kroku. Důsledkem je růst množiny, nad kterou je výpočet prováděn divergence řešení. Vznik nekonečné rekurze. Pro n > 0 je definována α(n) jako α(n) = Výpočet α(n) s použitím rekurze: { n α(n + 1) pro n > 1 1 pro n = 1 int alfa(int n) { if (n > 1) //Ukoncovaci podminka { return n * alfa(n + 1); //Mnozina roste } else return 1; //Nikdy nedojde k ukonceni rekurze } Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 17 / 86

Rekurze a její vlastnosti Nebezpečí rekurze 16. Špatná konstrukce rekurzivní podmínky Špatná konstrukce rekurzivní podmínky může způsobit nekonečný počet rekurzivních volání. Pro n > 0 je definována β(n) jako β(n) = Pro sudé n dojde k nekonečné rekurzi. Výpočet β(n) s použitím rekurze. { n β(n 2) pro n 1 1 pro n = 1 int beta(int n) { if (n!= 1) //Nedojde k ukonceni rekurze pro suda n { return n * beta(n - 2); } else return 1; } Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 18 / 86

17. Další ukázky použití rekurze Nalezení maxima z množiny. Binární hledání. Hledání největšího společného dělitele. Převod čísel mezi soustavami. Hanojské věže QuickSort. Kresba vepsaných čtverců, spirály. Fraktály: Kochova vločka. Binární stromy. Digitální kartografie: generalizace Douglas & Peucker. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 19 / 86

Hledání maxima rekurzí 18. Nalezení maxima z množiny prvků Dána neuspořádaná posloupnost prvků x = {x i }, i = 1,..., N. Nalezněte hodnotu x max = max(x i ). Varianty: Bez použití rekurze. S použitím rekurze. Nalezení minima bez použití rekurze: hodnotu x max inicializujeme prvním prvkem posloupnosti, tj. x max = x[0]. porovnáme x max s ostatními členy posloupnosti. Pokud x max > x[i], pak x max = x[i]. po provedení porovnání se všemi prvky x max = max(x i ). Složitost algoritmu O(N). Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 20 / 86

19. Hledání maxima klasicky Hledání maxima rekurzí Zdrojový kód v Javě: double maximum(double [] x) { double max = x[0]; //Inicializace maxima for (int i = 0; i < c.length; i++) { //Prirazeni nejvetsiho cisla jako maxima if max > x[i] max = x[i]; } return max; } Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 21 / 86

20. Hledání maxima rekurzí Hledání maxima rekurzí Hledání maxima z n čísel lze řešit přirozenou rekurzí. Úloha je dekomponovatelná na úlohy stejné třídy: 1 Hledání maxima v posloupnosti n prvků lze převést na dva stejné podproblémy, a to hledání maxima ve dvou posloupnostech tvořených n/2 prvky: {x 0, x 1,..., x n/2 } a {x n/2+1, x n/2+2,..., x n 1 }. 2 Hledání maxima v těchto posloupnostech lze řešit stejným způsobem, a to rozdělením každé z nich na dvojici posloupností s n/4 prvky, atd... 3 Pro n = 2 je funkce maximum volána pro posloupnosti tvořené dvěma za sebou následujícími prvky x i, x i+1. 4 Pro n = 1 vrací funkce přímo hodnotu prvku {x i }. 5 Ukončení rekurzivního volání. 6 Nalezení maxima z dvojice za sebou následujících prvků ve všech posloupnostech a jejich vrácení max = max(x i, x i+1 ). 7 Nalezení maxim z těchto maxim: atd...max = max(max(x i, x i+1 ), max(x i+2, x i+3 )), atd... Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 22 / 86

Hledání maxima rekurzí 21. Hledání maxima, rekurzivní dělení intervalu Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 23 / 86

23. Hledání maxima rekurzí Hledání maxima rekurzí double maximum(double [] x, int l, int r) { //Maximum z 1-2 prvku umime if (r - l <= 1) return Math.max(x[l],x[r]); int mid =(l + r)/2; //Nalezeni prostredniho prvku double lmax = maximum(x, l, mid); //Rekurze,L interval double rmax = maximum(x, mid + 1, r); //Rekurze, R interval } return Math.max(lmax, rmax); Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 24 / 86

Převod čísla mezi polyadickými soustavami 24. Převod čísla mezi polyadickými soustavami (1/2) Celočíselná část čísla v polyadické soustavě o základu z n a = ± b i z i = ±(b nz n + b n 1 z n 1 +... + b 3 z 3 + b 2 z 2 + b 1 z 1 + b 0 z 0 ). i=0 Při převodu čísla hledáme koeficienty b 0,...,b n. a = ±[z(b nz n 1 + b n 1 z n 2 +... + b 3 z 2 + b 2 z 1 + b 1 z 0 ) + b 0 z 0 ], b 0 = a z(b nz n + b n 1 z n 1 + b n 2 z n 2 +... + b 3 z 2 + b 2 z 1 + b 1 z 0 ) = a%z. a/z = ±[b nz n 1 + b n 1 z n 2 +... + b 3 z 2 + b 2 z 1 + b 1 z 0 ], = ±[z(b nz n 2 + b n 1 z n 3 +... + b 3 z 1 + b 2 z 0 ) + b 1 z 0 ], b 1 = a z z(bnzn 2 + b n 1 z n 3 +... + b 3 z 1 + b 2 z 0 ) = a z %z, a/z 2 = ±[b nz n 2 + b n 1 z n 3 +... + b 3 z 1 + b 2 z 0 ], = ±[z(b nz n 3 + b n 1 z n 4 +... + b 3 z 0 ) + b 2 z 0 ] = a z 2 %z, b 2 = a z 2 z(bnzn 3 + b n 1 z n 4 +... + b 3 z 0 ), Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 25 / 86

Převod čísla mezi polyadickými soustavami 25. Převod čísla mezi polyadickými soustavami (2/2) a/z 3 = ±[b nz n 3 + b n 1 z n 4 +... + b 3 z 0 ], = ±[z(b nz n 4 + b n 1 z n 5 +...) + b 3 z 0 ], b 3 = a z 3 z(bnzn 4 + b n 1 z n 5 +...)......... b n = a z n b n 1z 0 = a z n %z. Postupné odečítání mocnin z k od převáděného čísla dokud zbytek po dělení není roven nule. Odečítání lze nahradit zbytkem po dělení: Postup lze zapsat ve tvaru: b 0 = a%z, b 1 = a z %z b 2 = a a %z... bn = z2 z n %z. b 0 = a%z, a = a/z b 1 = a%z a = a/z... b n = a z n %z. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 26 / 86

Převod čísla mezi polyadickými soustavami 26. Ukázka a = (105) 10 = (?) 2. b 0 = a%z = 105%2 = 1, a = a/z = 52, b 1 = a%z = 0, a = a/z = 26. b 2 = a%z = 0, a = a/z = 13. b 3 = a%z = 1, a = a/z = 6. b 4 = a%z = 0, a = a/z = 3. b 5 = a%z = 1, a = a/z = 1. b 6 = a%z = 1, a = a/z = 0. Platí: (a) 2 = 1 2 6 + 1 2 5 + 1 2 3 + 1 2 0 = 0. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 27 / 86

Převod čísla mezi polyadickými soustavami 27. Algoritmus převodu (nerekurzivní) Opakované hledání b = a%z pro převáděné číslo: public void convertnumber(int a, int z) { while (a > 0) //Opakuj, dokud a>0 { int b = a % z; System.out.println(b); a = a / z; } } Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 28 / 86

Převod čísla mezi polyadickými soustavami 28. Algoritmus převodu (rekurzivní) Opakované hledání b = a%z pro převáděné číslo: Iterace realizována rekurzí. public void convertnumber(int a, int z) { if (a == 0) return; else { int b = a % b; System.out.println(b); convertnumber ( a / z, b ); } } Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 29 / 86

Převod čísla mezi polyadickými soustavami 29. Prvočíslo (1/2) Číslo d N dělí c N, pokud existuje k N takové, že c = kd. Označení d c. Vlastnosti: 1) Pro všechna c N platí 1 c a c c. 2) Pokud k c a c d pak k d. Číslo c N prvočíslem, pokud pro každá a N a b N platí c (a b) c a c b. Alternativně c : a c b c a = c b = 1 a = 1 b = c. Číslo c N je složené, pokud není prvočíslo. 3) Pro a Z, a > 0, c, a < c 2a. 4) MFV: Pro a Z, c, 0 < a < c, c (a c a). Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 30 / 86

Převod čísla mezi polyadickými soustavami 30. Prvočíslo (2/2) Počet prvočísel π(n) na intervalu [2, N] Hustota prvočísel π(10) = 4, π(100) = 25. Složené číslo c = a b ρ(n) = π(n) N N ln N. c : a c b c a 2 b c/2 a c/2 b 2. Pokud a b a = c. Díky komutativitě symetrie: c = ab = ba. Příklad: 36 = 2 * 13 = 4 * 9 = 6 * 6 = 9 *4 = 13 *2. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 31 / 86

Převod čísla mezi polyadickými soustavami 31. Největší společný dělitel (1/2) Největší společný dělitel d, d Z, čísel a Z, b Z d = gcd(a, b) : d a d b. Pokud a, b nesoudělná, pak gcd(a, b) = 1. Dělení se zbytkem a beze zbytku b a = r a = kb + r, b a = 0 a = kb. Necht a Z, b Z, pak a = kd, b = ld. Rozdíl čísel je také dělitelný d = a b = d(k l), a = b +, platí gcd(a, b) = gcd(b, ). Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 32 / 86

32. Největší společný dělitel (2/2) Převod čísla mezi polyadickými soustavami Výše uvedený princip použit u Eukleidova algoritmu gcd(a b, b) = gcd(a, b), po k krocích gcd(0, b) = gcd(a, b). Předpoklad a > b, opakujeme, dokud a > 0. Výhodou je velmi jednoduchá implementace. do if a < b. swap a b. a a b. while a > 0 d b Rekurzivní verze na cvičení. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 33 / 86

33. Vylepšení algoritmu (1/2) Převod čísla mezi polyadickými soustavami Pro velké a, b cyklus může běžet relativně dlouho. Místo a a b použijeme a a mb, m Z. Platí Algoritmus: do if a < b. swap a b. a a%b. while a > 0 d b a mb = a a/b b = a%b. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 34 / 86

34. Vylepšení algoritmu (2/2) Převod čísla mezi polyadickými soustavami Nemusíme prohazovat a b. Předpoklad b a%b. Do a přiřadíme max(b, a%b). Do b přiřadíme min(b, a%b). Algoritmus: do a b; b a%b; while b > 0; Upravená testovací podmínka, protože a b. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 35 / 86

35. Rekurzivní řešení Převod čísla mezi polyadickými soustavami int gcd (int a, int b) { if (a==0 b== 0 ) return -1; } if ( a%b > 0) return gcd (b, a % b); else return b; Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 36 / 86

Binární hledání 36. Binární hledání Předpokladem je uspořádaná vstupní množina (tj. setříděná dle hodnot prvků). Použití při opakovaném hledání nad množinou, jejíž prvky se často nemění. Složitost hledání O(log 2 (N)), setřídění O(N log 2 (N)), celkově O(N log 2 (N)). Princip: V každém kroku rozdělení vstupní množiny na dvě poloviční definované prostřednictvím dvojice krajních indexů. Indexy tvoří posloupnost {N/2, N/4, N/8,..., 1}. Test, ve které z podmnožin hledaný prvek leží. Pro N=1 přímý test, v ostatních případech rekurzivní dělení. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 37 / 86

Binární hledání 37. Binární hledání, nerekurzivní řešení int bsearch( int a, int [] x) { int l = 0, r = x.length - 1; while (l <= r){ int m = (l + r)/ 2 //Index prostredniho prvku if (a == x[m]) return m; //Byl prvek nalezen? } if (a > x[m]) l = m + 1; // Inkrementuj levy index else r = m - 1; //Dekrementuj pravy index } return -1; Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 38 / 86

Binární hledání 38. Binární hledání, rekurzivní řešení int bsearch( int a, int [] numbers, int l, int r) { if (l > r) return -1; //Prazdny interval int m = (l + r)/2; //Index prostredniho prvku if (a == x[m]) return m; //Cislo nalezeno v mnozine } else if ( a < x[m] ) return bsearch(a, x, i, m - 1); //Leva podmnozina else return bsearch(a, x, m + 1, j ); //Prava podmnozina Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 39 / 86

Úloha Hanojských věží 39. Problém Hanojských věží Mniši v Tibetu řeší zajímavý hlavolam tvořený třemi tyčemi. Na první tyči navlečeno 64 kroužků seřazených dle velikosti, největší dole, nejmenší nahoře. Každý den přesunou jeden kroužek z jedné tyče na druhou tak, aby se kroužek o větším průměru nikdy nevyskytl na kroužku o menším průměru. Až přemístí všechny kroužky z první tyče na třetí tak, aby kroužek o menším průměru ležel na kroužku o větším průměru, zanikne svět. Poznámka: Nastane za 2 64 1 = 18446744073709551615 dní 50504432782230120 let (51 biliard let). Plánovaná doba existence sluneční soustavy je miliardkrát kratší. Netřeba mít strach :-). Problém lze řešit rekurzí. Počet kroužků n. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 40 / 86

40. Ukázka řešení pro n = 2 Úloha Hanojských věží První kroužek přesuneme z 1. na 2. tyč. Druhý kroužek přesuneme z 1. na 3. tyč. První kroužek přesuneme z 2. na 3. tyč. Celkem 2 2 1 přesunů. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 41 / 86

41. Ukázka řešení pro n = 3 Úloha Hanojských věží Celkem 2 3 1 přesunů. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 42 / 86

Úloha Hanojských věží 43. Rozbor problému Tah h s n kroužky z i na j přes k h n (i, j, k). Dva kroužky, n = 2: h 2 (1, 3, 2) = {h 1 (1, 2, 3), h 1 (1, 3, 2), h 1 (2, 3, 1)}. Tři kroužky, n = 3: h 3 (1, 3, 2) = {h 1 (1, 3, 2), h 1 (1, 2, 3), h 1 (3, 2, 1), h 1 (1, 3, 2), h 1 (2, 1, 3), h 1 (2, 3, 1), h 1 (1, 3, 2)}, = {h 2 (1, 2, 3), h 1 (1, 3, 2), h 2 (2, 3, 1)}. Zobecnění h n (1, 3, 2) = {h n 1 (1, 2, 3), h 1 (1, 3, 2), h n 1 (2, 3, 1)}. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 43 / 86

Úloha Hanojských věží 44. Řešení rekurze pro n prvků Základní myšlenka rekurzivního přístupu pro n prvků tvořena 3 kroky: přemístíme n 1 kroužků z první tyče (zdrojové) na druhou tyč (pomocnou) -> rekurze. přemístíme 1 kroužek z první tyče (zdrojové) na třetí tyč (cílovou). přemístíme n 1 kroužků z druhé tyče (pomocné) na třetí (cílovou) -> rekurze. Kroky 1) a 3) řeší stejnou úlohu avšak s jinými tyčemi a menším množstvím prvků. Kroky 1) a 3) lze rekurzivně dále rozložit stejným způsobem jako výchozí úlohu Úloha je dekomponovatelná na úlohy stejného typu. V každém kroku se velikost množiny zmenšuje, pro řešení lze využít rekurzi. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 44 / 86

45. Zápis zdrojového kódu Úloha Hanojských věží goid hanoi(int n, int o, int k, int p) { } if (n==0) return; //Ukonceni rekurze, neni co presouv hanoi(n-1, o, p, k); //Presun 1-2 System.out.println( Z + o + na + k); hanoi(n-1, p, k, o); //Presun 2-3 Volání: hanoi(3,1,3,2); Počet rekurzivních volání: 2 n 1. Velmi neefektivní, max 20 kroužků. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 45 / 86

Úloha Hanojských věží 46. Znázornění stromu rekurzivních volání Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 46 / 86

Úloha Hanojských věží 47. Znázornění posloupnosti rekurzivních volání Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 47 / 86

48. QuickSort Příklady použití rekurze QuickSort Třídící algoritmus založený na principu rozděl a panuj. Velmi rychlý pro většinu typů vstupních dat, rychlost ovlivňuje prohazování prvků na velké vzdálenosti. Lze řešit prostřednictvím rekurze. Tříděná posloupnost prvků: {x 1,..., x n }. Princip algoritmu QuickSort: 1 V prvním kroku je zvolena střední hodnota x, tzv. pivot (medián, modus, náhodně). 2 Posloupnost je uspořádána rozdělením na dvě části tak, že levá část obsahuje prvky x i < x, pravá část prvky x i > x. 3 Každá z těchto částí je stejným způsobem rekurzivně rozdělena. 4 Počty úseků se s každým dělením zdvojnásobují, délky úseků (tj. počty prvků) snižují na polovinu. 5 Dělení provádíme tak dlouho, dokud délky úseků nejsou rovny jedné. Problém lze opět řešit rekurzí: zmenšování množiny a dekompozice na problémy stejné třídy. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 48 / 86

QuickSort 49. Pseudokód algoritmu QuickSort QuickSort(double [] pole, int levy, int pravy) { } int mid =(int)(0.5 * ( l + p ) ); //Prostredni prvek /* Vlastni trideni, probrano pozdeji */ QuickSort(pole, levy, mid -1); //Setrideni leve polovin QuickSort(pole,mid + 1, pravy); //Setrideni prave polov Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 49 / 86

QuickSort 50. Ukázka činnosti algoritmu QuickSort Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 50 / 86

51. QuickSort, strom pivotů QuickSort Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 51 / 86

52. Binární strom Příklady použití rekurze Binární stromy Vlastnosti binárního stromu: Acyklický graf. Uzly stupně n = 2. Každý uzel má dva potomky: levý podstrom a pravý podstrom. Existuje právě jeden uzel, do kterého nevstupuje žádná hrana. Do každého uzlu existuje právě jedna cesta. Využití pro rychlé vyhledávání, indexace, komprese,... Kořen: uzel, do kterého nevstupuje žádná hrana, nemá předchůdce (1). List: uzel, který nemá potomka. Vnitřní uzly: uzly, které nejsou kořenem či potomkem. Každý vnitřní uzel stromu je kořenem podstromu (podmnožina stromu). Operace nad stromem lze dekomponovat na operace stejného typu nad menší množinou lze efektivně řešit prostřednictvím rekurze. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 52 / 86

Binární stromy 53. Uzly v binárním stromu uzel A=kořen, uzly B-G=vnitřní uzly, uzly H-N=listy. uzel B= kořen stromu {B,D,E,H,I,J}. uzel E=kořen stromu {E,I,J}. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 53 / 86

54. Binární vyhledávací strom Binární stromy Datová struktura, která se používá pro rychlé ukládání a vyhledávání dat. Uspořádání dat ve vyhledávacím stromu: každá hodnota se ve vyhledávacím stromu smí vyskytnout pouze jednou pro každý uzel U platí, že všechny údaje v levém podstromu jsou menší než U a všechny údaje v pravém podstromu větší než U. Operace nad takovým stromem lze realizovat se složitostí O(lg(N)). Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 54 / 86

Binární stromy 55. Operace nad binárním vyhledávacím stromem Základní operace nad binárním stromem: Vytvoření prázdného stromu. Přidání uzlu. Procházení uzlu: PREORDER, INORDER, POSTORDER. Nalezení uzlu. Smazání stromu. Smazání uzlu. Implementace rekurzivní datovou strukturou, odkazuje na prvky stejného typu. public class Uzel { int data; Uzel levy; //Odkaz na levy podstrom Uzel pravy; //Odkaz na pravy podstrom } Další podrobnosti a operace podrobně probrány v letním semestru. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 55 / 86

Binární stromy 56. Procházení binárního stromu 3 základní metody procházení binární stromu: Přímé zpracování (PREORDER): Nejprve zpracován kořen, poté levý podstrom, nakonec pravý podstrom. Vnitřní zpracování (INORDER): Nejprve zpracován levý podstrom, poté kořen, nakonec pravý podstrom. Zpětné zpracování (POSTORDER): Nejprve zpracován levý podstrom, poté pravý podstrom, nakonec kořen. Ukázka zpracování PREORDER: public void preorder(uzel u) { if (u==null) return; else { System.out.println(u.data); //1. koren preorder(u.levy); //2. levy podstrom preorder(u.pravy); //3. pravy podstrom } } Princip zpracování stejný, liší se však pořadím prováděných operací. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 56 / 86

Kartografická generalizace 57. Douglas&Peucker algoritmus Používá se pro generalizaci lomených čar. Na rozdíl od běžných algoritmů neodstraňuje z lomené čáry vrcholy nesplňující geometrickou podmínku, ale přidává do ní vrcholy splňující geometrickou podmínku. Provádí opakované dělení vstupní množiny na menší podmnožiny. V každém kroku dochází ke zjednodušení problému, lze implementovat jako rekurzivní algoritmus. Postup Douglas-Peuckerova algoritmu: Lomená čára L, generalizovaná lomená čára G, parametr generalizačního algoritmu: koridor o šířce h. Přidání počátečního a koncového bodu z L do G. Lomená čára v prvním kroku nahrazena úsečkou. Nalezení bodu Q nejvzdálenějšího od segmentu G takového, který leží vně koridoru o šířce h. Přidání Q do G. Nad každým segmentem G opakuj 2) a 3), dokud existuje nějaký bod vně koridoru. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 57 / 86

Kartografická generalizace 58. Ukázka Douglas-Peuckerova algoritmu Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 58 / 86

Kartografická generalizace 59. Implementace Douglas-Peuckerova algoritmu void dp(double corridor, Polyline input, Polyline output, int start, int end) { if ( end = start + 1 ) return; //Zadny mezilehly bod int index_max = start + 1; //Inicializace double d_max = distance(input[start],input[end], input[start + 1]); } for (int i = start + 2; i < end, i++ ) { //Hledani nejvzdalenejsiho bodu double di=distance(input[start],input[end], input[start + 1]); if (di > d_max) { index_max = i; d_max = di; } } if (d_max >= corridor) { //Rekurze nad obema segmenty dp(corridor, input, start, index_max); dp(corridor, input, index_max, end); output polyline.add(input[index_max]); //Pridani bodu do seznamu } Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 59 / 86

Kartografická generalizace 60. Strom rekurzivního volání Douglas-Peuckerova algoritmu Znázornění situace ze str. 57. Lomená čára tvořená posloupností bodů {P 1,..., P 14 }. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 60 / 86

Jednoduchá kresba s využitím rekurze 61. Kresba vepsaných čtverců rekurzí Nakreslete posloupnost vepsaných čtverců s použitím rekurze. Délku počáteční hrany označme d. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 61 / 86

Jednoduchá kresba s využitím rekurze 62. Rozbor problému Lze problém řešit prostřednictvím rekurze? Úloha je dekomponovatelná na úlohy stejné třídy: kresba čtverců daných vrcholy. V dalším kroku rekurze nedochází k zesložitění problému. Lze snadno stanovit podmínku ukončení rekurze: velikost strany menší než ε. Existuje několik variant řešení problému: Konstrukce po čtvercích: v jednom kroku zkonstruován jeden čtverec. Konstrukce po dvojicích čtverců: v jednom kroku zkonstruována dvojice čtverců. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 62 / 86

63. Znázornění konstrukce Jednoduchá kresba s využitím rekurze Vlevo konstrukce po čtvercích, vpravo konstrukce po dvojicích čtverců. Čtverce konstruované v jednom kroku znázorněny stejnou barvou. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 63 / 86

64. Konstrukce po čtvercích Jednoduchá kresba s využitím rekurze Vrcholy čtverce v i-tém rekurzivním kroku: P (i) 1, P(i) 2, P(i) 3, P(i) 4. P (i) 1 = [x (i) 1, y (i) 1 ], P(i) 2 = [x (i) 2, y (i) 2 ], P(i) 3 = [x (i) 3, y (i) 3 ], P(i) 4 = [x (i) 4, y (i) 4 ]. Vrcholy čtverce v i + 1-tém rekurzivním kroku: P (i+1) 1, P (i+1) 2, P (i+1) 3, P (i+1) 4. P (i+1) 1 = [x (i+1) 1, y (i+1) 1 ], P (i+1) 2 = [x (i+1) 2, y (i+1) 2 ], P (i+1) 3 = [x (i+1) 3, y (i+1) 3 ], P (i+1) 4 = [x (i+1) 4, y (i+1) 4 ]. Jaký je vztah mezi souřadnicemi vrcholů dvou čtverců v různých úrovních rekurze i a i + 1: P (i+1) 1 x (i+1) P (i+1) 2 x (i+1) P (i+1) 3 x (i+1) P (i+1) 4 x (i+1) 1 = x(i) 1 +x(i) 2 y (i+1) 2 1 = y(i) 1 +y(i) 2 2 2 = x(i) 2 +x(i) 3 y (i+1) 2 2 = y(i) 2 +y(i) 3 2 3 = x(i) 3 +x(i) 4 y (i+1) 2 3 = y(i) 3 +y(i) 4 2 4 = x(i) 4 +x(i) 1 y (i+1) 2 4 = y(i) 4 +y(i) 1 2 Podmínka ukončením rekurze: délka strany nenatočenéjo čtverce menší než ε. Tomáš Bayer bayertom@natur.cuni.cz (Katedra(i) aplikované (i) geoinformatiky Rekurze. (i) a kartografie, (i) Přírodovědecká fakulta UK.) 64 / 86

65. Zápis zdrojového kódu Jednoduchá kresba s využitím rekurze void ctverec (int x1,int y1,int x2,int y2,int x3,int y3,int x4, int y4) { } //Podminka ukonceni rekurze if ((x2-x1>0) (y2-y1>0)) //Pouze pro cela cisla { } Volání funkce: //Kresba ctverce MoveTo(x1,y1); //Presun pero LineTo(x2,y2); //Nakresli usecku LineTo(x3,y3); //Nakresli usecku LineTo(x4,y4); //Nakresli usecku LineTo(x1,y1); //Nakresli usecku //Kresli dalsi ctverec ctverec((x1+x2)/2,(y1+y2)/2,(x2+x3)/2, (y2+y3)/2, (x3+x4)/2,(y3+y4)/2,(x4+x1)/2,(y4+y1)/2); ctverec (0,0,d,0,d,d,0,d); Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 65 / 86

66. Konstrukce po dvojicích čtverců Jednoduchá kresba s využitím rekurze Vztah mezi vrcholy čtverců z kroků (i) a (i + 1). Počátek souřadnicového sytému v P 1. Orientace os: x P 1, P 2, y P 1, P 4. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 66 / 86

67. Konstrukce po dvojicích čtverců Jednoduchá kresba s využitím rekurze Vrcholy čtverců v i-tém rekurzivním kroku: P (i) 1, P(i) 2, P(i) 3, P(i) 4 (vnější čtverec) a P (i) 5, P(i) 6, P(i) 7, P(i) 8 (vnitřní čtverec): P (i) 1 x (i) y (i) P (i) 5 x (i) + d 2 y (i) P (i) 2 x (i) + d y (i) P (i) 6 x (i) + d y (i) + d 2 P (i) 3 x (i) + d y (i) + d P (i) 7 x (i) + d 2 y (i) + d P (i) 4 x (i) y (i) + d P (i) 8 x (i) y (i) + d 2 Vrcholy čtverců v i + 1-tém rekurzivním kroku posunuty o hodnotu ± d, velikost strany 4 se zmenší na polovinu d (i+1) = d(i). 2 P (i+1) 1 x (i) 1 + d y (i) 4 1 + d P (i+1) 4 5 x (i+1) 1 + d 2 y (i+1) 1 P (i+1) 2 x (i) 2 d 4 y (i) 2 + d 4 P (i+1) 6 x (i+1) 1 + d y (i+1) 1 + d 2 P (i+1) 3 x (i) 3 d 4 y (i) 3 d 4 P (i+1) 7 x (i+1) 1 + d 2 y (i+1) 1 + d P (i+1) 4 x (i) 4 + d 4 y (i) 4 d 4 P (i+1) 8 x (i+1) 1 y (i+1) 1 + d 2 Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 67 / 86

68. Zápis zdrojového kódu Jednoduchá kresba s využitím rekurze void ctverec (int x,int y,int d) { } if(d>0) { } //Podminka ukonceni rekurze //Kresba ctverce 1 MoveTo(x,y); //Presun pero LineTo(x+d,y); //Nakresli usecku LineTo(x+d,y+d); //Nakresli usecku LineTo(x,y+d); //Nakresli usecku LineTo(x,y); //Nakresli usecku //Kresba ctverce 2 MoveTo(x+d/2,y); //Presun pero LineTo(x+d,y+d/2); //Nakresli usecku LineTo(x+d/2,y+d); //Nakresli usecku LineTo(x,y+d/2); //Nakresli usecku LineTo(x+d/2,y); //Nakresli usecku //Rekurzivni volani funkce ctverec(x+d/4,y+d/4, d/2) Volání funkce: Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 68 / 86

69. Konstrukce spirály rekurzí Zkonstruujte za použití rekurze spirálu. Délka spirály d, zkrácení spirály d. Jednoduchá kresba s využitím rekurze Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 69 / 86

Jednoduchá kresba s využitím rekurze 70. Rozbor problému Lze problém řešit prostřednictvím rekurze? Úloha je dekomponovatelná na úlohy stejné třídy: opakovaná konstrukce jednoho závitu spirály tvořeného 4 úsečkami. V dalším kroku rekurze nedochází k zesložitění problému. Podmínka ukončení rekurze: d d <= 0. Možné řešení problému: Zkonstruujeme jeden závit spirály tvořený 4 segmenty. Délky prvního a druhého segmentu d, délka třetího a čtvrtého segmentu d d. Stejným způsobem rekurzí zkonstruujeme další závity. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 70 / 86

71. Znázornění spirály Jednoduchá kresba s využitím rekurze Vztah mezi závity z i-tého a i + 1 kroku. Počátek souřadnicového sytému v P 1. Orientace os: x P 1, P 2, y P 1, P 4. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 71 / 86

72. Konstrukce spirály Jednoduchá kresba s využitím rekurze Vrcholy závitu v i-tém rekurzivním kroku: P (i) 1, P(i) 2, P(i) 3, P(i) 4. Délka d (i). P (i) 1 x (i) 1 + d (i) y (i) 1 P (i) 2 x (i) 2 + d (i) y (i) 2 + d (i) P (i) 3 x (i) 3 + d (i) y (i) 3 + d (i) P (i) 4 x (i) 4 + d y (i) 4 + d (i) Nová poloha vrcholu P (i+1) 1 = P 1 + d. Změna délky segmentu závitu d (i+1) = d (i) 2 d. Vrcholy závitu v i-tém rekurzivním kroku: P (i+1) 1, P (i+1) 2, P (i+1) 3, P (i+1) 4. P (i+1) 1 x (i) 1 + d (i) y P (i+1) 2 x (i) 2 d (i) y P (i+1) 3 x (i) 3 P (i+1) 4 x (i) 4 1 + d 2 + d d (i) y 3 d + d (i) y 4 d Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 72 / 86

73. Zápis zdrojového kódu Jednoduchá kresba s využitím rekurze void spirala(int x, int y, int d, int diff) { //Test ukonceni rekurze? if (d-diff>0) { LineTo(x,y); LineTo(x+d,y); LineTo(x+d,y+d); LineTo(x+diff,y+d); } } Volání funkce: //Rekurzivni volani spiraly spirala(x+diff,y+diff, d-2*diff,diff) spirala(0,0,200,5); Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 73 / 86

74. Kochova vločka Příklady použití rekurze Konstrukce Kochovy vločky rekurzí Autorem Niels Fabian Helge von Koch. Patří mezi první objevené fraktální křivky. Geometrický útvar vzniklý opakovaným rekurzivním dělením rovnostranného trojúhelníku. Princip konstrukce: Každá ze stran trojúhelníku rozdělena na třetiny. Nad prostřední stranou vytvořen nový rovnostranný trojúhelník, jehož vrchol leží vně původního trojúhelníku. Z nového rovnostranného trojúhelníku odstraněna základna a pokračuje se bodem 1. Kochova vločka vznikne opakováním tohoto postupu n krát. Délka d Kochovy vločky se s každým krokem prodlouží o 1, celková délka Kochovy 3 vločky Pro n dělení platí d = ( 4 3 )n. lim (d) =. n Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 74 / 86

75. Kochova vločka Příklady použití rekurze Konstrukce Kochovy vločky rekurzí Kochova vločka pro n = 1, n = 2, n = 3, n = 4. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 75 / 86

Konstrukce Kochovy vločky rekurzí 76. Postup konstrukce Kochovy vločky Rekurzivní dělení prováděno nad každou ze tří stran trojúhelníku. Známy souřadnice koncových bodů P 1 = [x 1, y 1 ], P 2 = [x 2, y 2 ] strany trojúhelníku. Určujeme souřadnice bodů P 3, P 4, P 5 tvořící koncové body nových segmentů. V každém kroku vznikají čtyři nové segmenty, výsledkem strom čtvrtého stupně. Směrový vektor u, normálový vektor n, n u. ( ) ( ) x2 x u = 1 n y2 y = 1 y 2 y 1 x 1 x 2 Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 76 / 86

77. Výpočet souřadnic vrcholů Konstrukce Kochovy vločky rekurzí Souřadnice bodů P 1, P 2, P 3 ( x3 ) y 5 ( 3 x5 ) y 4 ( x4 ) = = = ( ) x1 + 1 ( ) x2 x 1 y 1 3 y 2 y 1 ( ) x1 + 2 ( ) x2 x 1 y 1 3 y 2 y 1 ( ) ( ) 1 x1 + x 2 y2 y + α 1, kde α (0, 1). 2 y 1 + y 2 x 1 x 2 Výška h v P 4, P 5, Q Parametr α Bod P 4 h = d 2 α = h n 9 d2 36 = d 2 3. = d 2 3d = 1 2 3. ( ) [( ) x4 1 x1 + x = 2 + 1 ( )] y2 y 1. y 4 2 y 1 + y 2 3 x 1 x 2 Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 77 / 86

Konstrukce Kochovy vločky rekurzí 78. Zápis zdrojového kódu void koch(double x1,double y1, double x2,double y2, int n) { if (n>1) { } else //Podminka ukonceni rekurze //Strana 1 koch(x1,y1,x1+(x2-x1)/3,y1+(y2-y1)/3,n-1); //Strana2 koch(x1+(x2-x1)/3,y1+(y2-y1)/3,(x1+x2)/2+2*sqrt(3)* (y2-y1),(y1+y2)/2+2*sqrt(3)*(x1-x2),n-1); //Strana 3 koch((x1+x2)/2+2*sqrt(3)*(y2-y1),(y1+y2)/2+2* sqrt(3)*(x1-x2),x1+2*(x2-x1)/3,y1+2*(y2-y1)/3,n-1); //Strana 4 koch(x1+2*(x2-x1)/3,y1+2*(y2-y1)/3,n-1); { //Kresba usecky MoveTo(x1,y1); LineTo(x2,y2); } Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 78 / 86

79. Vhodnost/nevhodnost rekurze Vhodnost/nevhodnost rekurze Při práci s rozsáhlými daty jsou rekurzivní algoritmy neefektivní, značné nároky na pamět. Lze ji použít, pokud počet rekurzivních volání roste lineárně: funkce by měla obsahovat pouze jedno rekurzivní volání sama sebe. Pro každé rekurzivní volání vytvoření nové sady lokálních proměnných, jejich uložení do zásobníku a následné vyjmutí (značná hw. režie). Nevhodná změna hodnoty proměnné ovlivňující ukončení rekurze způsobí nekonečnou rekurzi. Pro rozsáhlé datové soubory může dojít pamět dříve, než nalezeno řešení. Stručný, ale nepříliš přehledný kód, někdy není jasné, co algoritmus dělá. Používá se u řešení problémů, kde není známo nerekurzivní řešení. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 79 / 86

Převod rekurze na iteraci 80. Převod rekurze na iteraci Cílem zefektivnění algoritmu, zejména snížení nároků na pamět. Každý rekurzivní algoritmus lze přepsat na iterační. U některých jazyků jediná možnost k provádění iterace představuje rekurze (nepoužívají cykly). Možnosti převodu rekurze na iteraci: Jednoduchá rekurze Náhrada jedním cyklem (preference) či využití zásobníku popř. kombinace. Vícenásobná rekurze Každé rekurzivní volání reprezentováno samostatným vnořeným cyklem nebo využití zásobníku. Zásobník zpravidla používán pro složitější problémy, kde použití pouze cyklů nepřehledné. Pro běžné typy problémů řešených rekurzí existují tzv. rekurzivní schémata: řešení problémů bez rekurze. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 80 / 86

Převod rekurze na iteraci 81. Odstranění jednoduché rekurze zásobníkem Kombinace zásobníku (Stacku) + cyklu. Dva kroky: Převod lokálních proměnných na globální. Lokální proměnné procedury/funkce převedeny na globální vzhledem k rekurzivní funkci. Převod rekurze bez lokálních proměnných na iteraci. Rekurzivní podmínka převedena na řídící podmínku cyklu Proměnné a mezivýsledky přidávány do zásobníku a následně dopočítávány jako při zpětné rekurzi. Nevýhodou velká režie spojená se zásobníkem, hardwarově náročné. Preferujeme cykly, pokud je to možné. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 81 / 86

Převod rekurze na iteraci 82. Jednoduchá rekurzivní funkce & Stack f (n) //Rekurzivni funkce: prima rekurze { Stack S; S.push(D(n)); //Hodnota D pro n i = n; //Ridici promenna cyklu while (i == podminka) { C i ; //Blok prikazu, fce n sestupne res_old = S.pop(); //Vyjme predchozireseni res = D(i,res_old) //Aktualizace reseni S.push(res) //Pridani noveho reseni E n i ; //Blok prikazu, fce n vzestupne i--; //Dekrementace i } } Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 82 / 86

Převod rekurze na iteraci 83. Fibonacciho čísla zásobníkem fib (n) { Stack s; S.push (0); S.push (1); while (n > 1) { int fi = S.pop(); //i-ty clen int fi_1= S.pop(); //i-1 clen int fii = fi + fi_1; //i+1 clen S.push(fi); //Pridani jako i-1 clenu S.push(fii); //Pridani jako i clenu n--; } Opět neefektivní, v každé iteraci dvojí přidávání a výběr ze zásobníku. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 83 / 86

Převod rekurze na iteraci 84. Rekurzivní schémata Řada návrhů algoritmů vede k jejich rekurzivní implementaci. Základní rekurzivní implementace většiny algoritmů jsou podobné, vedou ke vzniku rekurzivních schémat. Nejčastější rekurzivní schémata: schéma if-else: F = {G, if P then F } schéma while-do: F = {G, while P do F } V obou případech nemá smysl rekurzi používat, lze ji snadno nahradit iterací. Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 84 / 86

Převod rekurze na iteraci 85. Rekurzivní schéma if-else Často používané rekurzivní schéma s jedním voláním. Náhrada úplné podmínky dvojicí cyklů. Nejprve vyřešena kladná část podmínky, v samostatném cyklu větev else. C () C() { { if (podminka(x)) int n = 0; { while (podminka(x)) A(x); { C(); A(x); B(x); n++; } } else D(x) D(x); } while (n--!=0) B(x); Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 85 / 86

Převod rekurze na iteraci 86. Rekurzivní schéma while-do Rekurzivní schéma s jedním voláním opakováno v cyklu, dokud splněna podmínka. Náhrada rekurze dvojicí cyklů + záměna cyklu while za do-while. C () C() { { while (podminka(x)) int n = 0; { do A(x); { C(); while (podminka(x)) B(x); { } A(x); D(x) n++; } } D(x); if (n==0) return; n--; B(x); } while (n!=0); Tomáš Bayer bayertom@natur.cuni.cz (Katedra aplikované geoinformatiky Rekurze. a kartografie, Přírodovědecká fakulta UK.) 86 / 86