Rekurze.

Slides:



Advertisements
Podobné prezentace
Grafové algoritmy.
Advertisements

Standardní knihovní funkce pro práci s textovými řetězci
Stavový prostor. • Existují úlohy, pro které není k dispozici univerzální algoritmus řešení • různé hry • problém batohu, problém obchodního cestujícího.
Programování v C jazyku - SEMINÁŘ
Funkce Připomeňme si program pro výpočet faktoriálu:
Programovací jazyk C++
Cvičení Úloha 1: Rozhodněte zda posloupnost znaků v poli délky n tvoří palindrom (slovo, které je stejné při čtení zprava i zleva). Př.: [a,l,e,l,a] [a,n,n,a]
ALGO – Algoritmizace 1. cvičení
Algoritmy I Cvičení č. 5.
Algoritmy I Cvičení č. 2. Cíl hodiny Datové typy a přetypování (int, float, double, bool, char, long, short) Konstanty – Celočíselné Desítkové – 15, 0,
Alg51 Rozklad problému na podproblémy Postupný návrh programu rozkladem problému na podproblémy –zadaný problém rozložíme na podproblémy –pro řešení podproblémů.
Algoritmy I Cvičení č. 4.
Algoritmy I Cvičení č. 3.
Medians and Order Statistics Nechť A je množina obsahující n různých prvků: Definice: Statistika i-tého řádu je i-tý nejmenší prvek, tj., minimum = statistika.
J a v a Začínáme programovat Lucie Žoltá Přetěžování metod, rekurze.
J a v a Začínáme programovat Lucie Žoltá metody, objekty, konstruktor.
Vývojové diagramy a základy algoritmizace
Algoritmy a datové struktury
Algoritmizace a programování
Řadicí algoritmy autor: Tadeáš Berkman.
Procedury a funkce Základní charakteristika a použití v programu.
TI 7.1 NEJKRATŠÍ CESTY Nejkratší cesty - kap. 6. TI 7.2 Nejkratší cesty z jednoho uzlu Seznámíme se s následujícími pojmy: w-vzdálenost (vzdálenost na.
Algoritmizace a základy programování
Algoritmy vyhledávání a řazení
6. cvičení Polymorfismus
Algoritmizace a programování Třídící algoritmy - 12
ALGORITMIZACE A ZÁKLADY PROGRAMOVÁNÍ
Počítače a programování 1
Informatika I 7. přednáška RNDr. Jiří Dvořák, CSc.
Informatika I 8. přednáška RNDr. Jiří Dvořák, CSc.
Příklady v jazyku C – část 3
Sorty Bubble, Insert a Quick
7. Typ soubor Souborem dat běžně rozumíme uspořádanou množinu dat, uloženou mimo operační paměť počítače (na disku). Pascalský soubor je abstrakcí skutečného.
1 / 9X36DSA 2005The complexity of different algorithms varies: O(n), Ω(n 2 ), Θ(n·log 2 (n)), … Různé algoritmy mají různou složitost: O(n), Ω(n 2 ), Θ(n·log.
Rozklad problému na podproblémy, rekurze
KIV/PRO Cvičení Nejkratší cesta Vstup – N měst – Mezi některými dvojicemi měst vedou obousměrné silnice, zadány délky cest Výstup – Nejkratší.
Grafický zápis algoritmů (vývojové diagramy) Eratosthenovo síto
C – jak na procedury Mgr. Lenka Švancarová. C – procedury #include int main() { printf("Ahoj\n"); return(0); } #include void pozdrav(void) { printf("Ahoj\n");
C – procedury Mgr. Lenka Švancarová.
Sylabus V rámci PNV budeme řešit konkrétní úlohy a to z následujících oblastí: Nelineární úlohy Řešení nelineárních rovnic Numerická integrace Lineární.
C – if Mgr. Lenka Švancarová. if vývojový diagram Podmínka Příkaz(y) Podmínka Příkaz(y) Úplné větveníNeúplné větvení ++--
Vícerozměrná pole (1) Jazyk C povoluje, aby pole mělo více rozměrů (dimenzí) než jeden Z vícerozměrných polí bývá nejčastěji použí-váno pole dvourozměrné.
Rekurze. volání podprogramu opětovně v jeho těle –v době, kdy předchozí volání ještě nebylo ukončeno Druhy rekurze přímá rekurze nepřímá rekurze.
ALGORITMIZACE A ZÁKLADY PROGRAMOVÁNÍ
Funkce Přednáška č. 5. Funkce (functions)  posloupnost příkazů uvedená hlavičkou  využití – opakovaně volaná sekvence – strukturování programu – ošetření.
Hledání silně souvislý komponent Silně souvislá komponenta orientovaného grafu G= (V,E) je maximální množina uzlů UV taková že ∀ u,v ∈ V : u je dosažitelné.
Úvod do programování 10. hodina RNDr. Jan Lánský, Ph.D. Katedra informatiky a matematiky Fakulta ekonomických studií Vysoká škola finanční a správní 2015.
Algoritmy vyhledávání a řazení Zatím nad lineární datovou strukturou (polem) …
Programování OPERÁTOR SIZEOF, FUNKCE, POLE JAKO PARAMETRY FUNKCÍ ERIK KRÁL.
NEJKRATŠÍ CESTY Nejkratší cesty - kap. 6.
Úvod do programování 11. hodina
Vícerozměrná pole (1) Jazyk C povoluje, aby pole mělo více rozměrů (dimenzí) než jeden Z vícerozměrných polí bývá nejčastěji použí-váno pole dvourozměrné.
Rekurze.
Programovací jazyk C++
C# konzole – Podíl dvou čísel, podmínka IF
ZAL – 3. cvičení 2016.
NÁZEV ŠKOLY: Základní škola Strančice, okres Praha-východ
NÁZEV ŠKOLY: Základní škola Strančice, okres Praha-východ
Úvod do programování 11. hodina
Oblast platnosti identifikátoru (1)
Podprogramy.
ALG 07 Selection sort (Select sort) Insertion sort (Insert sort)
Různé algoritmy mají různou složitost
Algoritmizace a datové struktury (14ASD)
Algoritmizace Dynamické programování
Opakování ze 4. cvičení int a; printf("Zadej číslo: ");
Funkce s proměnným počtem parametrů
Algoritmizace a datové struktury (14ASD)
Algoritmizace a datové struktury (14ASD)
Algoritmizace a datové struktury (14ASD)
Transkript prezentace:

Rekurze

Rekurze volání podprogramu opětovně v jeho těle Druhy rekurze v době, kdy předchozí volání ještě nebylo ukončeno Druhy rekurze přímá rekurze nepřímá rekurze

Přímá rekurze podprogram volá sám sebe void A(…) { A(); }

Nepřímá rekurze aktivují se vzájemně dva podprogramy void A(…) { B(); } void B(…) A();

pravidla tvorby rekurzivní funkce musí být definována podmínka pro ukončení rekurze v algoritmu se musí ověřit, zda nenastala koncová situace v každém kroku musí dojít ke zjednodušení problému

Napište rekurzivní funkci pro výpočet faktoriálu Příklad 1 Napište rekurzivní funkci pro výpočet faktoriálu long fakt(int n) { if (n<=1) return 1; else return n*fakt(n-1); }

Jak se rekurze volá? int main() { fakt(2); } fakt(2) return 2*fakt(1)

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 2584 a 4589 Zásobník n 3

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 2584 a 4589 Zásobník x 12346786 11 n 3

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 2584 a 4589 Zásobník x 12346786 11 n 3

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 2584 a 4589 Zásobník n 2 x 12346786 11 n 3

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 2584 a 4589 Zásobník 5 n 2 x 12346786 11 n 3

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 2584 a 4589 Zásobník x 123464545 5 n 2 x 12346786 11 n 3

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 2584 a 4589 Zásobník x 123464545 5 n 2 x 12346786 11 n 3

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 2584 a 4589 Zásobník n 1 x 123464545 5 n 2 x 12346786 11 n 3

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 2584 a 4589 Zásobník x 123664545 5 n 1 x 123464545 5 n 2 x 12346786 11 n 3

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 2584 a 4589 Zásobník x 123664545 5 n 1 x 123464545 5 n 2 x 12346786 11 n 3

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 1 a 4589 Zásobník 5 n 1 x 123464545 5 n 2 x 12346786 11 n 3

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 1 a 4589 Zásobník n 1 x 1 5 n 2 x 12346786 11 n 3

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 1 a 4589 Zásobník x 1 5 n 2 x 12346786 11 n 3

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 2584 a 4589 Zásobník x 2 5 n 2 x 12346786 11 n 3

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 2 a 4589 Zásobník 5 n 2 x 12346786 11 n 3

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 2 a 4589 Zásobník n 2 x 2 11 n 3

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 2 a 4589 Zásobník x 2 11 n 3

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 2 a 4589 Zásobník x 6 11 n 3

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 6 a 4589 Zásobník 11 n 3

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 6 a 6 Zásobník n 3

V registru procesoru AX se předává návratová hodnota long fakt(int n) { long x; 1: if (n<=1) 2: return 1; 3: else { 4: x=fakt(n-1); 5: x = n*x; 6: return x; } int main() {long a; 10: a = fakt(3); 11: cout << a; } AX: 6 a 6 Zásobník

Úloha 1 Napište rekurzivní funkci pro výpočet Fibbonaciho posloupnosti F(n) = F(n-1) + F(n-2)

rekurze, je-li příliš „hluboká“, způsobí růst velikosti zásobníku v některých případech je možné ji nahradit pouhým cyklem jindy se musí simulovat zásobník long fakt(int n) { long faktorial = 1; for(i=2;i<=n;i=i+1) faktorial = faktorial*i; return faktorial; }

Úloha 2 Je dána celá částka v Kč. Máme k dispozici mince v hodnotách 20 Kč, 10 Kč, 5 Kč, 2Kč, 1 Kč. Napište rekurzivní proceduru, která vytiskne na obrazovku složení částky z co nejmenšího počtu mincí (vytiskne seznam mincí). Domácí úloha: Odstraňte rekurzi (přepište proceduru pomocí cyklu).

Hanojské věže máme 3 tyče (1, 2, 3) na první tyči je věž z n disků naskládaných na sebe, spodní disk má největší průměr úkol: přemístit věž z tyče 1 na tyč 2 pomocí třetí tyče 3 přesouváním disků za podmínek: v jediném kroku lze přenést jeden disk z tyče na tyč disk lze odložit pouze na tyč nelze položit disk o větším průměru na disk s menším průměrem.

odkud = tyč 1 kam = tyč 2 pomocí = tyč 3

void Prenes_disk(int odkud, int kam), triviální úloha přenesení věže o výšce 1, tj. přenesení disku, z tyče na tyč je reprezentována procedurou void Prenes_disk(int odkud, int kam), která v našem programu vypíše informaci o přesunu disku, např.: 1 -> 2 úvaha chci-li přesunout věž např. o výšce 3 disky z tyče 1 na tyč 2 pomocí tyče 3, musím nejprve přesunout věž o výšce 2 (počítáno od shora) na tyč 3 pomocí 2, pak přesunout spodní největší disk z tyče 1 na tyč 2 a nakonec přesunout věž o výšce 2 z tyče 3 na tyč 2 pomocí tyče 1

void prenes_vez(int vyska, int odkud, int kam, int pomoci) { if (vyska == 1) prenes_disk(odkud,kam); else prenes_vez(vyska-1, odkud, pomoci, kam); prenes_disk(odkud,kam); prenes_vez(vyska-1,pomoci,kam,odkud); }

Jaká je složitost algoritmu? přesunutí věže o n discích se skládá z přesunutí věže o (n-1) discích, přesunutí disku a přesunutí věže zpět o (n-1) discích počet kroků algoritmu (počet přesunutí disků) je dán rekurentním vztahem: F(n) = F(n-1) + 1 + F(n-1) = 2F(n-1)+1, přičemž F(1) = 1

tj. počet přesunů disku u věže výšky n je roven 2n - 1 řešením rovnice je vztah F(n) = 2n - 1 tj. počet přesunů disku u věže výšky n je roven 2n - 1 složitost algoritmu je tedy O(2n) exponenciální

Aplikace rekurze Prohledávání s návratem (Backtracking) používá se pro hledání všech řešení daného problému princip: řešení hledám po krocích, pokud je řešení nalezeno nebo nelze úlohu dále řešit, vrátím se o krok zpět úlohy: hledání všech cest v bludišti problém rozmístění 8 dam na šachovnici

Problém 8 dam na šachovnici úkol: umístit 8 dam na šachovnici 8x8 polí, aby se vzájemně neohrožovaly princip: umístím dámu na první řádek na první sloupec, další dámu na druhý řádek na třetí sloupec atd., pokud nemohu další dámu umístit, provedu návrat na předchozí řádek a dámu posunu

Problém 8 dam demonstrace na 4 dámách na šachovnici 4x4

Problém 8 dam

Problém 8 dam další dámu nemohu umístit, provedu návrat

Problém 8 dam

Problém 8 dam

Problém 8 dam další dámu nemohu umístit, provedu návrat

Problém 8 dam

Problém 8 dam

Problém 8 dam

Problém 8 dam

Problém 8 dam

Problém 8 dam

Rozděl a panuj (Divide and Conquer) používá se pro zjednodušení řešení složitého problému princip: rozdělím prostor řešení na dva menší (pokud možno stejně velké) podprostory vyřeším problém na každém podprostoru samostatně (stejnou technikou) spojím obě řešení úlohy: Hanojské věže řazení: QuickSort

Hledání cest v bludišti  

algoritmus s návratem (rekurzivní) je-li to možné, v každé místnosti zkusím „jít na všechny“ světové strany do další místnosti pokud jsem našel východ, vypíši cestu a vrátím se o krok zpět vracím se o krok zpět, nemohu-li postoupit do další mísnosti (jsem v slepé uličče)

Jak bude principiálně algoritmus vypadat? Napišme jej v pseudokódu. Připomeňme si pravidla tvorby rekurzivní procedury: podmínka ukončení rekurze nalezení východu nebo slepá ulička zjednodušení problému v dalším kroku postoupil jsem do další místnosti (nalezená cesta je o 1 krok delší)

jdi_do_mistnosti(kam) { if (jsem_venku) { tiskni_cestu(); return; } else if (mohu_na_sever) jdi_do_mistnosti(sever); if (mohu_na_jih) jdi_do_mistnosti(jih); if (mohu_na_vychod) jdi_do_mistnosti(vychod); if (mohu_na_zapad) jdi_do_mistnosti(zapad); }

Data + Algorithms = Programs Donald Knuth Data + Algorithms = Programs Rozmyslíme si datové struktury a algoritmy nad nimi !

Co lze řešit rekurzí (prohledávání s návratem) Kostka domina je tvořena dvěma poli. Každé z nich může být prázdné nebo může obsahovat jistý počet teček od 1 do 6. Kostky se skládají do řady tak, že vedle sebe stojící kostky musí sousedit stejnými poli; za kostkou s prázdným polem nelze dát další kostku. Vstupem vašeho programu bude soubor se seznamem kostek domina, které máte k dispozici (na každém řádku bude dvojice čísel oddělená mezerou, představující počet teček). V seznamu se může opakovat i více stejných kostek. Zjistěte jakou nejdelší řadu lze z těchto kostek sestavit. Vytiskněte tuto řadu a její délku měřenou počtem kostek. Stačí jedno řešení.