Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Úvod do programování 12. hodina

Podobné prezentace


Prezentace na téma: "Úvod do programování 12. hodina"— Transkript prezentace:

1 Úvod do programování 12. hodina
RNDr. Jan Lánský, Ph.D. Katedra informatiky a matematiky Fakulta ekonomických studií Vysoká škola finanční a správní 2015

2 Úvod do programování 12. hodina
Umíme z minulé hodiny Zásobník Create, Push, Pop, Top, IsEmpty Fronta Create, Enqueue, Dequeue, Front, IsEmpty Cyklická fronta, fronta s posunem, prioritní fronta Backtracking - úvod N-ciferná čísla (variace s opakováním) doplnění znamének Jan Lánský Úvod do programování 12. hodina

3 Úvod do programování 12. hodina
Cíle hodiny Backtracking Problém N dam Normální magické čtverce Jezdcova procházka Ořezávání Heuristiky Vlna Cesta koněm po šachovnici Jan Lánský Úvod do programování 12. hodina

4 Problém N dam 8 dam: Max Bezzel 1848 N dam: Franz Nauck 1850 Rozmístit N dam na šachovnici N x N, tak aby se neohrožovaly. Žádné dvě dámy nesmějí být ve stejném řádku nebo ve stejném sloupci nebo ve stejné úhlopříčce. Nejznámější varianta 8 dam na šachovnici 8x8 má 92 řešení. Najdeme všechna řešení backtrackingem 12 základních, zbytek symetrická Jan Lánský Úvod do programování 12. hodina

5 Problém 8 dam Šachová terminologie: Šachovnice má 64 hracích polí. Aby se nám "hrací pole" nepletlo s polem jako datovou strukturou, budeme používat "políčko" D Jedno z možných řešení problému Pro dvě vybrané dámy je znázorněno jaká políčka ohrožují. Jan Lánský Úvod do programování 12. hodina

6 Problém N dam algoritmus
Obvykle se nepoužívá pole pro pamatování hrozeb, ale hrozby se kontrolují na místě. Moje řešení mě přijde pochopitelnější. Na každém řádku musí být 1 dáma. Postupně vyzkoušíme všechna umístění 1. dámy na 1. řádku a pro ně rekurzivně umístíme 2. dámu na 2. řádek Pro každé políčko šachovnice si pamatujeme, kolika dříve umístěnými dámami je ohrožováno. Na ohrožené políčko nebudeme dámu umisťovat. Pokud nelze na daném řádku umísit žádnou dámu, vracíme se z rekurze. Při návratu z rekurze musíme upravit počet ohrožení pro políčka, která byla ohrožována dámou, jejíž umístění vracíme. Pokud jsme umístili všech N dam, vypíšeme výsledek. Jan Lánský Úvod do programování 12. hodina

7 Výpis šachovnice Dáma = true, volno = false
Šachovnice 0 až (N – 1) x 0 až (N – 1). V levém horním rohu je políčko s indexem [0,0] Dáma D, prázdné políčko tečka Jan Lánský Úvod do programování 12. hodina

8 Příprava na rekurzi Rekurze začíná na řádku 0
Dvojrozměrné pole hrozby: hodnota prvků udává počet dam, která se nacházejí na nižších řádcích a ohrožují políčko reprezentované daným prvkem Vracíme počet řešení Nesledujeme hrozby dam z vyšších řádků. Tyto dámy budou odstraněny při návratu z rekurze, dříve než budeme s prvkem pracovat U hrozeb musíme znát jejich počet, nestačí bool (kvůli návratu z rekurze) Jan Lánský Úvod do programování 12. hodina

