Rekurze. IB111 Základy programování Radek Pelánek

Podobné dokumenty
Rekurze. IB111 Úvod do programování

Rekurze. IB111 Úvod do programování skrze Python

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

IB111 Úvod do programování skrze Python

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

Kombinatorika, výpočty

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

IB111 Úvod do programování skrze Python

Rekurze a rychlé třídění

Programy a algoritmy pracující s čísly. IB111 Úvod do programování

Rekurzivní algoritmy

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

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

Programy a algoritmy pracující s čísly. IB111 Úvod do programování skrze Python

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

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

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

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

Programování v Pythonu

Rekurze. Jan Hnilica Počítačové modelování 12

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

Programy a algoritmy pracující s čísly. IB111 Úvod do programování skrze Python

IB111 Úvod do programování 1 / 62

Metody návrhu algoritmů, příklady. IB111 Programování a algoritmizace

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

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

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

IB111 Základy programování Radek Pelánek 1 / 61

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

Rozklad problému na podproblémy

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

Programování: základní konstrukce. IB111 Úvod do programování

Stromy, haldy, prioritní fronty

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

(a kryptografické odbočky) IB111 Úvod do programování skrze Python

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

(a kryptografické odbočky) IB111 Úvod do programování skrze Python

Algoritmy a datové struktury

Programy a algoritmy pracující s čísly

Úvod do teorie grafů

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

Úvod do programování 10. hodina

Dynamické programování

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.

Programování: základní konstrukce

Úvod do informatiky. Miroslav Kolařík

Práce s daty. IB111 Základy programování Radek Pelánek

VISUAL BASIC. Práce se soubory

Hanojská věž. T2: prohledávání stavového prostoru. zadání [1 1 1] řešení [3 3 3] dva možné první tahy: [1 1 2] [1 1 3]

Prioritní fronta, halda

Funkce, podmíněný příkaz if-else, příkaz cyklu for

Techniky návrhu algoritmů

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

Přednáška 3. Rekurze 1

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

Základy algoritmizace 4. Problémy, algoritmy, data

Programovací jazyk Haskell

Programovací í jazyk Haskell

Implementace LL(1) překladů

Dynamické programování

Vysvětlete funkci a popište parametry jednotlivých komponent počítače a periferních zařízení.

Rozklad problému na podproblémy, rekurze

Obecná informatika. Matematicko-fyzikální fakulta Univerzity Karlovy v Praze. Podzim 2012

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

5. Dynamické programování

Struktura programu v době běhu

Rozklad problému na podproblémy, rekurze

Vyučovací hodina. 1vyučovací hodina: 2vyučovací hodiny: Opakování z minulé hodiny. Procvičení nové látky

Martin Flusser. November 1, 2016

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

Časová a prostorová složitost algoritmů

10. Složitost a výkon

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

Logo2 operace, rekurze, větvení výpočtu

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

Dekompozice problému, rekurze

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

2 Strukturované datové typy Pole Záznam Množina... 4

VYŠŠÍ ODBORNÁ ŠKOLA a STŘEDNÍ PRŮMYSLOVÁ ŠKOLA Mariánská 1100, Varnsdorf PROGRAMOVÁNÍ FUNKCE, REKURZE, CYKLY

Konečný automat. Jan Kybic.

Basic256 - úvod do programování Příklady. ing. petr polách

Úvod do Matlabu. Praha & EU: Investujeme do vaší budoucnosti. 1 / 24 Úvod do Matlabu

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

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

R zné algoritmy mají r znou složitost

Lokální definice (1) plocha-kruhu

Optimalizace & soft omezení: algoritmy

Zadání semestrálního projektu Algoritmy I. zimní semestr 2018/2019

součet cvičení celkem. známka. Úloha č.: max. bodů: skut. bodů:

Návrh Designu: Radek Mařík

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

Datové struktury 2: Rozptylovací tabulky

ALGORITMY A DATOVÉ STRUKTURY

Vstupní požadavky, doporučení a metodické pokyny

Programovací jazyk Pascal

Pascal. Katedra aplikované kybernetiky. Ing. Miroslav Vavroušek. Verze 7

PROGRAMOVÁNÍ V JAZYCE C V PŘÍKLADECH 11 Dynamické datové struktury 11.1 Spojové struktury Příklad PROG_

SPJA, cvičení 1. ipython, python, skripty. základy syntaxe: základní datové typy, řetězce. podmínky: if-elif-else, vyhodnocení logických výrazů

Řídicí struktury. alg3 1

IB111 Základy programování Radek Pelánek

Transkript:

Rekurze IB111 Základy programování Radek Pelánek 2018 1 / 72

xkcd: Tabletop Roleplaying https://xkcd.com/244/ 2 / 72

To iterate is human, to recurse divine. (L. Peter Deutsch) 3 / 72

