25
1 Jan Hnilica Počítačové modelování 15 Prohledávání do šířky a do hloubky

Prohledávání do šířky a do hloubky - ih.cas.cz · 2. krok 3. krok 4. krok 5. krok 6. krok 7. krok 8. krok 9. krok jsme u cíle po 9 krocích prohledaná oblast Královská procházka

  • Upload
    vodien

  • View
    223

  • Download
    0

Embed Size (px)

Citation preview

1 Jan Hnilica Počítačové modelování 15

Prohledávání do šířky a do hloubky

Úkol • postupně systematicky prohledat vymezený stavový prostor

Stavový prostor (SP) • možné stavy a varianty vývoje nějakého procesu (výpočetního, výrobního, herního...)

• co může být stavovým prostorem?

· varianty vývoje na šachovnici (hledáme cestu k vítězství)

· bludiště (hledáme cestu ven)

· silniční síť (hledáme cestu z A do B) ... a mnoho dalších příkladů

Co můžeme hledat? • nejrychlejší řešení (nejdříve dostupné)

• optimální řešení

• všechna řešení

• alespoň jedno řešení (jakékoliv)

Prohledávání do hloubky nebo do šířky • oba algoritmy vedou k úplnému prohledání SP, liší se ale pořadím navštívených míst

• v praxi mezi nimi volíme podle cíle, kterého má být dosaženo (viz dále)

Jan Hnilica Počítačové modelování 15 2

Prohledávací algoritmy

• SP si můžeme představit jako strom (a také se tak v programu často realizuje)

• kořen stromu = úvodní stav

· např. výchozí poloha v bludišti

• synové uzlu U = stavy, do kterých se lze dostat z U pomocí nějakého elementárního kroku

· elementární krok = např. postup v bludišti na další rozcestí

• listy = konec cesty

· východ z bludiště nebo slepá ulička

Jan Hnilica Počítačové modelování 15 3

Stavový prostor jako strom

A

E

B D

I J F

K H C G

I

D A B

F

L J E

C

G H

K L

Jan Hnilica Počítačové modelování 15 4

Průchod stromem do hloubky a do šířky

• cílem je postupně prohledat všechny uzly stromu • k dočasnému skladování uzlů použijeme datovou strukturu DS (viz dále) • algoritmus:

1. vlož do DS kořen stromu 2. cyklus: dokud DS není prázdná 2a. vyjmi z DS uzel U // uzel U je navštívený 2b. vlož do DS všechny syny uzlu U // např. zprava doleva

použitá datová struktura DS je:

• zásobník ⇒ průchod do hloubky uzly navštíveny v pořadí: A, B, D, E, C, F, G

• fronta ⇒ průchod do šířky (po vrstvách) uzly navštíveny v pořadí: A, B, C, D, E, F, G

A

D

B

E

C

F G

• = backtracking, DFS (depth first search)

Algoritmus • postupně prohledáváme jednu větev po druhé, postupujeme do hloubky směrem k listům

• pokud na dané cestě nenajdeme řešení, vracíme se zpět na místo předchozího větvení a vydáme se jinou cestou

Realizace • rekurzivní funkce nebo cyklus s vlastním zásobníkem

Paměťová složitost • odpovídá výšce stromu (na zásobníku udržujeme pouze aktuálně prohledávanou cestu)

• ⇒ obvykle dobře zvládnutelné

Časová složitost • odpovídá počtu uzlů ve stromu, které musíme navštívit

• ⇒ exponenciálně roste s výškou stromu

• ⇒ časově extrémně náročné, použitelné pro malé úlohy

Jan Hnilica Počítačové modelování 15 5

Prohledávání do hloubky

• pro zmírnění časových nároků se používají prořezávání a heuristiky

Prořezávání • při každém kroku hlouběji k listům zkoušíme průběžně vyhodnotit, jestli daná cesta

může vést k nalezení řešení

