Část I. Rekurze. Část 1 Rekurze. Rekurze. Část 2 Příklady. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze

Podobné dokumenty
Rekurze. Jan Faigl. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze. Přednáška 6 A0B36PR1 Programování 1

Rekurze. Jan Faigl. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze. Přednáška 6 A0B36PR1 Programování 1

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

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

Rozklad problému na podproblémy

Nerovnice s absolutní hodnotou

2.8.9 Parametrické rovnice a nerovnice s absolutní hodnotou

Standardní knihovny C. Rekurze.

Rozklad problému na podproblémy, rekurze

Rozklad problému na podproblémy, rekurze

Část I. Část 1 Standardní knihovny, čtení/zápis ze souboru. Přehled témat. Standardní knihovny C. Rekurze. Standardní knihovny

Standardní knihovny C. Rekurze.

Kvadratické rovnice pro učební obory

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

{ } Kombinace II. Předpoklady: =. Vypiš všechny dvoučlenné kombinace sestavené z těchto pěti prvků. Urči počet kombinací pomocí vzorce.

Kvantové počítače algoritmy (RSA a faktorizace čísla)

2.7.2 Mocninné funkce se záporným celým mocnitelem

Část 1 Standardní knihovny, čtení/zápis ze/do souboru

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

1. Programování, typy programovacích jazyků, historie.

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

Číselné soustavy Ing. M. Kotlíková, Ing. A. Netrvalová Strana 1 (celkem 7) Číselné soustavy

( ) Kreslení grafů funkcí metodou dělení definičního oboru I. Předpoklady: 2401, 2208

Funkce a procedury. Jan Faigl. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze. Přednáška 5 A0B36PR1 Programování 1

Kvadratické rovnice pro studijní obory

Dopravní úloha. Jiří Neubauer. Katedra ekonometrie FEM UO Brno

3.2.4 Podobnost trojúhelníků II

Část 1 Funkce, lokální proměnné a přidělování paměti. Funkce a procedury. Část 2 Cykly a řízení jejich průchodu. Část 3 Příklady

Paradigmata programování 1

Algoritmizace a programování

Hledání k-tého nejmenšího prvku

3. Ve zbylé množině hledat prvky, které ve srovnání nikdy nejsou napravo (nevedou do nich šipky). Dát do třetí

Zákonitosti, vztahy a práce s daty

Př. 3: Dláždíme čtverec 12 x 12. a) dlaždice 2 x 3 12 je dělitelné 2 i 3 čtverec 12 x 12 můžeme vydláždit dlaždicemi 2 x 3.

Třídy a objekty -příklady

1.3.1 Kruhový pohyb. Předpoklady: 1105

STEREOMETRIE. Vzdálenost bodu od přímky. Mgr. Jakub Němec. VY_32_INOVACE_M3r0113

= musíme dát pozor na: jmenovatel 2a, zda je a = 0 výraz pod odmocninou, zda je > 0, < 0, = 0 (pak je jediný kořen)

Filtrace snímků ve frekvenční oblasti. Rychlá fourierova transformace

Zvyšování kvality výuky technických oborů

Algoritmizace a programování

INŽENÝRSKÁ MATEMATIKA LOKÁLNÍ EXTRÉMY

Operační systém teoreticky

16. února 2015, Brno Připravil: David Procházka

Principy překladačů. Architektury procesorů. Jakub Yaghob

Dynamické datové struktury III.

4.2.7 Voltampérová charakteristika rezistoru a žárovky

Intervalové stromy. Představme si, že máme posloupnost celých čísel p 0, p 1,... p N 1, se kterou budeme. 1. Změna jednoho čísla v posloupnosti.

( ) Neúplné kvadratické rovnice. Předpoklady:

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

Kalendář je nástroj, který vám pomůže zorganizovat si pracovní čas. Zaznamenáváme do něj události jako schůzky, termíny odevzdání práce a podobně.

Pracovní ukázka vstupního testu DSA 1.