Rekurze použití funkce při její vlastní definici volání sebe sama (s jinými parametry) 4 / 72

Sebereference https://xkcd.com/688/ 5 / 72

Sebereferenční test 1 Které písmeno není správnou odpovědí na žádnou otázku: (A) A (B) C (C) B 2 Odpověd na 3. otázku je: (A) stejná jako na 1. otázku (B) stejná jako na 2. otázku (C) jiná než odpovědi na 1. a 2. otázku 3 První otázka, na kterou je odpověd A, je otázka: (A) 1 (B) 2 (C) 3 Hlavolamikon 6 / 72

Piráti 5 pirátů si děĺı poklad: 100 mincí nejstarší pirát navrhne rozdělení, následuje hlasování alespoň polovina hlasů rozděleno, hotovo jinak navrhující pirát zabit, pokračuje druhý nejstarší (a tak dále) (rekurze!) priority 1 přežít 2 mít co nejvíce mincí 3 zabít co nejvíc ostatních pirátů složitější varianty: 6 pirátů a 1 mince, 300 pirátů a 100 mincí 7 / 72

Rekurze a sebereference Rekurze a sebereference kĺıčové myšlenky v informatice některé souvislosti: matematická indukce funkcionální programování rekurzivní datové struktury (např. stromy) gramatiky logika, neúplnost nerozhodnutelnost, diagonalizace 8 / 72

Rekurze a sebereference... nejen v informatice M. C. Escher; Drawing Hands, 1948 Gödel, Escher, Bach: An Eternal Golden Braid; Douglas Hofstadter 9 / 72

Rekurze a úvodní programování uvedené aplikace rekurze a sebereference často poměrně náročné hodí se pořádně pochopit rekurzi na úrovni jednoduchých programů bezprostřední návaznost Algoritmy a datové struktury 10 / 72