• pokud můžeme určit, že cesta vede do slepé uličky, ihned se vracíme a neztrácíme čas jejím rozvíjením („odřízneme“ celý podstrom)

• ne vždy je prořezávání možné, ale pokud ano, dokáže zásadním způsobem snížit časové nároky algoritmu

Heuristiky • použitelné, pokud hledáme jedno řešení (jakékoliv)

• princip: přednostně procházíme ty větve, kde tušíme existenci blízkého řešení

• heuristika = intuitivní odhad, jakou cestou se vydat (kde by se řešení mohlo nalézat)

• dobrá heuristika ⇒ výrazné zrychlení, projdeme pouze malou část stromu

• špatná heuristika ⇒ nic se neděje, o řešení nepřijdeme (heuristika pouze mění pořadí, ve kterém jsou podstromy procházeny)

Příklady prořezávání a heuristik viz dále...

Jan Hnilica Počítačové modelování 15 6

Prohledávání do hloubky

Luštění Sudoku • tabulka 9 × 9, uvnitř dále rozdělená na 9 bloků 3 × 3 • vyplňujeme čísly 1 – 9, zadání je částečně předvyplněno • omezení: v žádném sloupci, řádku ani bloku se žádné číslo nesmí opakovat

Základní řešení (hromotlucké) • rekurzivní algoritmus, do každého volného políčka postupně zkoušíme čísla 1 – 9 • po vyplnění celé tabulky vždy otestujeme, zda jsme našli řešení

(tzn. zda jsme vytvořili korektní sudoku podle daných omezení)

Časová složitost • 81 políček, na každém hodnoty 1 – 9

• celkem 981 variant ⇒ nelze prohledat v rozumném čase!!!

Urychlení pomocí prořezávání • po vyplnění každého políčka ihned otestujeme, zda jsme neporušili pravidla

⇒ test sloupce, řádku a bloku • pokud ano, nemá smysl větev rozvíjet dál ⇒ ihned návrat o patro výš • ušetříme mnoho zbytečné práce, výrazné zrychlení

Jan Hnilica Počítačové modelování 15 7

Prohledávání do hloubky

Koňská procházka • na šachovnici stojí samotný kůň, cílem je nalézt takovou posloupnost tahů, při které kůň

postupně proskáče celou šachovnici a na žádné pole přitom neskočí dvakrát

Algoritmus

• z každé pozice postupně zkoušíme provést všechny tahy, které vedou na dosud nenavštívená pole, čímž vznikají nové pozice, které rekurzivně rozvíjíme stejným postupem

• z dané pozice

· jsou možné další tahy ⇒ rekurzivní rozvoj

· nejsou možné další tahy ⇒ slepá ulička, návrat o patro výš

· vždy samozřejmě kontrolujeme, zda jsme nedosáhli řešení

Urychlení pomocí heuristiky

• přednostně provádíme ty tahy, které vedou do omezených pozic (tzn. do pozic s menším počtem možných pokračování)

• velmi výrazné zrychlení výpočtu (pokud hledáme jedno řešení)

Jan Hnilica Počítačové modelování 15 8

Prohledávání do hloubky

Koňská procházka

Realizace (jedna z možností)

• šachovnice = 2D pole int [8][8], hodnota políčka = pořadí kroku, kterým jsme na něj přišli

• rekurzivní funkce, pracující nad jediným polem v paměti (š. předávaná jako parametr)

• úvod: všechna políčka šachovnice mají hodnotu 0, startovní pozice má hodnotu 1

• rozvoj z pozice P na pozici P´ (další tah):

· zapsat na P´ číslo o jedničku vyšší než má P

· rekurzivní rozvoj pozice P´

· návrat z rozvoje P´:

· ve větvi bylo nalezeno řešení ⇒ návrat zpět (oznámit čekajícím funkcím nahoře)

· řešení nalezeno nebylo ⇒ vrátit na P´ hodnotu 0 a pokračovat rozvojem jiného tahu

• informace o nalezeném řešení:

· např. proměnná typu int, předávaná mezi funkcemi odkazem