9 Dvojrozměrné pole hrozby
1 2 3 4 5 6 7 První řádek musí být nulový z definice (není žádná dáma na nižším řádku Červená políčka – je na nich umístěna dáma Prvek [4,6] má hodnotu 1. Ohrožuje ho jen jedna dáma z nižšího řádku [3, 5]. Dámy [4,2], [5,6] a [7,3] jsou na vyšších řádcích. Jan Lánský Úvod do programování 12. hodina

10 N dam bylo umístěno, vypíšeme řešení. Počítáme počet řešeni – return 1
Pokusíme se umístit dámu do každého sloupce, vynecháme ohrožované sloupce Řádky i, sloupce j Nastavíme hrozby od dámy, kterou budeme umísťovat. 1. umístíme dámu 2. rekurze pro další řádek 3. odebereme dámu Odebereme hrozby po odebrané dámě Při návratu z rekurze jsme sčítali počty řešení Jan Lánský Úvod do programování 12. hodina

11 Hrozby Hrozby nastavujeme jen na řádky, které následují po aktuálním řádku Proto podmínka cyklu i+radek < Length(1) Proto první index pole i + radek sloupce Diagonály doprava a doleva Testy, zda jsme ještě na šachovnici 0 až N - 1 D j-i j j+i Indexy sloupce Jan Lánský Úvod do programování 12. hodina

12 Úvod do programování 12. hodina
Klasické řešení Učebnicové řešení Nepoužívá pole hrozby, ale pro políčko kam chceme umístit dámu provede kontrolu zda není ohrožováno nějakou dámou umístěnou ve sloupci nebo diagonálách nad políčkem Pro 8 dam 1,5 x pomalejší, pro 13 dam 3x pomalejší Jan Lánský Úvod do programování 12. hodina

13 Klasické řešení Nepotřebujeme pole hrozby
N dam bylo umístěno, vypíšeme řešení. Počítáme počet řešeni – return 1 Pokusíme se umístit dámu do každého sloupce Ohrožení testuje funkce Umístíme dámu; rekurze pro další řádek; odebereme dámu Jan Lánský Úvod do programování 12. hodina

14 Ohrožení sloupce Levá diagonála Pravá diagonála
Cyklus o dvou řídících proměnných pro průchod diagonálami: Řídící proměnné i a j. V inicializaci a inkrementu je oddělíme příkazy pro jednotlivé řídící proměnné operátorem čárky. V podmínce testujeme konjunkci podmínek pro jednotlivé řídící proměnné. Není moc obvyklé řešení, lze rozepsat while cyklem … Jan Lánský Úvod do programování 12. hodina

15 Normální magické čtverce
Čína, 650 př. n. l. Normální magický čtverec N x N obsahuje čísla 1 až N umístěna tak, že všechny řádky i sloupce i obě diagonály mají shodný součet hodnot čísel v nich umístěných. Součet čísel 1 až N2 je N2 (N2+1)/2 Součet hodnot čísel v řádku / sloupci N(N2+1)/2 N = 3, S = 15; N = 4, S = 34; N = 5, S = 65 Podobný princip sudoku Pro N = 2 nejde Jan Lánský Úvod do programování 12. hodina

16 Normální magický čtverec 4x4
Součet každé řádky, každého sloupce i každé úhlopříčky je 34 34 1 15 14 4 12 6 7 9 8 10 11 5 13 3 2 16 Jan Lánský Úvod do programování 12. hodina

17 Normální magické čtverce: Algoritmus
Ořezávání: nepokračujeme, když daná větev nemůže vést k řešení Backtracking: Budeme postupně plnit čísly 1. řádek (od 1. sloupce po poslední), 2. řádek … Budeme průběžně uchovávat součet hodnot v plněném řádku, když překročíme stanovenou hodnotu, vracíme se. Budeme průběžně uchovávat součet hodnot ve všech sloupcích a obou diagonálách. Když přidáním prvku překročíme stanovenou hodnotu, vracíme se. Některá řešení lze najít i bez backtrackingu Jan Lánský Úvod do programování 12. hodina

18 Úvod do programování 12. hodina
Ořezávání Backtracking obvykle exponenciální časová složitost. Jakékoliv vylepšení se hodí Pokud při backtrackingu zjistíme, že v danou chvíli nelze kandidáta na řešení žádným způsobem rozšířit na řešení, ukončíme větev rekurze. Čím dříve takového kandidáta ořízneme, tím lépe. Příklady N-ciferná čísla: pokračovali jsme v rekurzi jen pro povolené cifry (ostatní jsme ořízli) N-dam: pokračovali jsme v rekurzi jen pro neohrožená políčka Magické čtverce: pokud řádek nesplňoval požadovaný součet, končili jsme Jan Lánský Úvod do programování 12. hodina

19 Heuristiky Odhadneme, které prodloužení kandidáta má největší šanci na úspěch a zpracujeme ho přednostně. Obecně určíme pořadí, ve kterém budeme jednotlivá prodloužení kandidáta zpracovávat. Pokud se spleteme, zpomalíme se jen o čas odhadu nejlepšího prodloužení. Řešení najdeme (mírně) později než bez použití heuristiky. Pokud chceme rychle najít jedno řešení a nezajímají nás všechna řešení. Při hledání všech řešení nemají smysl. Zatím jsme heuristiky nepoužívali, hledali jsme všechna řešení Bude: jezdcova procházka V cyklu jsme postupně prošli všechna možná prodloužení Jan Lánský Úvod do programování 12. hodina

20 Kombinace heuristiky a prořezávání
Chceme nalézt nejlepší řešení úlohy podle zadaného kritéria Pomocí heuristiky najdeme rychle nějaké řešení Pomocí ořezávání ukončujeme ty kandidáty na řešení, které jsou v zadaném kritériu horší. Příklad: Hledání nejkratší cesty mezi městy. Pokud kandidát na cestu má větší délku než nejlepší již nalezená cesta, ukončíme ho. Jan Lánský Úvod do programování 12. hodina

21 Úvod do programování 12. hodina
Jezdcova procházka Zadána startovní pozice jezdce na šachovnici NxN. Cílem je navštívit každé políčko šachovnice právě jednou Varianta zakončit cestu na políčku sousedícím se startovním (nebudeme řešit) Šachovnice 8x8 Backtracking do úrovně 64 Počet řešení Budeme hledat pouze jedno Řešení: Backtracking Jan Lánský Úvod do programování 12. hodina

22 Pohyb jezdce 1 2 3 4 5 6 7 J 8 Jezdec se pohybuje do "L".
1 2 3 4 5 6 7 J 8 Jezdec se pohybuje do "L". Dva tahy v jednom směru (řádek, sloupec) a jeden tah v druhém směru. Tah 1: [-1, -2] Tah 2: [-1, +2] Tah 3: [+1, -2] Tah 4: [+1, +2] Tah 5: [-2, -1] Tah 6: [-2, +1] Tah 7: [+2, -1] Tah 8: [+2, +1] Jan Lánský Úvod do programování 12. hodina

23 Jezdcova procházka Barva políček od bílé po červenou, jak se blížíme cíli Na šachovnici jsou čísla tahů [2,3][1,1][0,3][1,5] [0,7][2,6][0,5][1,7] [3,6][5,7][7,6][6,4] [7,2][6,0][4,1][2,0] [0,1][1,3][2,1][0,0] [1,2][0,4][1,6][2,4] [3,2][4,0][6,1][7,3] [6,5][7,7][5,6][3,7] [4,5][5,3][7,4][6,6] [4,7][3,5][2,7][0,6] [1,4][0,2][1,0][2,2] [3,0][5,1][7,0][6,2] [4,3][3,1][5,0][7,1] [5,2][4,4][2,5][3,3] [5,4][4,2][3,4][4,6] [6,7][5,5][6,3][7,5]; 1 2 3 4 5 6 7 20 17 42 22 40 43 21 18 41 23 8 16 19 44 24 55 39 45 50 25 56 59 38 9 32 26 15 58 49 54 33 60 37 51 46 53 34 57 62 31 10 14 27 48 63 12 29 36 61 47 52 13 28 35 64 11 30 Jan Lánský Úvod do programování 12. hodina

24 Příprava na rekurzi Struktura tah na uchování pozice řádku a sloupce
Šachovnice obsahuje čísla tahů, kterými jsme na dané políčko vstoupili Nastavíme startovní pozici (= 1.tah) a rekurzi pouštíme pro druhý tah Jan Lánský Úvod do programování 12. hodina

25 Rekurze Celé pole je projité, vypíšeme tah do souboru
Funkce, která vrátí pole možných tahů. V proměnné vrátí navíc počet tahů. Bude jich obvykle méně než je délka pole. 1) Nastavíme tah 2) Pustíme pro něj rekurzi (n+1) 3) Zrušíme tah. Zda jsme nalezli řešení, bude ukončovat rekurzi, viz podmínka cyklu Jan Lánský Úvod do programování 12. hodina

