Stáhnout prezentaci
Prezentace se nahrává, počkejte prosím
1
Rekurze
2
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
3
Přímá rekurze podprogram volá sám sebe void A(…) { A(); }
4
Nepřímá rekurze aktivují se vzájemně dva podprogramy void A(…) { B();
} void B(…) A();
5
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
6
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); }
7
Jak se rekurze volá? int main() { fakt(2); } fakt(2) return 2*fakt(1)
8
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
9
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 11 n 3
10
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 11 n 3
11
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 11 n 3
12
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 11 n 3
13
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 5 n 2 x 11 n 3
14
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 5 n 2 x 11 n 3
15
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 5 n 2 x 11 n 3
16
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 5 n 1 x 5 n 2 x 11 n 3
17
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 5 n 1 x 5 n 2 x 11 n 3
18
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 5 n 2 x 11 n 3
19
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 11 n 3
20
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 11 n 3
21
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 11 n 3
22
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 11 n 3
23
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
24
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
25
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
26
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
27
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
28
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
29
Úloha 1 Napište rekurzivní funkci pro výpočet Fibbonaciho posloupnosti
F(n) = F(n-1) + F(n-2)
30
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; }
31
Ú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).
32
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.
34
odkud = tyč 1 kam = tyč 2 pomocí = tyč 3
35
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
36
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); }
37
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) F(n-1) = 2F(n-1)+1, přičemž F(1) = 1
38
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í
39
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
40
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
41
Problém 8 dam demonstrace na 4 dámách na šachovnici 4x4
42
Problém 8 dam
43
Problém 8 dam další dámu nemohu umístit, provedu návrat
44
Problém 8 dam
45
Problém 8 dam
46
Problém 8 dam další dámu nemohu umístit, provedu návrat
47
Problém 8 dam
48
Problém 8 dam
49
Problém 8 dam
50
Problém 8 dam
51
Problém 8 dam
52
Problém 8 dam
53
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
54
Hledání cest v bludišti
55
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)
56
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ší)
57
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); }
58
Data + Algorithms = Programs
Donald Knuth Data + Algorithms = Programs Rozmyslíme si datové struktury a algoritmy nad nimi !
59
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í.
Podobné prezentace
© 2024 SlidePlayer.cz Inc.
All rights reserved.