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.
Orbis pictus 21. století Tato prezentace byla vytvořena v rámci projektu.
Programování v C jazyku - SEMINÁŘ
Programovací jazyk C++
Přednáška 11 Jiří Šebesta
1 Vnitřní řazení s využitím dynamických struktur Tvorba spojového seznamu je vcelku triviální záležitostí: a)Vytvořím prázdný seznam příkazem LIST:=nil.
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í č. 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.
Datové struktury. 2 Co je datová struktura v C datový typ složený z jiných datových typů nejjednodušší datová struktura je pole. všechny jeho prvky jsou.
Algoritmizace a programování
Řadicí algoritmy autor: Tadeáš Berkman.
Informatika I 2. přednáška
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.
Algoritmy vyhledávání a řazení
Současný svět Projekt č. CZ /3. 1
6. cvičení Polymorfismus
Algoritmizace a programování Třídící algoritmy - 12
Další abstraktní datové typy
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.
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) Test na trojúhelník (trojúhelníková nerovnost) Maximum ze tří čísel s použitím pomocné proměnné Pravoúhlý.
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");
Vazby dynamických proměnných,databázové systémy Přednáška č. 10.
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í.
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.
Typ struktura (1) Datový typ struktura (struct) je agrego-vaný heterogenní datový typ Jedná se o skupinu několika proměnných, které mohou mít různé datové.
Ú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é.
Programovací jazyk C++
NÁZEV ŠKOLY: Základní škola Strančice, okres Praha-východ
Rekurze.
NÁZEV ŠKOLY: Základní škola Strančice, okres Praha-východ
Úvod do programování 11. hodina
PROLOG strategie vyhodnocení dotazu
Abstraktní datové typy
Oblast platnosti identifikátoru (1)
Podprogramy.
ALG 07 Selection sort (Select sort) Insertion sort (Insert sort)
Různé algoritmy mají různou složitost
Toky v sítích.
Algoritmizace a datové struktury (14ASD)
Algoritmizace Dynamické programování
Opakování ze 4. cvičení int a; printf("Zadej číslo: ");
ZAL – 4. cvičení 2016.
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 !

reprezentace bludiště informace o velikosti – šířce a délce dynamické dvourozměrné pole informací o místnostech typedef struct { int sirka, delka; TMistnost **plocha; } TBludiste;

reprezentace místnosti informace o otevřenosti dveří na čtyři světové strany typedef enum { ZAVRENO=0,OTEVRENO=1} TStavDveri; typedef struct { TStavDveri sever; TStavDveri jih; atd; } TMistnost;

kam budu ukládat místnosti z nalezené cesty nevím předem, jak bude cesta dlouhá mám algoritmus s návratem, tj. při postupu do jiné místnosti potřebuji přidávat na konec cesty novou mísnost, při návratu ji z konce odebrat nejlepší bude obousměrný spojový seznam prevence proti cyklu booleovké pole místností, které jsem navštívil mohu doplnit o přímý test, abych nešel na tu světovou stranu v místnosti, ze které jsem přišel

hlavička rekurzivní procedury void jdi_do_mistnosti(TBLudiste *bludiste, TSvetStrany kam_jdu, int x, int y, TCesta *cesta);

x1 <= x2 <= x3 <=…<= x(K-1) <=xK a Úloha Vstupem programu jsou čísla N a K. Nalezněte všechny K-tice celých kladných čísel x1,x2,x3, … x(K-1), xK, pro které platí x1 <= x2 <= x3 <=…<= x(K-1) <=xK a x1 + x2 + x3 +…..+ x(K-1) + xK = N.

Úloha 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í.