26 Výpis tahu Časová sloužitost N^4, kde N je hrana šachovnice. Pro každé pořadí tahu najdeme políčko, které bylo daným tahem obsazeno. Nutno při tom projít šachovnici. Pokud by tento postup byl pomalý, jde tahy ukládat na zásobník v průběhu hledání. Tahy vypíšeme do souboru, pro každý tah vypisujeme [řádek, sloupec] Jan Lánský Úvod do programování 12. hodina

27 Další tahy Maximálně 8 možných tahů, na krajích šachovnice méně. Ke konci hry bude hodně políček obsazených 3 vnořené cykly 1) Absolutní hodnota pohybu v řádku (sloupec se dopočítá) 2) Znaménko pohybu v řádku 3) Znaménko pohybu v sloupci V cyklech inkrementuje řídící proměnnou o 2 Kontrola, zda řádek tahu není mimo šachovnici Kontrola, zda sloupec tahu není mimo šachovnici Kontrola, zda políčko není obsazené Jan Lánský Úvod do programování 12. hodina

28 Další tahy – alternativní řešení
Učebnicové, ale o 50 % pomalejší Všech 8 možných tahů uložíme do pole jako relativní posuny od zadané pozice Cyklus přes všech 8 tahů Ke skutečné pozici přičteme relativní posun Testy zda je tah není mimo šachovnici a zda pole není obsazené Jan Lánský Úvod do programování 12. hodina