· nebo návratová hodnota samotné rekurzivní funkce

Jan Hnilica Počítačové modelování 15 9

Prohledávání do hloubky

Koňská procházka

• jedno z možných řešení (start vlevo nahoře)

Jan Hnilica Počítačové modelování 15 10

Prohledávání do hloubky

a b c d e f g h

8 1 4 57 20 41 6 43 22 8

7 34 19 2 5 58 21 40 7 7

6 3 56 35 60 37 42 23 44 6

5 18 33 48 53 46 59 8 39 5

4 49 14 55 36 61 38 45 24 4

3 32 17 52 47 54 27 62 9 3

2 13 50 15 30 11 64 25 28 2

1 16 31 12 51 26 29 10 63 1

a b c d e f g h

• = algoritmus vlny, BFS (breadth first search)

Algoritmus • současně rozvíjíme všechny varianty pokračování řešené úlohy

• strom výpočtu procházíme do šířky po vrstvách

Realizace • uzly určené k dalšímu zpracování odkládáme do fronty

• informace o zpracovávaných uzlech lze také zakódovat do reprezentace stavového prostoru (např. šachovnice = 2D pole, políčka obsahují informaci, zda byla už navštívena, popř. v kolikátém kroku)

Paměťová složitost • ve frontě uložena celá vrstva, šířka vrstvy s hloubkou exponenciálně roste

⇒pro větší hloubky výpočtu paměťově nerealizovatelné

Časová složitost • = obecně všechny uzly stromu (jako u backtrackingu)

• ⇒ algoritmus používáme, pokud chceme nalézt nejrychleji dostupné řešení (BFS vždy jako první najde toto řešení)

Jan Hnilica Počítačové modelování 15 11

Prohledávání do šířky

Královská procházka • král stojí na šachovnici na startovním poli S, jeho úkolem je dostat se na cílové pole C

• omezení: na některých polích jsou překážky, na tato pole král nesmí vstoupit

• cílem je zjistit nejmenší možný počet kroků z S na C, případně vypsat cestu

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

Prohledávání do šířky

start

cíl

překážka

Algoritmus

• okolo výchozí pozice najdeme a označíme všechna pole, na které král může vstoupit

• všechny označené pozice souběžně rozvíjíme, tzn. pro každou z nich najdeme všechny dosud nenavštívené sousedy, na které je možné vstoupit a označíme je pro rozvoj v dalším kroku

• kolem výchozí pozice se v jednotlivých krocích rozlévá „vlna“, která postupně dojde na cílové pole (nebo nedojde, pokud je král překážkami odříznut od cíle)

Jan Hnilica Počítačové modelování 15 13

Prohledávání do šířky

start

cíl

překážka

1. krok

čelo vlny

2. krok 3. krok

4. krok 5. krok 6. krok

9. krok jsme u cíle po 9 krocích 7. krok 8. krok

prohledaná oblast

Královská procházka

Královská procházka

Technická realizace

• šachovnice opět nejlépe jako 2D pole int hodnota políčka = pořadí kroku, kterým se na něj dá dostat

• uložení aktuálně rozvíjených pozic

• lineární seznam

• nebo v každém kroku projít celou šachovnici a nalézt pole s příslušnou hodnotou (nemusíme udržovat lineární seznam, ale přístup k rozvíjeným pozicím je pomalejší)

Výpis konkrétní cesty

• vyžaduje zpětný chod od cílové pozice ke startu

• v každém kroku postupujeme na pole s hodnotou o jedničku menší (takových polí může být víc, teoreticky je jedno, které zvolíme)

Jan Hnilica Počítačové modelování 15 14

Prohledávání do šířky

Přelévání vody

• máme n nádob o definovaných objemech, první je plná, ostatní prázdné

• cíl: pomocí přelévání vody mezi nádobami dosáhnout požadovaných obsahů vody v jednotlivých nádobách