Pingpongový míček. Petr Školník, Michal Menkina. TECHNICKÁ UNIVERZITA V LIBERCI Fakulta mechatroniky, informatiky a mezioborových studií

4.6.6 Složený sériový RLC obvod střídavého proudu

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

( ) ( ) ( ) 2 ( ) Rovnice s neznámou pod odmocninou II. Předpoklady: 2715

Tvorba trendové funkce a extrapolace pro roční časové řady

Matematika a její aplikace. Matematika a její aplikace

Mobilní aplikace pro ios

Gymnázium Vysoké Mýto nám. Vaňorného 163, Vysoké Mýto

int t1, t2, t3, t4, t5, t6, t7, prumer; t1=sys.readint();... t7=sys.readint(); prume pru r = r = ( 1+t 1+t t3+ t3+ t4 t5+ t5+ +t7 +t7 )/ ;

Postup práce s elektronickým podpisem

Plán předmětu Název předmětu: Školní rok: Ročník: Semestr: Typ předmětu: Rozsah předmětu: Počet kreditů: Přednášející: Cvičící: Cíl předmětu

Příklady a návody. Databázová vrstva

DUM téma: KALK Výrobek sestavy

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

přirozený algoritmus seřadí prvky 1,3,2,8,9,7 a prvky 4,5,6 nechává Metody řazení se dělí:

9.2.5 Sčítání pravděpodobností I

1.1.1 Kvadratické rovnice (dosazení do vzorce) I

Výsledky testování školy. Druhá celoplošná generální zkouška ověřování výsledků žáků na úrovni 5. a 9. ročníků základní školy. Školní rok 2012/2013

DSA, První krok: máme dokázat, že pro left = right vrátí volání f(array, elem, left, right)

Střední průmyslová škola strojnická Olomouc, tř.17. listopadu 49

Sada 2 - MS Office, Excel

JAK PŘIDAT UŽIVATELE PRO ADMINISTRÁTORY

Přepočet přes jednotku - podruhé II

Google Apps. pošta 2. verze 2012

Semestrální práce NÁVRH ÚZKOPÁSMOVÉHO ZESILOVAČE. Daniel Tureček zadání číslo 18 cvičení: sudý týden 14:30

IMPORT A EXPORT MODULŮ V PROSTŘEDÍ MOODLE

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

Aritmetika s didaktikou I.

Kapitola 7: Integrál. 1/14

15 s. Analytická geometrie lineárních útvarů

2.7.1 Mocninné funkce s přirozeným mocnitelem

Na začátku rozdělíme práci a určíme, které podproblémy je potřeba vyřešit. Tyto

Třídění a vyhledávání Searching and sorting

Důkazové metody. Teoretická informatika Tomáš Foltýnek

Výsledky testování školy. Druhá celoplošná generální zkouška ověřování výsledků žáků na úrovni 5. a 9. ročníků základní školy. Školní rok 2012/2013

Používání IS Carsystem

Stromy. Základní pojmy