29 Úvod do programování 12. hodina
Heuristika H. C. von Warnsdorf, 1823 Navržené řešení je velmi pomalé N = 6 cca 3s, N = 8 ??? Heuristika Upřednostňovat tahy, které vedou na políčka, ze kterých je nejméně možných tahů. Modifikujeme funkci DalsiTahy přeuspořádáme tahy v poli podle počtu možných tahů, které z nich vedou Z exponenciální časové složitosti se stane lineární Jan Lánský Úvod do programování 12. hodina

30 Další tahy: Heuristika I.
Přejmenována funkce Přidáno pole na uložení počtu tahů, které mohou po daném tahu následovat Zavoláme původní funkci DalsiTahy, která pro každý tah vrátí počet možných tahů Jan Lánský Úvod do programování 12. hodina

31 Další tahy: Heuristika II
Šlo by řešit prioritní frontou, ale vzhledem k charakteru dat pomalé Pole tahů musíme setřídit podle hodnot v poli pokračování. Třídíme vzestupně Insertion sortem Třídíme obě dvě pole: Tahy i pokračování, ale pro porovnání při třídění uvažujeme jen hodnoty pole pokračování Jan Lánský Úvod do programování 12. hodina

32 Algoritmus vlny Varianta: U stromů prohledávání do šířky Současně rozšiřujeme kandidáta na řešení o všechny možné kroky. Vznikne tím více kandidátu na řešení Při backtrackingu jsem rozšiřovali jednoho kandidáta na řešení o jeden vybraný krok dokud to šlo. První najité řešení bude nejkratší. Oproti Backtrackingu paměťově náročnější Využití fronty Při backtrackingu se využíval zásobník Jan Lánský Úvod do programování 12. hodina

33 Cesta jezdcem na šachovnici
Najití nejkratší cesty jezdcem na šachovnici ze zadaného startovního políčka do zadaného cílového políčka Měřeno počtem tahů Umíme najít backtrackingem, ale časově náročné (až 63 tahů místo 6) Algoritmus vlny Jan Lánský Úvod do programování 12. hodina

34 Cesta jezdcem na šachovnici
Dvojrozměrné pole šachovnice Startovní políčko označíme hodnotou 1 Políčka, kam jde táhnout ze startovní pozice označíme 2 Políčka, kam jde táhnout z políček z hodnotou n označíme n+1 Tahy budeme ukládat do fronty Konec, až cílové políčko bude mít přiřazeno číslo udávající počet tahů Rekonstrukce tahů vedoucích k cíli: Pro každé políčko pamatujeme, z jakého políčka jsme se na něj dostali Jan Lánský Úvod do programování 12. hodina

35 Cesta jezdcem na šachovnici
1 2 3 4 5 6 7 Start: zelená Cíl červená Cesta: [3,3] [1,4] [2,2] [4,3] [5,5] Jan Lánský Úvod do programování 12. hodina

36 Šachovnice s počtem tahů Šachovnice s tahy zpět
Musíme frontu upravit, aby pracovala s typem Tah Do fronty dáme startovní pozici jezdce 1. Vyzvedneme tah z fronty 2. Vygenerujeme možné tahy 3. Možné tahy vložíme do fronty 4. Na šachovnici možným tahům nastavíme délku cesty 5. Možným tahům nastavíme cestu zpět na výchozí tah. Vypíšeme jednotlivé tahy Vracíme délku cesty Jan Lánský Úvod do programování 12. hodina

37 Výpis cesty Pole cesta bude mít nevyužitý prvek s indexem nula
Cestu získáváme od cíle, pomocí tahů zpět Výpis na obrazovku od prvku s indexem 1 Jan Lánský Úvod do programování 12. hodina

38 Úvod do programování 12. hodina
Zpětná vazba Objevili jste ve slajdech chyby? Včetně pravopisných Nechápete nějaký slajd? Je příliš obtížný, nesrozumitelný? Máte nějaký nápad na vylepšení? Anonymní formulář Odeslání za pár vteřin Jan Lánský Úvod do programování 12. hodina


Stáhnout ppt "Úvod do programování 12. hodina"

Podobné prezentace


Reklamy Google