• omezení: nádoby nemají žádné rysky, takže jediné povolené operace, při kterých udržíme informaci o obsahu vody v nádobách jsou:

• úplné vylití nádoby do jiné nádoby

• úplné naplnění nádoby obsahem (nebo částí obsahu) jiné nádoby

• úkol: napsat program, který pro zadané objemy nádob vypíše nejkratší posloupnost přelití, kterou se lze dostat do cílového stavu

Jan Hnilica Počítačové modelování 15 15

Prohledávání do šířky

10 0 0

10 7 2

5 5 0 úvodní stav:

objemy nádob:

cílový stav:

Přelévání vody

Řešení

• v každém kroku současně rozvíjíme všechny stavy vzniklé v předchozím kroku až do nalezení cílového stavu (nebo do zjištění, že nové stavy už vznikat nemůžou ⇒ úlohu nelze splnit)

Realizace stavového prostoru

• n-rozměrné pole (souřadnice reprezentují aktuální obsahy), prvky pole obsahují pořadí kroku, případně další informace (ze kterého stavu se sem dojde na nejmenší počet kroků...)

• obecný strom stavů uzly obsahují aktuální obsahy, pointery na syny, případně pointer na otce

• při rozvoji je dobré dát pozor na duplicitní rozvoj stejných stavů (z A se lze dostat jedním přelitím na B ⇒ z B se lze dostat zpětným přelitím na A)

Vypsání posloupnosti přelití po nalezení cílového stavu

• zpětný chod stavovým prostorem

• zpětný chod stromem od listu ke kořeni (⇒ tady se bude hodit ten pointer na otce)

Jan Hnilica Počítačové modelování 15 16

Prohledávání do šířky

Přelévání vody

• řešení úlohy

Jan Hnilica Počítačové modelování 15 17

Prohledávání do šířky

10 0 0

10 7 2

3 7 0

3 5 2 5 5 0

• záleží na zadané úloze

Prohledávání do hloubky

• vhodné, pokud je úkolem nalézt

• všechna řešení

• optimální řešení

• ⇒ nutné prohledat celý strom, což trvá u obou algoritmů stejně dlouho, ale prohledávání do hloubky spotřebuje výrazně méně paměti

• nebo pokud hledáme libovolné řešení, které je ale ve stromu daleko od kořene (stejný důvod)

Prohledávání do šířky

• při úkolu nalézt nejrychleji dostupné řešení

• pokud ve velkém stavovém prostoru existuje řešení blízko kořene

Jan Hnilica Počítačové modelování 15 18

Kdy použít který algoritmus

• algoritmus, který umí "inteligentně" hrát např. piškvorky, dámu, šachy...

• obecně hry pro dva hráče, ve kterých jsou veškeré informace viditelné na hrací ploše (ne tedy např. karetní hry)

Hra

• dva hráči (černý a bílý) se pravidelně střídají v tazích

• algoritmus hraje např. v pozici bílého protihráč = člověk (nebo jiný algoritmus)

• cílem algoritmu je vždy v aktuální herní situaci vybrat nejlepší tah

Jan Hnilica Počítačové modelování 15 19

Minimax

z partie Garry Kasparov vs Deep Blue

Strom hry

• uzel = stav na šachovnici (kořen je výchozí stav)

• synové uzlu = možné tahy (vznikají nové stavy)

• bílé uzly ... na tahu je bílý černé uzly ... na tahu je černý

• list = konec hry (výhra jednoho z hráčů nebo remíza)

Jan Hnilica Počítačové modelování 15 20

Minimax

Velikost stromu hry

• obvykle velká hloubka stromu - hry končí až po desítkách tahů

• obvykle velký stupen větvení - uzly mívají desítky synů (počet možných tahů z daného stavu)

⇒ kompletní strom hry bývá velmi rozsáhlý

Hodnota stavu na šachovnici • = číslo, vyjadřující např. aktuální herní materiál hráčů, bonusy za výhodné pozice atd.

• vysoká hodnota ⇒ výhodná pro bílého nízká hodnota ⇒ výhodná pro černého