(a) = (a) = 0. x (a) > 0 a 2 ( pak funkce má v bodě a ostré lokální maximum, resp. ostré lokální minimum. Pokud je. x 2 (a) 2 y (a) f.

Tabulky Word egon. Tabulky, jejich formátování, úprava, změna velikosti

Jméno autora: Mgr. Zdeněk Chalupský Datum vytvoření: Číslo DUM: VY_32_INOVACE_13_FY_A

AUTORKA Barbora Sýkorová

Metodika - Postupy optimálního využití moderních komunikačních kanálů

Bubble sort. příklad. Shaker sort

Dualita v úlohách LP Ekonomická interpretace duální úlohy. Jiří Neubauer. Katedra ekonometrie FEM UO Brno

Svobodná chebská škola, základní škola a gymnázium s.r.o. Zlomky sčítání a odčítání. Dušan Astaloš. samostatná práce, případně skupinová práce

PŘÍRUČKA K POUŽÍVÁNÍ APLIKACE HELPDESK

PHP formátování řetězců

Název: VY_32_INOVACE_PG3309 Booleovské objekty ve 3DS Max - sčítání a odčítání objektů

Transkript:

Část Rekurze Rekurze Jan Faigl Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze Přednáška 6 A0B6PR Programování Faktoriál Obrácený výpis Karel Hanojské věže Rekurze Fibonacciho posloupnost Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze / 9 Část Příklady Eratosthenovo síto Rozklad na prvočinitele Část I Rekurze Řazení Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze / 9

Výpočet faktoriálu Příklad výpis posloupnosti / Iterace n! = n(n )(n )... int factoriali(int n) { int f = ; for(; n > ; --n) { f *= n; return f; Rekurze n! = pro n n! = n(n )! pro n > int factorialr(int n) { int f = ; if (n > ) { f = n * factorialr(n-); return f; lec05/demofactorial.java Připomínka Vytvořte program, který přečte posloupnost čísel a vypíše ji v opačném pořadí Rozklad problému: Zavedeme abstraktní příkaz: obrať posloupnost Příkaz rozložíme do tří kroků:. Přečti číslo číslo uložíme pro pozdější obrácený výpis. Pokud není detekován konec posloupnost obrať posloupnost pokračujeme ve čtení čísel. Vypiš číslo vypíšeme uložené číslo Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 6 / 9 Příklad výpis posloupnosti / void reverse() { int v = scan.nextint(); if (scan.hasnext()) { reverse(); 5 6 System.out.printf("%d ", v); 7 8 9 public void start() { 0 System.err.println("Enter a sequence of numbers ( use ctr+d for the end of the the sequence"); reverse(); System.out.println(""); //end of line lec06/demorevertsequence.java Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 9 / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 8 / 9 Příklad výpis posloupnosti / lec06/demorevertsequence.java Vytvoření posloupností./generate_numbers.sh tr \n cat > numbers.txt javac DemoRevertSequence.java java DemoRevertSequence < numbers.txt >/dev/null > numbersr.txt java DemoRevertSequence <numbers-r.txt >/dev/null > numbers -rr.txt Příkaz pro výpis obsahu souborů for i in numbers.txt numbers-r.txt numbers-rr.txt; do echo "$i"; cat $i; echo ""; done Výpis obsahu souborů numbers.txt 0 0 8 8 5 8 6 7 7 numbers-r.txt 7 7 6 8 5 8 8 0 0 numbers-rr.txt 0 0 8 8 5 8 6 7 7 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 0 / 9

Robot Karel hledání beeperu Robot Karel má za úkol najít beeper v bludišti a vrátit se s ním zpět na výchozí pozici Karel se pohybuje v mřížkovém ortogonálním světě Karel umí: jít rovně o jeden krok otočit se doleva o 90 vzít / položit beeper vypnout se Karel umí zjistit, zda-li: je před ním zeď je na políčku, na kterém stojí, beeper Robot Karel Iterační řešení / Návrh řešení. Jdi podél zdi (po pravé straně) dokud není na políčku beeper a počítej počet kroků;. Seber beeper ;. Otoč se a jdi podél zdi (po levé straně) a udělej stejný počet kroků jako při hledání beeperu ;. Polož beeper a vypni se. Abstraktní příkazy pro nalezení beeperu sledování zdi na pravé straně: Otoč se doprava: turnright Zjisti, zda-li je na pravé straně zeď: iswallonright Jdi podél pravé zdi: gobyrightwall Analogické abstraktní příkazy pro pohyb podél zdi na levé straně: iswallonleft a gobyleftwall Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze / 9 Robot Karel Iterační řešení / void turnright() { for (int i = 0; i < ; i++) { turnleft(); 5 6 7 boolean iswallonright() { 8 turnright(); 9 boolean out = isinfrontofwall(); 0 turnleft(); return out; void gobyrightwall() { 5 while (!isonbeeper()) { 6 if (!wallonright()) { 7 turnright(); 8 9 while (isinfrontofwall()) { 0 turnleft(); step(); Analogicky pro zeď po levé straně Robot Karel Iterační řešení / Počet kroků je inkrementován v proceduře step Při návratu podél levé zdi Karel ujde stejný počet kroků public void execute() { gobyright(); pickbeeper(); turnaround(); 5 6 if (stepstaken > 0) { 7 gobyleft(stepstaken); 8 9 0 putbeeper(); turnoff(); Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 5 / 9

Robot Karel Rekurzivní řešení / Řešení rekurzí založíme na opakovaném volání funkce, která posune robot pouze o jeden krok vpřed a následně jej vrátí zpět ve funkci go:. Pokud jsi na beeperu seber jej a otoč o 80 a ukonči hledání. Zapamatuj si svou orientaci a udělej jeden krok podél pravé zdi. go (opakuj hledání o jeden krok). Udělej jeden krok zpět (vrať se o jeden krok zpět a natoč se do původního směru) Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 6 / 9 Robot Karel Rekurzivní řešení / Hlavní procedura obsahuje pouze volání funkce go, která vrací robot na výchozí políčko void execute() { go(); putbeeper(); turnoff(); 5 Pro spuštění využijeme knihovnu KarelJRobot.jar a modifikovaný svět maze.klwd javac -cp lib/kareljrobot.jar DemoKarel.java java -cp lib/kareljrobot.jar:. DemoKarel Robot se při zpáteční cestě vrací rychleji, protože již explicitně nekontroluje, zda-li je zeď na levé straně. Uvedený demonstrační program není plným řešení úlohy ze. cvičení lec06/demokarel.java Robot Karel Rekurzivní řešení / void go() { if (isonbeeper()) { pickbeeper(); 5 turnaround(); //turn back return; 6 7 int numberturnright = 0; 8 if (!iswallonright()) { 9 0 turnright(); numberturnright++; while (isinfrontofwall()) { 5 turnleft(); numberturnright--; 6 7 move(); //move forward 8 go(); 9 move(); //move backward 0 numberturnright = (numberturnright + ) % ; for (int i = 0; i < numberturnright; ++i) { turnleft(); //revert the turns 5 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 7 / 9 Příklad Hanojské věže Přemístit disky na druhou jehlu s použitím třetí (pomocné) jehly za dodržení pravidel:. V každém kroku můžeme přemístit pouze jeden disk a to vždy z jehly na jehlu Disky nelze odkládat mimo jehly. Položit větší disk na menší není dovoleno Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 8 / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 0 / 9

Hanojské věže disk Hanojské věže disk Přesunutý disk z jehly na jehlu. Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze / 9 Hanojské věže disk Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze / 9 Hanojské věže disky Hotovo Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze / 9

Hanojské věže disky Hanojské věže disky Přesunutý disk z jehly na jehlu. Přesunutý disk z jehly na jehlu. Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 5 / 9 Hanojské věže disky Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 6 / 9 Hanojské věže disky Hotovo Přesunutý disk z jehly na jehlu. Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 7 / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 8 / 9

Hanojské věže disky Hanojské věže disky Přesunutý disk z jehly na jehlu. Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 9 / 9 Hanojské věže disky Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 0 / 9 Hanojské věže disky Přesunutý disk z jehly na jehlu. Přesunutý disk z jehly na jehlu. Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze / 9

Hanojské věže disky Hanojské věže disky Přesunutý disk z jehly na jehlu. Přesunutý disk z jehly na jehlu. Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze / 9 Hanojské věže disky Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze / 9 Hanojské věže disky Přesunutý disk z jehly na jehlu. Přesunutý disk z jehly na jehlu. Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 5 / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 6 / 9

Hanojské věže disky Hanojské věže disky Hotovo Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 7 / 9 Hanojské věže disky Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 8 / 9 Hanojské věže disky Přesunutý disk z jehly na jehlu. Přesunutý disk z jehly na jehlu. Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 9 / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 0 / 9

Hanojské věže disky Hanojské věže disky Přesunutý disk z jehly na jehlu. Přesunutý disk z jehly na jehlu. Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze / 9 Hanojské věže disky Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze / 9 Hanojské věže disky Přesunutý disk z jehly na jehlu. Přesunutý disk z jehly na jehlu. Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze / 9

Hanojské věže disky Hanojské věže disky Přesunutý disk z jehly na jehlu. Přesunutý disk z jehly na jehlu. Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 5 / 9 Hanojské věže disky Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 6 / 9 Hanojské věže disky Přesunutý disk z jehly na jehlu. Přesunutý disk z jehly na jehlu. Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 7 / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 8 / 9

Hanojské věže disky Hanojské věže disky Přesunutý disk z jehly na jehlu. Přesunutý disk z jehly na jehlu. Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 9 / 9 Hanojské věže disky Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 50 / 9 Hanojské věže disky Přesunutý disk z jehly na jehlu. Přesunutý disk z jehly na jehlu. Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 5 / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 5 / 9

Hanojské věže disky Hanojské věže disky Hotovo Přesunutý disk z jehly na jehlu. Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 5 / 9 Hanojské věže 5 disků Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 5 / 9 Návrh řešení 5? 5 Zavedeme abstraktní příkaz movetower(n,,, ) realizující přesun n disků z jehly na jehlu s použitím jehly. Pro n > 0 můžeme příkaz rozložit na tři jednodušší příkazy. movetower(n-,,, ) přesun n disků z jehly na jehlu. přenes disk z jehly na jehlu přesun největšího disku na cílovou pozici abstraktní příkaz. movetower(n-,,, ) přesun n disků na cílovou pozici Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 55 / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 56 / 9

Příklad řešení void movetower(int n, int from, int to, int tmp) { if (n > 0) { movetower(n -, from, tmp, to); //move to tmp System.out.println("Move disc from " + from + " to " + to); 5 movetower(n -, tmp, to, from); //move from tmp 6 7 8 9 void start() { 0 int numberofdiscs = 5; movetower(numberofdiscs,,, ); lec06/demotowersofhanoi.java Příklad výpisu lec06/demotowersofhanoi.java java DemoTowersOfHanoi Move disc from to Move disc from to Move disc from to Move disc from to Move disc from to Move disc from to Move disc from to java DemoTowersOfHanoi Move disc from to Move disc from to Move disc from to Move disc from to Move disc from to Move disc from to Move disc from to Move disc from to Move disc from to Move disc from to Move disc from to Move disc from to Move disc from to Move disc from to Move disc from to Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 57 / 9 Rekurzivní algoritmy Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 58 / 9 Rekurzivní vs iteračními algoritmy Rekurzivní funkce jsou přímou realizací rekurzivních algoritmů Rekurzivní algoritmus předepisuje výpočet shora dolů v závislosti na velikosti vstupních dat Pro nejmenší (nejjednodušší) vstup je výpočet předepsán přímo Pro obecný vstup je výpočet předepsán s využitím téhož algoritmu pro menší vstup Výhodou rekurzivních funkcí je jednoduchost a přehlednost Nevýhodou rekurzivních algoritmů může být časová náročnost způsobená např. zbytečným opakováním výpočtu Řadu rekurzivních algoritmů lze nahradit iteračními, které počítají výsledek zdola nahoru, tj. od menších (jednodušších) vstupních dat k větším (složitějším). Pokud algoritmus výpočtu zdola nahoru nenajdeme, např. při řešení problému Hanojských věží, lze rekurzivitu odstranit pomocí zásobníku. Např. zásobník využijeme pro uložení stavu řešení problému. Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 60 / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 6 / 9

Rekurze Elegance vs obtížnost rekurze To iterate is human, to recurse divine. L. Peter Deutsch http://www.devtopics.com/0-great-computer-programming-quotes I ve often heard people describe understanding recursion as one of those got it moments, when the universe opened its secret stores of knowledge and gifted the mind of a burgeoning developer with a very powerful tool. For me, recursion has always been hard. Each time I m able to peer more into its murky depths, I am humbled to see how little I feel like I really appreciate and understand its power and elegance. Rick Winfrey, 0 to-iterate-is-human-to-recurse-divine http://selfless-singleton.rickwinfrey.com/0//7/ Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 6 / 9 Fibonacciho posloupnost,,,, 5, 8,,,, 55,... F n = F n + F n pro F =, F = Nebo 0,,,,, 5,... Nebo F = 0, F = Nekonečná posloupnost přirozených čísel, kde každé číslo je součtem dvou předchozích. Limita poměru dvou následujících čísel Fibonacciho posloupnosti je rovna zlatému řezu. Sectio aurea ideální poměr mezi různými délkami Rozdělení úsečky na dvě části tak, že poměr větší části ku menší je stejný jako poměr celé úsečky k větší části ϕ = + 5,68 0 988 79 89 88... 5 8 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 6 / 9 Fibonacciho posloupnost historie Indičtí matematici (50 nebo 00 BC) Leonardo Pisano (75 50) popis růstu populace králíků italský matematik známý také jako Fibonacci F n velikost populace po n měsících za předpokladu První měsíc se narodí jediný pár. Narozené páry jsou produktivní od. měsíce svého života. Každý měsíc zplodí každý produktivní pár jeden další pár. Králíci nikdy neumírají, nejsou nemocní atd. Henry E. Dudeney (857 90) popis populace krav Jestliže každá kráva vyprodukuje své první tele (jalovici) za rok a poté každý rok jednu další jalovici, kolik budete mít krav za let, jestliže žádná nezemře a na počátku budete mít jednu krávu? Po let je k dispozici jeden či více býků Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 65 / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 66 / 9

Fibonacciho posloupnost rekurzivně Platí: f 0 = f = f n = f n + f n, pro n > int fibonacci(int n) { return n <? : fibonacci(n - ) + fibonacci(n - ); 5 Zápis je elegantní, jak je však takový výpočet efektivní? Fibonacciho posloupnost příklad / Počet operací při výpočtu Fibonacciho čísla n long counter; long fibonnacir(int n) { counter++; 5 return n <? : fibonnacir(n-) + fibonnacir(n-); 6 7 8 long fibonnacii(int n) { 9 long fibm = l; 0 long fibm = l; long fib = l; for (int i = ; i <= n; ++i) { fibm = fibm; fibm = fib; 5 fib = fibm + fibm; 6 counter += ; 7 8 return fib; 9 lec06/demofibonacci.java Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 67 / 9 Fibonacciho posloupnost rekurzivně / public void start(string[] args) { int n = args.length > 0? Integer.parseInt(args[0]) : 5; counter = 0; 5 long fibr = fibonnacir(n); long counter = counter; 6 7 counter = 0; 8 9 long fibi = fibonnacii(n); long countei = counter; 0 System.out.println("Fibonacci number recursive: " + fibr); System.out.println("Fibonacci number iteration: " + fibi); System.out.println("Counter recursive: " + counter); System.out.println("Counter recursive: " + countei); 5 javac DemoFibonacci.java java DemoFibonacci 0 Fibonacci number recursive: 669 Fibonacci number iteration: 669 Counter recursive: 6957 Counter iteration: 8 lec06/demofibonacci.java Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 69 / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 68 / 9 Fibonacciho posloupnost rekurzivně vs iteračně Rekurzivní výpočet Složitost roste exponenciálně s n n Iterační algoritmus Počet operací je proporcionální n n Skutečný počet operací závisí na konkrétní implementaci, programovacím jazyku, překladači a hardware Složitost algoritmů proto vyjadřujeme asymptoticky jako funkci velikosti vstupu Například v tzv. Big O notaci rekurzivní algoritmus výpočtu má složitost O( n ) iterační algoritmus výpočtu má složitost O(n) Efektivní algoritmy mají polynomiální složitost Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 70 / 9

Část II Příklady Pole reprezentující množinu prvočísel Vypsat všechna prvočísla menší nebo rovna zadané hodnotě max Algoritmus:. Vytvoříme množinu obsahující všechna přirozená čísla od do max. Z množiny vypustíme násobky čísla. Najdeme nejbližší číslo k tomu, jehož násobky jsme v předchozím kroku vypustili, a vypustíme všechny násobky tohoto čísla. Opakujeme krok, dokud číslo, jehož násobky jsme vypustili, není větší než odmocnina z max 5. Čísla, která v množině zůstanou, jsou hledaná prvočísla Pro reprezentaci množiny čísel použijeme pole prvků typu boolean, kde prvek pole sieve[i] udává, zda-li je celé číslo i v množině (true) nebo není (false), tj. zda-li je nebo není prvočíslem Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 7 / 9 Eratosthenovo síto / boolean[] createsieve(int max) { boolean[] sieve = new boolean[max + ]; for (int i = ; i <= max; ++i) { sieve[i] = true; 5 6 int p = ; 7 int pmax = (int)math.sqrt(max); 8 do { 9 for(int i = p + p; i <= max; i += p) { 0 sieve[i] = false; do { p++; while (!sieve[p]); 5 while (p <= pmax); 6 return sieve; 7 lec06/demosieveoferatosthenes.java Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 7 / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 7 / 9 Eratosthenovo síto / void print(boolean[] sieve) { for(int i = ; i < sieve.length; ++i) { if (sieve[i]) { System.out.print(i + " "); 5 6 7 8 9 void start(int max) { 0 boolean[] sieve = createsieve(max); System.out.print("Prime numbers from to " + max + ": "); print(sieve); System.out.println(""); javac DemoSieveOfEratosthenes.java java DemoSieveOfEratosthenes Prime numbers from to 00: 5 7 7 9 9 7 7 5 59 6 67 7 7 79 8 89 97 java DemoSieveOfEratosthenes 0 Prime numbers from to 0: 5 7 7 9 9 lec06/demosieveoferatosthenes.java Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 75 / 9

Rozklad na prvočinitele / Rozklad přirozeného čísla n na součin prvočísel Řešení: Dělit, pak, pak 5 a dalšími prvočísly, až n Každé dělení beze zbytku dodá jednoho prvočinitele Příklad: 60 / 0 / 5 / 5 / 5 60 má prvočinitele,,, 5 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 77 / 9 Řazení pole Problém seřadit množinu prvků podle klíče (celého čísla) Posloupnost prvků q = a,..., a n Délka posloupnosti q je q = n Posloupnost q je seřazená, právě tehdy když q < q klíč(a ) klíč(a ) a posloupnost a,... neobsahuje prvek a. Řazení polí je řazením na místě Pro jednoduchost v příkladech třídíme jen celá čísla, prakticky však zpravidla třídíme klíče datových položek. Rozklad na prvočinitele / Iterační algoritmus void getprimesi(int x) { int d = ; while (d < x) { while (d < x && x % d!= 0) { d++; System.out.print(d + " "); x = x / d; void start(int n) { Rekurzivní algoritmus System.out.println("Decomposition of " System.out.print("Iterative algorithm: "); getprimesi(n); System.out.println(""); System.out.print("Recursive algorithm: "); getprimesr(n, ); System.out.println(""); void getprimesr(int x, int d) { if (d < x) { while (d < x && x % d!= 0) { d++; System.out.print(d + " "); getprimesr(x / d, d); + n + " to primies"); lec06/demoprimes.java Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 78 / 9 Třídění přímým vkládáním Insert Sort / Příklad - Třídění přímým vkládáním 5 6 5 6 55 9 8 55 55 55 55 9 8 55 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 80 / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 8 / 9

Třídění přímým vkládáním Insert Sort / for i, n vlož a i na patřičné místo mezi a,..., a i Příklad - Algoritmus void insertsort(int[] array) { int x; int j; for (int i = ; i < array.length; i++) { 5 6 x = array[i]; j = i - ; 7 while (j >= 0 && x < array[j]) { 8 9 array[j + ] = array[j]; j--; 0 array[j + ] = x; Řazení přímým výběr Select Sort / for i, n { najdi index k nejmenšího prvku v a i,..., a n, a k = min a i,... a n, zaměň prvky a i, a k Třídění binárním vkládáním - vkládání provádíme do již zatříděného pole a,..., a i. Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 8 / 9 Řazení přímým výběr Select Sort / Příklad - Řazení přímým výběrem Select Sort 5 5 6 55 9 8 55 9 8 8 9 55 8 9 55 8 9 55 8 55 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 8 / 9 Řazení přímým výběr Select Sort / Příklad implementace void selectsort(int[] array) { for (int i = 0; i < array.length-; ++i) { int minidx = i; for (int j = i + ; j < array.length; ++j) { 5 if (array[minidx] > array[j]) { 6 minidx = j; 7 8 9 swap(minidx, i, array); 0 Zde pro jednoduchost třídíme jen celá čísla, prakticky však zpravidla třídíme klíče datových položek. Složitost O(n ), kde n je počet položek 6 8 55 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 8 / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 85 / 9

Řazení rozdělováním Quick Sort Nejvýznamnější výměny jsou ty na velké vzdálenosti. Pole rozdělíme nějakým prvkem x (pivot). Nalevo od prvku x umístíme všechny prvky menší než x. Napravo od prvku x umístíme všechny prvky větší než x. Rozdělení opakujeme pro pole tvořené prvky nalevo od x a pro pole napravo od x. Postup opakujeme dokud nerozdělujeme jednoprvkové úseky. Strategie rozděl a panuj. Tuto strategii můžeme implementovat rekurzí Rozdělení pole Příklad - rozdělení 5 8 55 8 9 5 8 55 8 9 5 8 8 55 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 86 / 9 Řazení rozdělením Quick Sort / void qsortpart(int l, int h, int[] array) { int i = l; //lower index int j = h; //higher index int pivot = array[l + (h - l) / ]; 5 while (i <= j) { 6 while(array[i] < pivot) { 7 i++; 8 9 while(array[j] > pivot) { 0 j--; if (i <= j) { swap(i++, j--, array); 5 6 if (l < j) { 7 qsortpart(l, j, array); 8 9 if (i < h) { 0 qsortpart(i, h, array); Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 88 / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 87 / 9 Řazení rozdělením Quick Sort / void quicksort(int[] array) { qsortpart(0, array.length-, array); Složitost pro nejnepříznivější případ je O(n ) Vhodně zvolený pivot výrazně snižuje časovou náročnost Randomizovaná varianta (vstupní pole permutováno a pivot je volen náhodně) O(nlog n) Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 89 / 9

Řazení Select Sort vs Quick Sort Příklad spuštění Select Sort vs Quick Sort javac DemoSort.java && java DemoSort 0 Values: 0 7 0 5 6 Values Select Sort: 5 0 7 0 6 Values Quick Sort: 5 0 7 0 6 java DemoSort 0000 Select Sort required time 5 ms Quick Sort required time 0 ms lec06/demosort.java Jednoduchý test výpočetní náročnosti můžeme udělat porovnáním výpočetních časů Např. využitím System.currentTimeMillis Skutečné výpočetní nároky se mohou lišit podle vstupních dat Zkuste zjistit počet operací pro vstupní pole setříděné sestupně Asymptotická složitost udává očekávané výpočetní nároky pro velké vstupy Reálné testování v tzv. mikro benchmarks může být zvláště v Javě zavádějící (HotSpot) Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 90 / 9 Diskutovaná témata Zápis algoritmu Quick Sort Implementace Quick Sort v programovacím jazyku Haskell qsort [] = [] qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs) Pro zajímavost Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 9 / 9 Diskutovaná témata Diskutovaná témata Shrnutí přednášky Rekurze a rekurzivní algoritmy Příklady rekurzivních algoritmů: Výpočet faktoriálu Výpis posloupnosti čísel Hanojské věže Fibonacciho posloupnost Reprezentace množiny polem Příklad implementace v algoritmu Eratosthenovo síto Rozklad na prvočinitele Příklad rekurze v řazení Příště: Objektově orientované programování v Javě Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 9 / 9 Jan Faigl, 0 A0B6PR Přednáška 6: Rekurze 9 / 9