Faktoriál f (n) = n! = 1 2 (n 1) n { 1 pokud n = 1 n f (n 1) pokud n > 1 11 / 72

Faktoriál iterativně (pomocí cyklu) def fact(n): f = 1 for i in range(1, n+1): f = f * i return f 12 / 72

Faktoriál rekurzivně def fact(n): if n == 1: return 1 else: return n * fact(n-1) 13 / 72

Faktoriál rekurzivně ilustrace výpočtu fact(4) 24 4 * fact(3) 6 3 * fact(2) 2 2 * fact(1) 1 1 14 / 72

Příklad: výpis čísel Vymyslete funkci, která: vypíše čísla od 1 do N pomocí rekurze bez použití cyklů for, while 15 / 72

Příklad: výpis čísel Vymyslete funkci, která: vypíše čísla od 1 do N pomocí rekurze bez použití cyklů for, while def sequence(n): if n > 1: sequence(n-1) print(n) 16 / 72

Co udělá tento program? def test(n): print(n) if n > 1: test(n-1) print(-n) test(5) 17 / 72

Ilustrace zanořování test(3) 3 test(2) 2 test(1) 1-1 -2-3 18 / 72

Nepřímá rekurze def even(n): print("even", n) odd(n-1) def odd(n): print("odd", n) if n > 1: even(n-1) even(10) 19 / 72

Rekurzivní stromeček 20 / 72

Rekurzivní stromeček nakreslit stromeček znamená: udělat stonek nakreslit dva menší stromečky (pootočené) vrátit se na původní pozici 21 / 72

Stromeček želví grafikou def tree(length): forward(length) if length > 10: left(45) tree(0.6 * length) right(90) tree(0.6 * length) left(45) back(length) 22 / 72

Podoby rekurze, odstranění rekurze koncová rekurze (tail recursion) rekurzivní volání je poslední příkaz funkce lze vesměs přímočaře nahradit cyklem plná rekurze zanořující se volání např. stromeček lze přepsat bez použití rekurze za použití zásobníku rekurzivní podoba často výrazně elegantnější 23 / 72

Hanojské věže aneb O konci světa video: https://www.fi.muni.cz/~xpelanek/ib111/hanojske_veze/ https://www.youtube.com/watch?v=8yaoed8jc8y klášter kdesi vysoko v horách u města Hanoj velká místnost se třemi vyznačenými místy 64 různě velkých zlatých disků podle věštby mají mniši přesouvat disky z prvního na třetí místo a až to dokončí... 24 / 72

Hanojské věže: pravidla N disků různých velikostí naskládaných na sobě vždy může být jen menší disk položen na větším možnost přesunout jeden horní disk na jiný koĺıček cíl: přesunout vše z prvního na třetí 25 / 72

Hanojské věže: řešení A B C A B C A B C A B C A B C A B C A B C A B C 26 / 72

Hanojské věže: výstup programu >>> solve(3, "A", "B", "C") A -> B A -> C B -> C A -> B C -> A C -> B A -> B 27 / 72

Hanojské věže: rekurzivní řešení def solve(n, start, end, auxiliary): if n == 1: print(start, "->", end) else: solve(n-1, start, auxiliary, end) solve(1, start, end, auxiliary) solve(n-1, auxiliary, end, start) 28 / 72

Řešení včetně vypisování stavu * *** ***** ------------------- *** ***** * ------------------- ***** *** * ------------------- * ***** *** ------------------- * *** ***** ------------------- * *** ***** ------------------- 29 / 72

Stav úlohy, reprezentace stav úlohy = rozmístění disků na koĺıcích disky na koĺıku A seznam celkový stav: 3 proměnné, v každé seznam nepěkné seznam seznamů, koĺıky interně značíme 0, 1, 2 příklad stavu (6 disků): [[4], [5, 2, 1], [6, 3]] 30 / 72

Řešení včetně vypisování stavu def solve(n, start, end, aux, state): if n==1: disc = state[start].pop() state[end].append(disc) print_state(state) else: solve(n-1, start, aux, end, state) solve(1, start, end, aux, state) solve(n-1, aux, end, start, state) def solve_hanoi(n): state = [list(range(n,0,-1)), [], []] print_state(state) solve(n, 0, 2, 1, state) 31 / 72

Vypisování stavu jednoduše def print_state(state): print(state) print("--") def print_state(state): for i in range(3): print("peg", chr(ord( A )+i), state[i]) print("--") 32 / 72

Vypisování stavu textová grafika def print_state(state): n = sum([len(s) for s in state]) for y in range(n+1): line = "" for peg in range(3): for x in range(-n+1, n): if len(state[peg]) > n-y and abs(x) < state[peg][n-y]: line += "*" else: line += " " line += " " print(line) print("-"*(n*6+1)) 33 / 72

Sierpińského fraktál rekurzivně definovaný geometrický útvar 34 / 72

Sierpińského fraktál 35 / 72

Sierpińského fraktál: kód def sierpinski(n, length): if n == 1: triangle(length) else: for i in range(3): sierpinski(n - 1, length) forward((2 ** (n - 1)) * length) right(120) 36 / 72

Další podobné fraktály 37 / 72

Robotanik tutor.fi.muni.cz, úloha Robotanik jednoduché grafické programování robota těžší příklady založeny na rekurzi vizualizace průběhu výpočtu, zanořování a vynořování z rekurze 38 / 72

Robotanik Kurz počítání rekurze jako pamět 39 / 72

Robotanik 40 / 72

Pokrývání plochy L kostičkami mřížka 8 8 s chybějícím levým horním polem úkol: pokrýt zbývající poĺıčka pomocí L kostiček rozšíření: rozměr 2 n 2 n chybějící libovolné pole obarvení 3 barvami, aby sousedi byli různí 41 / 72

Ukázky řešení 42 / 72

Řešení rozdělit na čtvrtiny umístit jednu kostku rekurzivně aplikovat řešení na jednotlivé části 43 / 72

Kahoot 44 / 72

Kahoot: program A def magic(n): return n + magic(n) 45 / 72

Kahoot: program B def test(n): if n > 0: print(n, end="") test(n-1) print(n, end="") test(3) 46 / 72

Přemýšlení o funkcích (rekurzivních obzvlášt ) obecně pro funkce: ujasnit vstupně-výstupní chování než začnu psát funkci rekurzivní funkce navíc: při psaní funkce předpokládám, že mám již funkci hotovou problém převedu na řešení menšího problému (který již umím vyřešit) ošetřím koncovou podmínku 47 / 72

Otočení řetězce rekurzivně >>> reverse("star wars") sraw rats 48 / 72

Otočení řetězce rekurzivně >>> reverse("star wars") sraw rats def reverse(s): if len(s) <= 1: return s return reverse(s[1:]) + s[0] 48 / 72

Kontrolní otázka Co dělá následující funkce (vstup je řetězec)? def magic(s): if len(s) <= 1: return s return magic(s[1:]) 49 / 72

Seznam vnořených seznamů Seznam čísel a vnořených seznamů čísel (SČAVSČ) je seznam, který obsahuje čísla nebo SČAVSČ. rekurzivní datová struktura scavsc = [[2, 8], 4, [3, [1, 7], 6], [2, 4]] Jak vypočítat součet všech čísel? 50 / 72

Součet vnořených seznamů def nested_list_sum(alist): total = 0 for x in alist: if isinstance(x, list): total += nested_list_sum(x) else: total += x return total 51 / 72

Příklady použití rekurze v informatice Euclidův algoritmus NSD vyhledávání opakovaným půlením řadicí algoritmy (quicksort, mergesort) generování permutací, kombinací fraktály prohledávání grafu do hloubky gramatiky 52 / 72

Euklidův algoritmus rekurzivně def nsd(a,b): if b == 0: return a else: return nsd(b, a % b) 53 / 72

Vyhledávání opakovaným půlením hra na 20 otázek hledání v seznamu hledání v binárním stromu 54 / 72

Vyhledávání: rekurzivní varianta def binary_search(value, alist, lower, upper): if lower > upper: return False mid = (lower + upper) // 2 if alist[mid] < value: return binary_search(value, alist, mid+1, upper) elif alist[mid] > value: return binary_search(value, alist, lower, mid-1) return True 55 / 72

Řadicí algoritmy quicksort vyber pivota rozděl na menší a větší zavolej quicksort na podčásti mergesort rozděl na polovinu každou polovinu seřad pomocí mergesort spoj obě poloviny 56 / 72

Generování permutací, kombinací permutace množiny = všechna možná pořadí příklad: permutace množiny {1, 2, 3, 4} jak je vypsat systematicky? jak využít rekurzi? k-prvkové kombinace n-prvkové množiny = všechny možné výběry k prvků příklad: 3-prvkové kombinace množiny {A, B, C, D, E} jak je vypsat systematicky? jak využít rekurzi? 57 / 72

Kombinace ( ) n = k ( ) n 1 + k 1 ( ) n 1 k def combinations(alist, k): if k == 0: return [[]] if len(alist) < k: return [] output = [] for comb in combinations(alist[1:], k-1): comb.append(alist[0]) output.append(comb) output.extend(combinations(alist[1:], k)) return output 58 / 72

Nevhodné použití rekurze ne každé použití rekurze je efektivní Fibonacciho posloupnost (kráĺıci): f 1 = 1 f 2 = 1 f n = f n 1 + f n 2 1, 1, 2, 3, 5, 8, 13, 21, 34,... Vi Hart: Doodling in Math: Spirals, Fibonacci, and Being a Plant 59 / 72

Fibonacciho posloupnost: rekurzivně def fib(n): if n <= 2: return 1 else: return fib(n-1) + fib(n-2) 60 / 72

Fibonacciho posloupnost: rekurzivní výpočet fib(5) fib(3) + fib(4) fib(1) + fib(2) fib(2) + fib(3) 1 1 1 fib(1) + fib(2) 1 1 61 / 72

Problém N dam šachovnice N N rozestavit N dam tak, aby se vzájemně neohrožovaly zkuste pro N = 4 pozn. speciální případ problému splnění podmínek 62 / 72

Problém N dam řešení 63 / 72

Problém N dam algoritmus ilustrace algoritmu backtracking hrubá síla, ale chytře začneme s prázdným plánem, systematicky zkoušíme umist ovat dámy pokud najdeme kolizi, vracíme se a zkoušíme jinou možnost přirozený rekurzivní zápis 64 / 72

Problém N dam backtracking řešení 65 / 72

Problém N dam reprezentace stavu pro každé pole si pamatujeme, zda na něm je/není dáma dvourozměrný seznam True/False pro každou dámu si pamatujeme její souřadnice seznam dvojic x i, y i pro každý řádek si pamatujeme, v kterém sloupci je dáma seznam čísel x i nejvýhodnější reprezentace 66 / 72

Problém N dam řešení def solve_queens(n, state): if len(state) == n: output(state) return True else: for i in range(n): state.append(i) if check_queens(state): if solve_queens(n, state): return True state.pop() return False 67 / 72

Kdy se ohrožují dvě dámy? y 1 x 1 x 2 y 2 68 / 72

Kdy se ohrožují dvě dámy? x 1 x 2 y 1 y 2 x 1 = x 2 y 1 = y 2 x 1 + y 1 = x 2 + y 2 x 1 y 1 = x 2 y 2 69 / 72

Problém N dam řešení def output(state): for y in range(len(state)): for x in range(len(state)): if state[y]==x: print("x", end=" ") else: print(".", end=" ") print() print() def check_queens(state): for y1 in range(len(state)): x1 = state[y1] for y2 in range(y1+1, len(state)): x2 = state[y2] if x1 == x2 or x1-y1 == x2-y2 or\ x1+y1 == x2+y2: return False 70 / 72

Backtracking další příklady použití mnoho logických úloh: Sudoku a podobné úlohy algebrogramy (SEND + MORE = MONEY) optimalizační problémy (např. rozvrhování, plánování) obecný problém splnění podmínek 71 / 72

Shrnutí rekurze: využití rekurze pro definici sebe sama logické úlohy: Hanojské věže, L kostičky, dámy na šachovnici fraktály aplikace v programování: vyhledávání, řazení, prohledávání grafu kĺıčová myšlenka v informatice nezapomeňte na piráty 72 / 72