Princip algoritmu • generuje se strom hry pro daný (omezený) počet tahů dopředu

• nejdříve se ohodnotí listy stromu

• uzly ve vyšších patrech získávají hodnotu postupně při průchodu stromem zdola nahoru

• uzel vždy získá hodnotu toho syna, kterého si daný hráč vybere jako svůj nejlepší tah

bílý maximalizuje ⇒ z možných tahů vybírá ten s nejvyšší hodnotou

černý minimalizuje ⇒ z možných tahů vybírá ten s nejnižší hodnotou

• v kořeni nakonec bílý vybírá tah s nejvyšší hodnotou

Technická realizace • strom hry nelze celý vygenerovat a uložit do paměti (ani u malých her)

⇒ strom se zároveň tvoří a prochází do hloubky, při návratu se uzly ve spodních patrech mažou

• hodnota v uzlu se průběžně upravuje při návratu z jeho podstromu

(v bílém uzlu - pokud se zespoda vrátí hodnota vyšší než prozatím dosažená, v černém naopak)

Jan Hnilica Počítačové modelování 15 21

Minimax

Jan Hnilica Počítačové modelování 15 22

Minimax

1 4

4 1 9 6

4 6 3 2 9 2 1

4

nejdříve ohodnotíme listy .........

vybíráme maximum ......................

vybíráme minimum ................................

vybíráme maximum ............................................ (provede se levý tah)

(demonstrace do hloubky 3 tahů)

Jan Hnilica Počítačové modelování 15 23

Minimax

int Minimax(sachovnice * S, int hloubka, int hrac) { // jsme v listu => vracíme hodnotu na šachovnici if (hloubka == 0) return Hodnota(S); // vygenerujeme tahy z aktuální pozice tah tahy[] = VygenerujTahy(S); int hodnota; int nejHodnota = -hrac * ∞; // postupně vyzkoušíme všechny tahy a zjistíme jejich cenu for (int i = 0; i < pocetTahu; i++) { ZahrajTah(S, tahy[i]); hodnota = Minimax(S, hloubka – 1, -hrac); ZahrajTahZpet(S, tahy[i]); if (hrac == 1) if (hodnota > nejHodnota) nejHodnota = hodnota; if (hrac == -1) if (hodnota < nejHodnota) nejHodnota = hodnota; } // úklid a návrat do vyšších pater SmazTahy(tahy); return nejHodnota; }

(nárys funkce)

Jan Hnilica Počítačové modelování 15 24

Minimax

Složitost minimaxu • paměť = výška stromu (není problém)

• čas = počet uzlů stromu hry, exponenciálně roste s hloubkou ⇒ nutno velmi omezit hloubku prohledávání

Možnosti prořezávání • subjektivní prořezávání (ztrátové)

· po několika tazích zhodnotit stav na šachovnici, pozice, které se jeví jako málo nadějné dál nerozvíjíme

· problém: hodnocení je subjektivní, pouze odhadujeme, jak by se stav mohl rozvinout ⇒ můžeme odmítnout cesty vedoucí nakonec k vítězství

• alfa-beta prořezávání (bez ztráty informace)

· algoritmus doplníme o dva parametry:

· alfa = maximum, které má ve vyšších patrech k dispozici maximalizující hráč

· beta = minimum, které má ve vyšších patrech k dispozici minimalizující hráč

· příklad použití: na tahu je bílý a zjistí, že některý jeho tah má hodnotu > beta ⇒ okamžitý návrat proč? zkoumáním dalších tahů by mohl hodnotu svého uzlu jen zvětšit, ale minimalizující hráč má někde nahoře k dispozici menší hodnotu, tuto větev si tedy stejně nevybere, tzn. nemá cenu pokračovat

Jan Hnilica Počítačové modelování 15 25

Minimax

1 4

4 1 6

4 6 2 1

4

(demonstrace alfa - beta prořezávání)

hodnota > beta

hodnota < alfa