34
FAKULTET ELEKTROTEHNIKE I RAČUNARSTVA ZAVOD ZA ELEKTRONIKU, MIKROELEKTRONIKU, RAČUNALNE I INTELIGENTNE SUSTAVE SEMINARSKI RAD: HEURISTIČKE METODE PRETRAGE Predmet: Predstavljanje znanja u informacijskim sustavima Nastavnik: prof. dr. sc. Nikola Bogunović Student: Miroslav Štampar, dipl. ing. MB: R-10/2008 Datum: 01.04.2011.

Heurističke metode pretrage

Embed Size (px)

DESCRIPTION

Seminarski rad

Citation preview

Page 1: Heurističke metode pretrage

FAKULTET ELEKTROTEHNIKE I RAČUNARSTVAZAVOD ZA ELEKTRONIKU, MIKROELEKTRONIKU, RAČUNALNE I

INTELIGENTNE SUSTAVE

SEMINARSKI RAD:

HEURISTIČKE METODE PRETRAGE

Predmet: Predstavljanje znanja u informacijskim sustavimaNastavnik: prof. dr. sc. Nikola BogunovićStudent: Miroslav Štampar, dipl. ing.MB: R-10/2008Datum: 01.04.2011.

Page 2: Heurističke metode pretrage
Page 3: Heurističke metode pretrage

Sadržaj1. Uvod...................................................................................................................................1

2. Teoretski dio.......................................................................................................................2

2.1. Heurističko pretraživanje............................................................................................2

2.2. Algoritam penjanja uzbrdo..........................................................................................5

2.3. Dinamičko programiranje............................................................................................7

2.4. Algoritam najboljeg prvog...........................................................................................9

2.4.1. Pretraživanje s uniformnim troškom..................................................................10

2.4.2. Pohlepno pretraživanje......................................................................................10

2.4.3. Algoritam A*.......................................................................................................11

2.5. Upotreba heuristike u računalnim igrama.................................................................12

2.5.1. Minimax.............................................................................................................12

2.5.2. Alfa-beta rezidba...............................................................................................14

2.6. Problemi kompleksnosti............................................................................................15

3. Praktični uradak...............................................................................................................18

4. Zaključak..........................................................................................................................21

5. Literatura..........................................................................................................................22

Dodatak A: Programski kod.................................................................................................23

A.1. TSP.py......................................................................................................................23

Page 4: Heurističke metode pretrage

1.Uvod

1. Uvod

Kada se u inteligentnom sustavu zadaju problem i pripadni prostorni parametri, na njemu je da s ograničenim procesnim resursima pronađe moguća rješenja, jedno za drugim, sve dok ne pronađe jedno koje zadovoljava zadani problem definiran konačnim testom. Ukoliko inteligentni sustav ima kontrolu nad generiranjem redoslijeda mogućih rješenja, tada bi bilo poželjno da se on uredi na taj način da se sva moguća konačna rješenja sa značajnom mogućnosti pojavljivanja pojave ranije. Takav sustav predstavlja inteligenciju u onoj mjeri u kojoj uspijeva ispuniti opisani zadatak. Stoga se kaže da se inteligencija sustava u okolini s ograničenim resursima sastoji upravo od donošenja „mudrih” odluka u momentima kada je potrebno odlučiti što uraditi sljedeće.

1

Page 5: Heurističke metode pretrage

2.Teoretski dio

2. Teoretski dio

2.1. Heurističko pretraživanje

U trenutku kada je Arhimed izlazio iz kupke stišćući u rukama zlatnu krunu, uzviknuše glasno „Eureka!”, što u prijevodu znači „Pronašao sam ga!”. Vezano, heuristika (korijen iz grčke riječi „Ε ρίσκωὑ ” za „tražiti” ili „pronaći”) je opći naziv za tehnike namijenjene rješavanju problema, učenju i/ili pronalaženju. Heurističke metode se koriste kako bi se ubrzao proces pronalaženja dovoljno dobrog rješenja, u situacijama kada je kompletno pretraživanje (engl. exhaustive search) nepraktično.

Preciznije rečeno, heurističke metode su zajednički naziv za strategije u kojima se koriste lako dostupne, iako slabo primijenjene, informacije za kontrolu rješavanja problema, kako kod ljudi tako i kod strojeva.

Većina temeljnih heurističkih metoda temelji se na procesu „pokušaja i pogreške” (engl. trial and error), koja se u osnovi može upotrijebiti na svemu, od pronalaženja prikladnih dijelova za računalo do pronalaženja vrijednosti varijabli u nekom algebarskom problemu. U neke od osnovnih heurističkih metoda spadaju:

• Ukoliko imate poteškoća s razumijevanjem problema, pokušajte problem predočiti slikom

• Ukoliko ne možete pronaći rješenje, pokušajte pretpostaviti da ga već imate i vidite što možete izvući iz samog tog saznanja (rad unatrag – engl. working backward)

• Ukoliko je problem apstraktne prirode, pokušajte ga proučiti na konkretnom primjeru

• Pokušajte riješiti općenitiji problem ranije

U pretrazi prostora stanja (engl. space search), heuristika je formalizirana kao skup pravila za odabir onih ogranaka u prostoru stanja koji će najvjerojatnije dovesti do prihvatljivog rješenja problema.

Kod rješavanja problema u polju umjetne inteligencije heuristika se koristi u dvije osnovne situacije:

1. Problem ne može imati točno rješenje zbog inherentne dvosmislenosti u zadanom problemu i/ili u raspoloživim podacima. Medicinska dijagnostika je odličan primjer za ovaj slučaj, stoga što dani skup simptoma može imati nekoliko mogućih uzroka. Liječnici koriste heuristiku kako bi odabrali najvjerojatniju dijagnozu i formulirali plan daljnjeg liječenja. Vid je još jedan primjer neegzaktnog problema. Vizualne scene su često nejasne, omogućuju više interpretacija povezanosti, mjere te orijentacije objekata. Optičke iluzije su primjer takvih nejasnoća. Sustavi za računalni vid često koriste heurističke metode kako bi odabrali najvjerojatnije od nekoliko mogućih interpretacija scene.

2. Problem može imati točno rješenje, ali potrebni računalni trošak pronalaženja može biti previsok. U mnogim slučajevima (kao u primjeru šaha), rast prostor

2

Page 6: Heurističke metode pretrage

2.Teoretski dio

stanja je kombinatorički eksplozivan, s brojem mogućih stanja koji raste eksponencijalno ili faktorijalno s dubinom pretraživanja. U tim slučajevima, iscrpne tehnike sirovog pretraživanja (engl. brute-force search), poput pretraživanja po dubini ili pretraživanja po širini, možda neće uspjeti pronaći rješenje u bilo kojoj praktičnoj duljini vremena. Kod heuristike se ova kompleksnost „napada” s navođenjem pretraživanja prostora problema na put (engl. path) koji najviše obećava. Uklanjanjem bezizglednih stanja i njihovih potomaka iz razmatranja, heuristički algoritam može „poraziti” ovu kombinatoričku eksploziju i pronaći prihvatljivo rješenje u prihvatljivom vremenu.

Nažalost, kao i sva pravila otkrića i izuma, heuristike su nesavršene. Heuristika je samo informirani pogodak sljedećeg koraka koji je potrebno poduzeti u procesu rješavanja problema. No, to je često izvedivo samo uz pomoć iskustva i intuicije. Budući da heuristike koriste ograničene informacije, kao što je poznavanje sadašnjeg stanja i/ili opisa stanja koji se trenutno nalaze na otvorenoj listi, one su rijetko u mogućnosti predvidjeti točno ponašanje prostora stanja jedan korak dalje u pretrazi.

Heuristika može nerijetko dovesti algoritam za pretraživanje do suboptimalnog rješenja ili čak do nenalaženja nijednog rješenja. To je inherentno ograničenje ove vrste pretraživanja i ne može biti eliminirano „boljom” heuristikom ili efikasnijim algoritmom za pretraživanje [12].

Heuristike i dizajn algoritama namijenjenih heurističkom pretraživanju dugo su bili izvor brige u području umjetne inteligencije. Računalne igre i dokazivanje teorema predstavljaju jedan od najstarijih praktičnih primjena umjetne inteligencije, pri čemu oboje zahtijevaju heuristike za smanjivanje prostora mogućih rješenja. Ispitivanje svakog zaključka u matematičkoj domeni, kao i svakog poteza na šahovskoj ploči, jednostavno nije izvedivo (engl. feasible). Heurističko pretraživanje je često jedino praktično rješenje.

Istraživanja u polju ekspertnih sustava su potvrdila važnost heuristika kao bitnu komponentu kod rješavanja problema. Kada ljudski stručnjak rješava problem, on ili ona proučava dostupne podatke i na temelju njih donosi odluku. „Pravila palca” (engl. rules of thumb) koje ljudski stručnjak koristi za rješavanje problema su po svojoj prirodi velikim djelom heurističke. Te su heuristike izvedene i formalizirane od strane stvaraoca ekspertnih sustava.

Razmotrimo heuristiku u igri križić-kružić. Kombinatorika za iscrpno pretraživanje je zahtjevna, ali ne i nepremostiva. Svaki od devet prvih poteza ima osam mogućih odgovora, koji pak imaju sedam sljedećih poteza, itd. Jednostavna analiza daje ukupan broj stanja za iscrpno (engl. exhaustive) pretraživanje 9x8x7... ili 9!.

Smanjenje simetrije (engl. symmetry reduction) smanjuje prostor pretraživanja. Mnoge su konfiguracije problema zapravo ekvivalentne s obzirom na simetrične operacije na ploči igre. Dakle, na kraju ne postoji devet, već samo tri početna poteza: prema uglu, prema središtu strane te prema središtu mreže. Uporaba simetrije na drugom potezu dodatno smanjuje broj staza kroz prostor problema na 12x7!, kao što se može vidjeti na slici 1. Simetrije u prostoru igre poput ove mogu se opisati matematičkim invarijantnama, takvim da se (kada postoje) često mogu koristiti kao ogromnu pomoć u procesu smanjenju opsega pretraživanja.

3

Page 7: Heurističke metode pretrage

2.Teoretski dio

Međutim, jednostavna heuristika gotovo u potpunosti otklanja potrebu za pretraživanjem. Kod početka igre automatski se premještamo u stanje u kojem X ima najviše mogućnosti za pobjedu. U slučaju stanja s jednakim brojem mogućih pobjeda, uzima se prvo takvo pronađeno stanje. Algoritam zatim odabire i prelazi na sljedeće stanje s najvećim brojem mogućnosti za pobjedu. U slučaju igre križić-kružić, na početku se zauzima samo središte mreže. Na ovaj način ne samo da su ostala dva alternativna stanja (s obzirom na simetriju) otklonjena, već i svi njihovi potomci. Dvije trećine cjelokupnog prostora stanja je uklonjeno samo s ovim prvim potezom.

Nakon prvog poteza, suparnik može odabrati bilo koji od dva preostala poteza. Koji god odabere, može se primijeniti heuristika na rezultirajuće stanje u igri. Kako se pretraživanje nastavlja, svakim se potezom računaju vrijednosti za potomke samo jednog stanja, odnosno, iscrpno pretraživanje nije potrebno. Na slici 2 prikazano je smanjenje pretraživanja nakon tri koraka u igri. Stanja su obilježena pripadnim heurističkim vrijednostima. Iako ne predstavljaju egzaktne vrijednosti za pretraživanje u ovakvoj strategiji „stanja s najviše pobjeda”, gruba gornja granica može se izračunati uz pretpostavku o maksimalnom broju od pet poteza po igri s pet opcija po potezu. U stvarnosti, broj stanja se smanjuje kako se ploča popunjava i reducira broj opcija. Ova gruba granica od 25 stanja je poboljšanje od četiri reda veličine naspram originalnog broja 9!.

4

Slika 1: Prva tri nivoa prostora pretraživanja za igru križić-kružić smanjena simetrijom

Page 8: Heurističke metode pretrage

2.Teoretski dio

2.2. Algoritam penjanja uzbrdo

U računalnoj znanosti, penjanje uzbrdo (engl. hill climbing) je naziv za matematičku metodu optimizacije iz obitelji heurističkih metoda lokalnog pretraživanja. To je iterativni algoritam koji počinje s proizvoljnim rješenjem problema, a zatim u svakoj iteraciji pokušava pronaći bolje rješenje postupnim mijenjanjem jednog elementa rješenja. Ukoliko promjena rezultira boljim rješenjem, novo rješenje se uzima kao postavka za daljnju pretragu, iterativno ponavljajući cijeli postupak sve dok je moguće dobiti daljnja poboljšanja.

Na primjer, ova se metoda može primijeniti na problem trgovačkog putnika (engl. traveling salesman problem). Jednostavno se može pronaći početno rješenje u kojem se posjećuju svi gradovi, no to rješenje će vrlo vjerojatno biti dosta lošije u odnosu na optimalno. Algoritam započinje s jednim takvim rješenjem te čini malo poboljšanje nad njim, kao što je promjena reda obilaska dva grada. Na kraju će se vrlo vjerojatno dobiti puno kraći put.

Kod penjanja uzbrdo osnovna ideja je ta da se uvijek krećemo prema stanju koje je bolje od trenutnog. Dakle, ako ste u gradu A i možete se kretati prema gradovima B i C, dok je vaš krajnji cilj grad D, tada biste se morali premjestiti u grad B ili C samo ukoliko je jedan od njih bliži gradu D nego što je to trenutni grad A.

5

Slika 2: Heuristički smanjen prostor stanja za igru križić-kružić

Page 9: Heurističke metode pretrage

2.Teoretski dio

Penjanje uzbrdo je dobra metoda za pronalaženje lokalnog optimuma (dobro rješenje koje se nalazi relativno blizu početnog rješenja), no nije zajamčeno da će se pronaći najbolje moguće rješenje (globalni optimum) od svih mogućih rješenja unutar cjelokupnog prostora pretrage.

Relativna jednostavnost algoritma ga čini popularnim i prvim izborom među optimizacijskim algoritmima. Široku uporabu ima u području umjetne inteligencije, za postizanje ciljnog stanja iz početnog čvora. Iako napredniji algoritmi poput „simuliranog kaljenja” (engl. simulated annealing) ili „tabu pretraživanja” (engl. tabu search) [2] mogu dati bolje rezultate, u nekim situacijama penjanje uzbrdo radi jednako dobro. Penjanje uzbrdo često može rezultirati boljim rezultatom nego ostali algoritmi, pogotovo kada je količina raspoloživog vremena dostupnog za obavljanje pretraživanja ograničeno, kao što je to slučaj sa sustavima za rad u stvarnom vremenu (engl. real-time systems).

Penjanje uzbrdo predstavlja najjednostavniji način implementacije heurističke pretrage. Ova metoda je imenovana po strategiji koju bi mogao koristiti uporan, no slijepi penjač na planinu: „Idi uzbrdo uz najoštriji mogući uspon sve dok ne možeš nastaviti dalje prema gore”. Budući da se ne čuva povijest pretrage, ovaj algoritam se ne može oporaviti od neuspjeha vlastite strategije.

1. Uzmi kao trenutni čvor t početni čvor s

2. Uzmi čvor n iz liste svih potomaka trenutnog čvora koji ima najbolji rezultat za heurističku funkciju vrednovanja f

3. Ukoliko je f(n) < f(t) vrati kao rezultat trenutni čvor t

4. Uzmi kao trenutni čvor t čvor n

5. Skoči na korak n

Programski kod 1: Pseudokod za algoritam penjanja uzbrdo

Glavni problem kod strategija baziranih na ovoj metodi je njihova tendencija da lako zaglave u lokalnom maksimumu. Ukoliko dođu do stanja koje rezultira boljom procjenom nego bilo koje dijete (potomak), algoritam staje s radom. Ukoliko to samo stanje nije cilj, već samo lokalni maksimum, algoritam može podbaciti u pronalaženju najboljeg rješenja. To znači da se performanse zbilja mogu poboljšati u ograničenom okruženju, no zbog mogućeg izgleda cjelokupnog prostora pretrage, može se vrlo lako dogoditi da uopće ne pronađe ukupno najbolje rješenje.

Primjer lokalnog maksimuma može se pronaći u igrama na ploči. Često, kako bi se dovelo figuru do svog konačnog cilja, ostale se figure također moraju pomicati. To znači da je ponekad potrebno privremeno pogoršati stanje na ploči kako bi se riješio problem. Stoga što „bolje” nije uvijek i „najbolje” u apsolutnom smislu, metode pretrage bez memorije o prijašnjim stanjima ili nekih drugih mehanizama oporavka nisu u mogućnosti prepoznati razliku između lokalnog i globalnog maksimuma.

Kod jednostavnog penjanja uzbrdo, odabire se prvi čvor bliži rješenju, dok se kod varijacije penjanja po najstrmijem usponu (engl. steepest ascent) bira onaj čvor susjed koji je najbliži rješenju. Obje su ove metode neučinkovite ukoliko ne postoji slijedeći čvor bliži rješenju, što se može dogoditi u slučaju lokalnog maksimuma u prostoru rješenja koje samo po sebi nije rješenje. Penjanje po najstrmijem usponu je

6

Page 10: Heurističke metode pretrage

2.Teoretski dio

vrlo slično pretrazi po „prvom najboljem” (engl. best-first search) (2.4.) u kojem se ispituju svi mogući produžeci puta umjesto samo jednog.

Kod stohastičkog se penjanja uzbrdo ne vrši ispitivanje svih susjeda prije nego što se odluči prijelaz u novo stanje. Umjesto toga, odabire se susjed nasumičnom metodom i odlučuje, ovisno o procjeni poboljšanja, da li se premjestiti u njega ili da se nastavi s ispitivanjem ostalih susjeda.

„Nasumično ponovno” (engl. random restart) penjanje uzbrdo je meta-algoritam izgrađen povrh algoritma za penjanje uzbrdo. Također je poznat i kao „sačmarica” (engl. shotgun) varijacija. Kod njega se iterativno obavlja penjanje uzbrdo, svaki put s nasumičnim inicijalnim početnim stanjem x0, pri čemu se čuva najbolji xm. Ukoliko novo izvršavanje penjanja uzbrdo rezultira boljim xm od sačuvanog, tada zamjenjuje staro stanje. Ova varijacija je iznenađujuće učinkovita u mnogim slučajevima, što dovodi do zaključka da je često bolje provesti procesorsko vrijeme istražujući prostor stanja, nego pažljivo birati (optimizirati) početno stanje.

2.3. Dinamičko programiranje

U matematici i računalnoj znanosti, dinamičko programiranje je naziv za metodu rješavanja složenih problema njihovim razbijanjem na manje jednostavnije potprobleme. Primjenjuje se na probleme sa svojstvom preklapanja potproblema koji su samo nešto manji i k tome s optimalnom podstrukturom. Ovoj metodi je u praksi potrebno puno manje vremena nego kod korištenja drugih osnovnijih (engl. naive) metoda.

Ključna ideja iza dinamičkog programiranja je poprilično jednostavna. Općenito, da bi se riješio zadani problem, trebamo riješiti različite dijelove problema (potprobleme), a zatim uz pomoću dobivenog skupa rješenja doći do konačnog rješenja. Uzmemo li u obzir rekurzivni programski pristup, možemo definirati problem u smislu njegovih potproblema te ih riješiti jedan po jedan. Međutim, u određenim slučajevima su mnogi od tih potproblema zapravo isti. Dakle, rekurzivni pristup rješavanju potproblema jedan-po-jedan rezultirati će rješavanjem istog potproblema mnogo puta. Kod dinamičkog programiranja se, s druge strane, osigurava rješavanje svakog potproblema samo jednom u cjelini, čime se štedi na računanju. Ta se ušteda pokazuje kao vrlo korisna kada je broj ponavljajućih potproblema eksponencijalno velik.

Pristup „od vrha prema dnu” (engl. top-down) kod dinamičkog programiranja podrazumijeva spremanje nekih proračuna u svrhu kasnije upotrebe i to iz razloga što na trenutnom nivou završni izračun predstavlja samo potproblem većeg proračuna. Pristup „od dna prema vrhu” (engl. bottom-up) uključuje formuliranje kompleksnog računa kao rekurzivni niz jednostavnijih kalkulacija.

Pojam dinamičkog programiranja prvi je 1940ih koristio Richard Bellman kako bi opisao proces rješavanja problema gdje se moraju pronaći najbolje odluke jedna za drugom. Do 1953., preformulirao je značenje u modernijem duhu, prvenstveno naglašavanjem na ugniježđivanje manjih preciznijih problema unutar većih odluka.

7

Page 11: Heurističke metode pretrage

2.Teoretski dio

Riječ dinamičko Bellman je izabrao stoga što je zvučalo impresivnije, a ne zato što je htio opisati što metoda zapravo radi [3]. Riječ programiranje se odnosilo na korištenje ove metode kod pronalaženja optimalnog programa, u smislu vojnog rasporeda za obuku ili logistiku. Uporaba riječi u ovom slučaju je slična kao i kod fraza linearno programiranje i matematičko programiranje, sinonima za optimizaciju [4].

Dinamičko programiranje se ponekad naziva „naprijed-nazad” (engl. forward-backward), ili u slučaju upotrebe vjerojatnosti Viterbi algoritam. Osnovna svrha dinamičkog programiranja je ograničavanje memorije u pretragama problema sastavljenih od više međusobno povezanih potproblema. Kod dinamičkog programiranja čuva se zabilješka o prethodno pretraženim i riješenim podtroblemima kako bi se kasnije iskoristilo unutar rješenja većeg problema. Najbolji primjer ove metode može se pronaći u korištenju rješenja za podnizove unutar konačnog rješenja za generiranje Fibonaccijevih nizova. Tehnika spremanja potproblema za ponovnu uporabu ponekad se naziva memoriranje rješenja parcijalnog podcilja (engl. memoizing partial subgoal solutions). Rezultat je vrlo bitan algoritam često korišten kod usporedbe nizova, provjere pravopisa i srodnih polja unutar obrade prirodnog jezika (engl. natural language processing).

Problem računanja n-tog broja u Fibonaccijevom nizu predstavlja osnovni primjer za primjenu dinamičkog programiranja zbog svog bitnog svojstva preklapanja potproblema. Jednostavna rekurzivna implementacija bi bila:

def fib(n):

if n == 0: return 0

if n == 1: return 1

return fib(n-1) + fib(n-2)

Programski kod 2: Jednostavna programska implementacija za računanje Fibonaccijevog niza

Problem računanja fib(n) tako ovisi o vrijednostima fib(n-1) i fib(n-2). Kako bi se predočilo kako se ovi potproblemi preklapaju, u sljedećem primjer mogu se vidjeti koliko se puta zove funkcija fib te s kojim argumentima:

fib(5)

fib(4) + fib(3)

fib(3) + fib(2) + fib(2) + fib(1)

fib(2) + fib(1) + fib(1) + fib(0) + fib(1) + fib(0) + fib(1)

fib(1) + fib(0) + fib(1) + fib(1) + fib(0) + fib(1) + fib(0) + fib(1)

Programski kod 3: Raspisani prikaz rekurzivnog zvanja funkcije za računanje Fibonaccijevog niza

Za dobivanje rezultata fib(k) u koraku k trebamo znati samo vrijednosti za fib(k-1) i fib(k-2), no vidljivo je da se u najjednostavnijem obliku vrši izračun istih vrijednosti višestruko puta. Počinjući od dna prema vrhu možemo na učinkovitiji iterativni način izračunati vrijednost sljedećeg elementa niza te na taj način eliminirati veliki dio redundancije:

8

Page 12: Heurističke metode pretrage

2.Teoretski dio

def fib2(n):

n2, n1 = 0, 1

for i in range(n-2):

n2, n1 = n1, n1 + n2

return n2+n1

Programski kod 4: Optimizirana funkcija za računanje Fibonaccijevog niza

U O-notaciji funkciji fib potrebno je O(cn) vremena, dok je fib2 funkciji potrebno O(n) vremena za izvršenje. Rješenje ovog problema predstavlja klasičan primjer uporabe dinamičkog programiranja za rješavanje problema s preklapajućim potproblemima.

2.4. Algoritam najboljeg prvog

Pretraživanje metodom najboljeg prvog (engl. best-first search) je naziv za algoritam u kojem se graf pretražuje proširivanjem najperspektivnijeg čvora odabranog prema određenom pravilu.

Judea Pearl je opisao pretraživanje po najboljem prvom kao procjenu „obećanja” (engl. promise) čvora n korištenjem heurističke funkcije za procjenu f(n) koja, općenito, može ovisiti o opisu samog čvora, opisu cilja, informacijama koje su se prikupile u procesu pretraživanja do tog trenutka, i najvažnije, o bilo kojem dodatnom znanju o problemskoj domeni [5].

Unatoč svojim ograničenjima, prethodno opisani algoritmi penjanja uzbrdo i dinamičkog programiranja mogu se efikasno koristiti ukoliko su njihove heurističke funkcije vrednovanja f(n) dovoljno informirane da izbjegnu lokalne maksimume, mrtve završetke (engl. dead ends) i slične anomalije u prostoru pretraživanja.

No, općenito, korištenje heurističkog pretraživanja zahtijeva fleksibilniji algoritam. Ovo je omogućeno korištenjem pretrage po najboljem prvom, gdje je s prioritetnim redom (engl. priority queue) omogućen oporavak od opisanih problematičnih situacija.

Kod ove se metode koriste slijedeće liste stanja: lista OTVORENI kako bi se vodila zabilješka o trenutnim granicama (engl. fringe) pretraživanja te ZATVORENI kako bi se vodila zabilješka o prethodno posjećenim stanjima. Pregledavanjem liste OTVORENI odabiru se stanja za daljnju obradu na temelju heurističke procjene njihove „blizine” (engl. closeness) cilju. Dakle, svaka iteracija petlje uzima u obzir „najobećavajuće” (engl. most promising) stanje iz liste OTVORENI te ga uzima za daljnju obradu.

1. Stvori listu, OTVORENI, u kojoj se nalazi samo jedan čvor, početni, s

2. Ukoliko je lista prazna prijavi neuspjeh

3. Ukloni iz liste OTVORENI čvor n s najboljim rezultatom za heurističku funkciju vrednovanja f, te ga premjesti u listu ZATVORENI

4. Proširi čvor n

5. Ukoliko je bilo koji potomak od n krajnji ciljni čvor, prijavi uspjeh i vrati rješenje (put od ciljnog čvora do početnog čvora s)

9

Page 13: Heurističke metode pretrage

2.Teoretski dio

6. Za svaki čvor potomak:

a) evaluiraj heurističku funkciju f za dati čvor

b) ukoliko čvor nije bio ni u jednoj listi dodaj ga u listu OTVORENI

7. Skoči na korak 2

Programski kod 5: Pseudokod za algoritam najboljeg prvog

Heuristička funkcija vrednovanja koja se koristi za određivanje vrijednosti čvora nije precizno definirana, kao ni u ostalim heurističkim metodama. Implementacija je u praksi ostavljena programeru te može varirati ovisno o posebnostima prostora pretraživanja. Dok sama izvedba funkcije vrednovanja može u velikoj mjeri odlučivati o djelotvornosti i učinkovitosti pretraživanja, za potrebe razumijevanja rada algoritma ne treba se zabrinjavati sa specifičnostima funkcije.

Pošto postoje različiti načini kako izračunati „najboljeg prvog”, u nastavku će biti opisane neke od poznatijih i najčešće korištenih varijanti ovog algoritma.

2.4.1. Pretraživanje s uniformnim troškom

Pretraživanje s uniformnim troškom (engl. uniform cost search) je naziv za algoritam koji se koristi za proputovanje i pronalaženje najkraćeg puta do cilja u težinskom stablu i grafovima. Algoritam počinje s radom u čvoru korijenu te se postepeno proširuje po ostalim čvorovima, uzimajući kao sljedeći čvor onaj s najmanjim ukupnim troškom od korijena, sve dok ne stigne do ciljnog čvora. Ova vrsta pretraživanja ne uzima u obzir koliko koraka postoji u putu, već samo krajnji trošak puta. Zbog ovog razloga putevi s troškom nula (lokalne petlje) dovesti će do opetovanog vraćanja u isti čvor, što će rezultirati beskonačnom petljom za ovaj algoritam, odnosno, ostat će zauvijek u istom čvoru bez daljnjeg pomaka. Kako bi se osiguralo da algoritam bude optimalan i kompletan, duljina svakog puta mora biti veća od neke zadane male vrijednosti ε.

Ovaj algoritam je vrlo sličan Dijkstra algoritmu za pronalaženje najkraćeg puta u težinskom grafu. Karakteristično svojstvo za ovu varijantu je korištena heuristička funkcija vrednovanja. U tom slučaju ona predstavlja ukupan trošak puta te se kod odabira čvorova odabire onaj čvor koji rezultira njezinom najmanjom vrijednošću.

2.4.2. Pohlepno pretraživanje

U „pohlepne” (engl. greedy) algoritme spada svaki onaj algoritam koji kao slijed za rješavanje problema u svakom koraku uzima lokalni optimum s nadom da će u daljnjim koracima na taj način doći do globalnog optimuma. Na primjer, korištenjem pohlepne strategije kod problema putujućeg trgovca (engl. travelling salesman), u kojem trgovac mora proći kroz sve gradove u što manje putovanja, dolazimo do sljedećeg algoritma: „U svakom koraku algoritma posjeti onaj neposjećeni grad koji je najbliži trenutnom gradu”.

U tom duhu, možemo napraviti onaj izbor koji se čini najboljim u datom trenutku, a zatim rješavati potprobleme koji nastaju u nastavku. Izbor pohlepnog algoritma može ovisiti o odlukama donešenim do sada, no ne i o budućim i/ili svim mogućim

10

Page 14: Heurističke metode pretrage

2.Teoretski dio

rješenjima potproblema. Svakom se iteracijom pravi jedan pohlepni izbor za drugim, što dovodi do smanjivanja zadanog problema na manji. Drugim riječima, pohlepni algoritam nikada ne razmatra svoje dosadašnje odabire. To je glavna razlika od dinamičkog programiranja, koje je iscrpno i u kojem je zagarantirano pronalaženje rješenja. Nakon svake faze, kod dinamičkog programiranja donose se odluke na temelju svih odluka donešenih u prethodnoj fazi, a može se razmotriti i algoritamski put do rješenja iz prethodne faze.

Jedan od jednostavnih zadataka s kojim algoritam pohlepnog pretraživanja ima problema je tzv. „problem vraćanja ostatka” (engl. giving change problem). Recimo da imamo tri vrste kovanica: 10 lipa, 5 lipa i 2 lipe, te da ih moramo koristiti za vratiti točan ostatak. Algoritam ne bi mogao riješiti ovaj problem za npr. 41 lipu. Nakon vraćanja 4 kovanice po 10 lipa, nikako nije moguće riješiti problem korištenjem kovanica od 2 lipe.

Pohlepni algoritmi se stoga mogu okarakterizirati kao „kratkovidni” (engl. short sighted) i „nepopravljivi” (engl. non-recoverable) te predstavljaju idealan izbor samo za probleme koji imaju optimalnu podstrukturu.

2.4.3. Algoritam A*

Kod heurističkih se pretraživanja koristi činjenica da za većinu problema postoji neka informacija koja čini razliku između različitih stanja u smislu njihove vjerojatnosti dovođenja do cilja. Funkciju koja daje ovu vrstu informacije smo već prethodno upoznali kao heurističku funkciju vrednovanja (2.2.). Drugim riječima, cilj heurističkog pretraživanja je smanjenje broja korištenih stanja, odnosno čvorova, u procesu traženju cilja.

Najčešće korištena varijanta algoritma pretraživanja po najboljem prvom je tzv. „A* algoritam”. Koristi se kao i svi ostali heuristički algoritmi za smanjenje troškova pretraživanja u zadanom problemu. Osnovna razlika između osnovne varijante pretraživanja po najboljem prvom i A* algoritma je ta da se u slučaju potonjeg uzima također u obzir utrošeni trošak od samog početka izvođenja, a ne samo lokalni troškovi nastali prelaskom iz prethodnog čvora. Kod osnovnog pretraživanja po najboljem prvom pronalazi se ciljno stanje u bilo kojem zadanom prostoru problema, no ne može se garantirati da će biti odabran i najkraći put do cilja [8]. Na primjer, ako postoje dvije opcije za odabir, pri čemu je jedna dalja od početnog stanja, no ima malo manju procjenu udaljenosti do cilja, te druga koja je vrlo blizu početnom stanju, no ima nešto dalju procjenu udaljenosti do cilja, kod osnovnog algoritma po najboljem prvom uvijek će se odabrati ona opcija koja ima manju procjenu udaljenosti do cilja. Korištenjem algoritma A* ispravlja se ovaj (potencijalni) nedostatak.

Ukratko algoritam A* pretražuje sve moguće rute od početnog stanja sve dok ne pronađe najkraći i/ili najjeftiniji put do cilja. Pojmovi poput najkraćeg puta i najjeftinijeg puta su ovdje opće prirode. Umjesto njih se mogu koristiti drugi alternativni pojmovi, ovisno o problemu. Algoritam A* ocjenjuje čvorove kombinirajući vrijednosti funkcija g(n) i h(n), što se u standardnoj terminologiji predstavlja kao:

f(n) = g(n) + h(n)

11

Page 15: Heurističke metode pretrage

2.Teoretski dio

Svrha ove jednadžbe je dobivanje najmanjeg rezultata za funkciju f u zadanom problemu, pri čemu je s n predstavljen trenutni čvor, f(n) ukupan trošak pretraživanja, g(n) trenutno najmanji trošak (najkraća proputovana ruta) na putu od početnog čvora do čvora n, te h(n) procijenjen trošak najjeftinije (najkraće) rute od čvora n do ciljnog čvora. Pseudokod je isti kao i za sve varijante ove vrste pretraživanja (Programski kod 6), dok se za heurističku funkciju vrednovanja uzima upravo opisana funkcija f(n).

U svakom čvoru, kao sljedeći korak bira se onaj čvor koji ima najnižu izračunatu vrijednost funkcije f(n), iterativno ponavljajući sve dok se ne dođe do ciljnog čvora. Kad god heuristička funkcija vrednovanja zadovoljava određene uvjete, pretraživanje po ovom algoritmu je kompletno i optimalno [7].

Kao osnovne karakteristike algoritma A* navode se dopuštenost (engl. admissibility) i konvergencija (engl. convergence). Strategije koje jamče optimalno rješenje, ukoliko postoji bilo kakvo rješenje, nazivaju se dopuštenim. Za algoritam A* kaže se da je dopušten ukoliko je korištena funkcija h(n) dopuštena, dok je funkcija h(n) dopuštena ukoliko je h(n) <= h*(n) za svaki čvor n, pri čemu je s h*(n) označena stvarna minimalna udaljenost do cilja od čvora n. Strategija je konvergentna ako je zajamčeno pronalaženje puta, grafa rješenja ili tražene informacije, ukoliko oni uopće postoje [9]. Ukoliko uistinu postoji rješenje, algoritam A* će ga uvijek biti u stanju pronaći.

Prema [8] glavni nedostatak algoritma A* i ostalih algoritama pretraživanja po najboljem prvom su njihovi veliki zahtjevi za memorijskim resursima. Budući da cijela lista OTVORENI mora biti sačuvana, ovaj algoritam je prostorno ograničen u praksi i zbog toga nije previše praktičan. Za velike prostore pretraživanja, algoritam A* će morati nasilno prestati s radom uslijed nedostatka slobodne memorije. Nasreću postoje neke od modifikacija, poput IDA* (engl. krat. za Iterative Deepening A*), koje omogućuje velike uštede na ovom području [7].

2.5. Upotreba heuristike u računalnim igrama

2.5.1. Minimax

Minimax je naziv za algoritam poznat prije svega po svojoj korisnosti u izračunu najboljeg poteza u igrama za dva igrača, u kojima su u svakom trenutku dostupne sve informacije (npr. šah ili križić-kružić) [10]. Osnovna ideja kod ovog algoritma je pretraživanje stabla u kojem su sadržani svi mogući potezi u igri, pri čemu je svaki potez predstavljen u smislu gubitka i/ili dobiti za jednog od igrača, kako bi se minimizirao mogući gubitak te maksimizirao potencijalni dobitak. Alternativno se kao osnovna ideja također može uzeti maksimiziranje minimalne dobiti (tzv. maximin). Slijedi da se ovaj algoritam može koristiti samo za donošenje odluka u igrama s nultim zbrojem (engl. zero-sum game), u kojima je gubitak jednog igrača dobitak za drugog igrača.

Algoritmi za pretraživanje imaju tendenciju da koriste koncept uzroka i posljedice (engl. cause-and-effect), odnosno, u procesu pretraživanja uzima se u obzir svako moguće djelovanje u određenom trenutku: razmatraju se prelasci u nova stanja,

12

Page 16: Heurističke metode pretrage

2.Teoretski dio

naredni prelasci iz svakog od tih stanja, i tako dalje, u pokušaju da se pronađe krajnje stanje koje zadovoljava zadane ciljne uvjete.

Međutim u natjecateljskoj višeigraćoj igri, kada su drugi agenti (korisnik ili računalo) uključeni i imaju različite ciljeve na umu (agenti obično imaju suprostavljene ciljeve), stvari postaju kompliciranije. Čak i ako algoritam za pretraživanje može pronaći ciljno stanje, obično ne može jednostavno uzeti skup radnji koje će dovesti do tog stanja, budući da za svaku akciju koju naš algoritam vodi prema svom cilju suprostavljeni igrač može poduzeti radnju koja će promijeniti sadašnje stanje (vjerojatno na nepovoljan način za naš algoritam). To ne znači da su algoritmi pretraživanja beskorisni u pronalaženju strategija za višeigraće igre, već da jednostavno zahtijevaju dodatne taktike kako bi bili učinkoviti.

Za igre s dva igrača, algoritam minimax je primjer takve taktike. U njemu se koristi činjenica da dva igrača uvijek rade na suprotstavljenim ciljevima, kako bi se lakše napravilo predviđanje o budućim stanjima do kojih će se doći kako igra bude napredovala. U skladu s tim predviđanjima igra se nastavlja dalje kako bi se poboljšale šanse za pobjedu. Teorija iza algoritma minimax je ta da će protivnik uvijek pokušati minimalizirati vrijednost koju algoritam pokušava maksimalizirati (od tuda i sam naziv minimax). Dakle, računalo treba napraviti potez koji ostavlja protivnika u stanju u kojem može napraviti najmanje štete.

U idealnom slučaju (kad računalo ima beskonačno vremena i beskonačan kapacitet za pohranu podataka), računalo će istražiti mogući ishod svake podigre (engl. subgame) iz trenutnog stanja igre, kao i putove koji vode to tih stanja, te dodijeliti krajnjim stanjima pripadne vrijednosti. Za igre poput šaha ili križić-kružić, postoje samo tri moguća krajnja rezultata: pobjeda, poraz i neriješeno (često s pridodjeljenim brojčanim vrijednostima po redu pojavljivanja: 1, -1 i 0). U ostalim igrama, s pravim rezultatima, poput pokera ili bele, koriste se same vrijednosti rezultata. Zatim, počevši od dna stabla, računalo procjenjuje koji je ishod najbolji za protivnika. U toj fazi se pretpostavlja da će protivnik napraviti potez koji će ga odvesti bliže tom cilju te će računalo pokušati odabrati potez kako bi ga u tome onemogućilo.

1. Ukoliko je trenutni čvor list ili dubina nula vrati heurističku vrijednost trenutnog čvora

2. Postavi vrijednost α na -∞

3. Za svako dijete čvor izračunaj α = max(α, -minimax(dijete, dubina-1))

4. Vrati α

Programski kod 7: Pseudokod za funkciju minimax(čvor, dubina)

Glavni problem kod ovog pristupa je inherentna pesimističnost. U trivijalnim igrama, poput križić-kružića, algoritam ima itekako smisla stoga što je opravdano očekivati da će protivnik biti u stanju pronaći najbolju moguću opciju. No, u kompleksnijim igrama to više neće biti toliko jasno. Algoritam će žrtvovati potencijalno vrlo dobre poteze kako bi se učinilo sve samo da računalo ne izgubi. Ukratko, računalo pretpostavlja da igra protiv protivnika koji posjeduje barem jednako (ako ne i veće) znanje kao i ono samo.

Međutim, u stvarnosti, neograničeno korištenje algoritma minimax ima tendenciju da bude beznadno nepraktično te za mnoge igre nezanimljivo. U jednostavnoj igri

13

Page 17: Heurističke metode pretrage

2.Teoretski dio

poput križić-kružić računalo može izračunati sve moguće ishode, kojih ima 9!=362880, no to neće pomoći. Nadalje, korištenje ovog algoritma bez ikakvih poboljšanja će, ukoliko oba dva igrača igraju optimalno, uvijek završiti neriješenim rezultatom. To također znači da u tom slučaju ne postoji nešto poput „najboljeg” otvaranja.

Ipak, ovaj algoritam je koristan kada se koristi zajedno s heuristikom koja približno računa ishode iz određene točke. Na primjer, u igrama poput šaha figurama se često dodijeljuju vrijednosti kako bi se približno odredila njihova relativna snaga i korisnost za pobjedu (kraljica=9, top=5, itd.). Dakle, iako računalo možda neće moći predvidjeti sve moguće situacije od prvog poteza do šah-mata, bit će u stanju ustvrditi koji će potez najvjerojatnije dovesti do materijalne koristi.

2.5.2. Alfa-beta rezidba

Minimax algoritam služi za pronalaženje optimalnog poteza u igri za dva igrača. Alfa-beta rezidba je naziv za algoritam koji služi za pronalaženje optimalnog minimax rješenja izbjegavanjem pretraživanja podstabala koje sadrže poteze koji sigurno neće biti odabrani.

Jedan od najelegantinijih algoritama za pretraživanje u području umjetne inteligencije je tzv. „alfa-beta rezidba” (engl. alpha-beta pruning). Osnovna ideja algoritma je ta da je moguće odrediti pripadnu minimax vrijednost korijena stabla bez razmatranja svih čvorova unutar cjelokupnog prostora pretraživanja.

Prednost alfa-beta rezidbe leži u činjenici da se grane stabla pretraživanja mogu elimitirati. Vrijeme pretraživanja se na taj način može ograničiti na podstabla koja „više obećavaju”. Ukoliko su čvorovi ocijenjeni u optimalnom i/ili blizu optimalnog reda, kod ove vrste optimizacije smanjuje se efektivna dubina pretraživanja na malo više od polovice s obzirom na (svog prethodnika) minimax algoritam.

Algoritam čuva dvije vrijednosti, alfa (α) i beta (β), koje predstavljaju minimalni maksimalni te maksimalni minimalni rezultat. U početku je alfa inicijalizirana na vrijednost minus beskonačno (-∞), dok je beta inicijalizirana na vrijednost plus beskonačno (+∞). Kako se rekurzija nastavlja tako i „prozor”, odnosno razmak između vrijednosti alfa i beta, postaje sve manji. U trenutku kad beta postane manja nego alfa, to znači da trenutna pozicija nikako ne može biti rezultat najbolje igre oba igrača te stoga ne mora biti istražena nadalje.

Daljnje poboljšanje može se postići bez žrtvovanja točnosti korištenjem heuristike u svrhu poređivanje dijelova stabla pretraživanja. Pojedini dijelovi stabla se preslaguju po principu da se na početak stave oni dijelovi koji su vjerojatniji kandidati da će ranije biti odsječeni od stabla. Na primjer, u šahu, potezi koji uzimaju figure mogu se obraditi prije ostalih poteza.

Alfa-beta pretraživanje može se još ubrzati korištenjem manjeg prozora za pretraživanje (u pravilu određenog nagađanjem na temelju iskustva). Ova varijanta je poznata kao „pretraživanje nadanjem” (engl. aspiration search). U ekstremnom slučaju, pretraživanje se odvija korištenjem jednakih vrijednosti za alfa i beta, pri čemu se ova tehnika naziva „pretraživanje nultim prozorom” (engl. zero-window search ili null-window search) ili tzv. „izviđačko pretraživanje” (engl. scout search) [6].

14

Page 18: Heurističke metode pretrage

2.Teoretski dio

Ovo je osobito korisno za pretragu krajnjih stanja pobjeda/poraz pri kraju igre gdje se dodatnom dubinom dobivenom korištenjem uskog prozora i jednostavnom evaluacijskom funkcijom može dovesti do konačnog rezultata. Ako pretraživanje nadanjem ne uspije, jednostavno je za otkriti da li je došlo do neuspjeha zbog gornje (viši rub prozora je bio prenizak) ili donje (niži rub prozora je bio previsok) granice prozora. Na taj se način također dobivaju informacije o tome koje bi vrijednosti prozora mogle biti korisne u ponovnom pretraživanju.

2.6. Problemi kompleksnosti

Najteži aspekt kombinatoričkih problema je taj da vrlo često dolazi do „eksplozija” bez da sam dizajner shvaća što se zapravo dogodilo. Stoga što se većina ljudskih aktivnosti, računalnih i inih, događaju u svijetu linearnog vremena, imamo poteškoća s poimanjem eksponencijalnog rasta. Tako se često može čuti prigovor poput: „Da sam samo imao malo jače (ili brže ili visoko skalabilno) računalo moj problem bi bio riješen”. Takve tvrdnje, obično izrečene nakon same eksplozije, su najčešće neozbiljne. Problem se nije shvatio na pravilan način te odgovarajući koraci nisu poduzeti kako bi se na vrijeme riješio kombinatorički problem situacije.

Puni opseg kombinatoričkog rasta može posrnuti i samu maštu. Procijenjeni je broj stanja potrebnih za pretraživanje cijelog prostora šahovskih poteza otprilike 1012. Ovo nije samo „još jedan veliki broj”, već se može usporediti s brojem molekula u svemiru ili brojem nanosekundi od „Velikog praska” (engl. Big Bang).

Razvijeno je nekoliko mjera kako bi se pomoglo kod izračuna složenosti. Jedan od njih je faktor grananja prostora [7]. Faktor grananja prostora definiran je kao prosječan broj grana (potomaka) koji se proširuje iz bilo kojeg stanja u prostoru pretraživanja. Broj stanja na dubini n kod pretraživanja jednak je faktoru grananja na n-tu potenciju. Jednom kad se izračuna faktor grananja za prostor pretraživanja moguće je procijeniti trošak potreban za generiranje putova bilo koje duljine. Na slici 3 je prikazan odnos između B (grananja), L (duljine puta) i T (ukupnog broja stanja u pretrazi) za male vrijednosti. Graf je prikazan u logaritamskom mjerilu za veličinu T.

15

Slika 3: Broj čvorova/stanja kao funkcija faktora grananja B za različite duljine puta L

Page 19: Heurističke metode pretrage

2.Teoretski dio

Mjerenje prostora pretraživanja je obično empirijski proces koji se izvodi znatnim „igranjem” s problemom i ispitivanjem njegovih varijanti. Pretpostavimo, na primjer, da želimo ustvrditi faktor grananja za slagalicu s osam dijelova. Računamo ukupan broj mogućih poteza: 2 iz svakog ugla za ukupno 8 poteza, 3 iz centra svake strane za ukupno 12, te 4 iz centra mreže za sveukupni broj poteza 24. Kad se taj broj podijeli s 9, odnosno brojem različitih lokacija za prazno polje, dobivamo prosječni faktor grananja 2.67.

Kao što se može vidjeti na slici 3, taj rezultat nije dobar za dubinsko traženje. Ukoliko eliminiramo poteze koji se vraćaju natrag na stanja roditelje tada ćemo dobiti jedan potez manje iz svakog stanja. Ovo daje faktor grananja 1.67, koji predstavlja značajno poboljšanje, što bi u konačnici moglo (u nekim prostorima stanja) omogućiti iscrpno pretraživanje (engl. exhaustive search).

Složenost utroška algoritma se također može mjeriti pomoću veličine otvorene i zatvorene liste (2.4.). Jedan način kako voditi razumnu veličinu liste otvorenih je spremanjem samo nekoliko (heuristički) najboljih stanja. Ovo može dovesti do bolje usmjerenih pretraživanja, no postoji opasnost da će se eventualno eliminirati najbolji, potencijalno i jedini, put do rješenja. Ova metoda održavanja razumne veličine liste stanja, često funkcija broja koraka sprovedenih u pretraživanju, naziva se „usmjereno pretraživanje” (engl. beam search).

U pokušaju da se smanji faktor grananja ili na neki drugi način ograniči pretraživanje prostora, uvodi se pojam „više informiranih heuristika”. Što je više informirano pretraživanje, manji je prostor potrebno pretražiti kako bi se dobilo optimalno rješenje. No, kod rješavanja problema na računalu nije dovoljno samo pronaći minimalni put do rješenja u što manjem prostoru pretraživanja. Također je potrebno minimizirati ukupne procesorske troškove.

16

Slika 4: Izračun stanja i heurističkih funkcija s obzirom na informiranost

Page 20: Heurističke metode pretrage

2.Teoretski dio

Na slici 4 se na informativan način pokušalo prikazati navedene probleme. Koordinatna os informiranosti predstavlja mjeru koja je proporcionalna s količinom ušteđenog računalnog utroška potrebnog za računanje heuristike. Koordinatna os računalnog troška predstavlja utrošeno procesorsko vrijeme i slične aspekte pretrage. Kako se količina informacija uključenih u heurističku pretragu povećava, tako se i povećava procesorski trošak. Slično tome, kako heuristika biva informiranija, tako i potreban procesorski trošak za računanje stanja biva manjim, i to zbog općenito manjeg broja stanja. „Kritičan trošak” (engl. critical cost) predstavlja ukupan trošak potreban za prolazak kroz sva stanja PLUS dodatni trošak računanja heuristike te je poželjno da on bude što manji.

17

Page 21: Heurističke metode pretrage

3.Praktični uradak

3. Praktični uradak

Za potrebe praktičnog dijela ovog uratka napravljena je implementacija tzv. „optimizacijskog algoritma mravlje kolonije” (engl. ant colony optimization algorithm – ACO) za rješavanje problema trgovačkog putnika (engl. traveling salesman problem – TSP). U računalnoj znanosti, optimizacijski algoritam mravlje kolonije je naziv za probabilističke tehnike namijenjene rješavanju računalnih problema koji se mogu svesti na pronalaženje „dobrih” staza kroz grafove.

Inteligencija roja (engl. swarm intelligence) je relativno nov pristup u rješavanju problema koji uzimaju za inspiraciju društveno ponašanje insekata i drugih životinja. Konkretno, mravi su poslužili kao inspiracija brojnim metodama i tehnikama, među kojima je najproučavaniji i najuspješniji optimizacijski algoritam mravlje kolonije. U njemu se kao inspiracija uzelo određeno ponašanje nekih vrsta mrava, koji ostavljaju feromone na terenu kako bi označili „povoljne” putove koje bi trebali slijediti i ostali članovi kolonije. U ovom se algoritmu koristi sličan mehanizam za rješavanje optimizacijskih problema [11].

U širem smislu, optimizacija mravlje kolonije je naziv za klasu algoritama modeliranih po uzoru na mravlje kolonije. Umjetni mravi (simulacijski agenti) pronalaze optimalna rješenja prolaženjem kroz parametarski prostor, koji predstavlja sva moguća rješenja. Pravi mravi ostavljaju feromone kako bi usmjeravali jedan drugoga do resursa prilikom istraživanja okoline. Umjetni mravi na sličan način „zapisuju” svoje pozicije i kvalitetu rješenja, tako da bi u kasnijim iteracijama simulacije više mrava pronašlo bolja rješenja. Samo kao primjer, jedna varijacija na ovaj pristup je tzv. „pčelinji algoritam” (engl. bees algorithm), koji za analogiju uzima obrazac skupljanja meda kod pčela [14].

Konkretno, u praktičnom uratku napravila se implementacija optimizacijskog algoritma mravlje kolonije kako bi se riješio problem putujućeg putnika (engl. traveling salesman problem – TSO). U problemu putujućeg putnika potrebno je pronaći najkraći put između svih zadanih gradova, pri čemu se smije kroz svaki grad proći samo jednom.

Također je napravljena implementacija rješenja problema korištenjem algoritma sirove snage (engl. brute force method), u kojem se pretražuje ukupan prostor stanja kako bi se pronašlo rješenje, radi usporedbe rezultata s onim dobivenim optimizacijskim algoritmom mravlje kolonije.

Za potrebe implementacije korišten je programski jezik Python, prije svega radi svoje jednostavnosti, fleksibilnosti i preglednosti napisanog koda. Prilikom izvođenja program generira slučajnim odabirom popis gradova i udaljenost među njima, pronalazi rješenje problema korištenjem oba algoritma te na kraju ispisuje dobivene najbolje puteve i vremena izvođenja.

Program (A.1.) se sastoji od bazne klase (TravelingSalesmanProblem), izvedene klase za algoritam sirove snage (BruteForce), izvedene klase za algoritam mravlje kolonije (AntColonyOptimization), metode za parsiranje argumenata (parseCmdLine) te glavne metode programa (main). U baznoj klasi su zadane metode potrebne za oba

18

Page 22: Heurističke metode pretrage

3.Praktični uradak

algoritma, poput metode za računanje duljine puta (pathDistance), metode za računanje svih bridova puta predstavljenog gradovima (pathEdges) ili metode za računanje svih mogućih putova iz svih zadanih gradova (allPaths). Kod oba algoritma glavna metoda (solve) predstavlja osnovu implementacije, s pripadnim (ostalim) pomoćnim metodama. Među argumentima koji se mogu zadati prilikom pokretanja programa tu su argumenti za zadavanje broja gradova (-c), maksimalne udaljenosti između gradova (-m), broja simuliranih mrava (-a), broja iteracija kod algoritma mravlje kolonije (-i), itd.

Metoda sirove snage je implementirana na način da se za sve moguće putove koji sadrže sve gradove traži onaj koji ima najmanju ukupnu dužinu. Metoda mravlje kolonije je implementirana na način da se za zadani broj iteracija izvrši simulacija prolaska zadanog broja mrava kroz put sačinjen od svih zadanih gradova na predefinirani način kako bi se na kraju uzeo onaj put koji ima najmanju ukupnu dužinu.

1. Inicijaliziraj feromone za sve moguće staze

2. Za svakog simuliranog mrava heuristički generiraj moguću stazu

3. Ažuriraj najbolju stazu na temelju dobivenih duljina

4. Dekrementiraj feromone svih staza

5. Inkrementiraj feromone samo trenutno odabranih staza

6. Skoči na 2 ukoliko je redni broj ponavljanja manji od zadanog

7. Vrati najbolju stazu

Programski kod 8: Pseudokod za algoritam mravlje kolonije

Srž algoritma se sastoji u heurističkom generiranju staza za svakog pojedinog mrava. Put se generira postepeno grad po grad (selectEdge) vjerojatnosnim odabirom staza na temelju heuristički izračunatih vrijednosti (getEdgeValue). Što je veća heuristička vrijednost promatrane staze, odnosno izračunati kvocijent vrijednosti feromona i udaljenosti između promatranih gradova, to je veća vjerojatnost da će baš ta staza biti odabrana za prelazak iz trenutnog stanja u sljedeće. Jednom kad se izračunaju heurističke vrijednosti, sve se moguće staze iz trenutnog grada poredaju na vjerojatnosnu liniju te se nasumičnim odabirom bira jedna od njih. Razumljivo, što je veća heuristička vrijednost to su i veće šanse da će upravo ta staza biti odabrana.

Kao rezultat praktičnog uratka uzeta su vremena izvođenja za metodu sirove snage (BF) i algoritam mravlje kolonije (ACO) s različitim vrijednostima parametra broja iteracija (50,100,200), za različit broj gradova (7,8,9,10). Program se izvršavao na operativnom sustavu Ubuntu Linux 10.10 32-bit, računalu zasnovanom na Intel Q6600 (4x2.4GHz) arhitekturi te programskom interpreteru Python 2.6.6.

Za svaki (pod)algoritam i različit broj gradova program se izvršio deset puta te se kao rezultat izvođenja uzela srednja vrijednost vremena izvođenja. Kao što je vidljivo na slici 5, vrijeme potrebno za rješavanja problema, za broj gradova veći od 9, u sve tri podvarijante algoritma mravlje kolonije (ACO(50),ACO(100),ACO(200)) bilo je znatno manje od metode sirove snage (BF). Također je vidljivo da povećanjem broja iteracija po podvarijantama algoritma mravlje kolonije raste i vrijeme potrebno za rješavanje problema.

19

Page 23: Heurističke metode pretrage

3.Praktični uradak

No, znatno bitniji zaključak koji je moguće dobiti iz grafa rezultata je taj da se kod heurističkog algoritma mravlje kolonije vrijeme izvođenja povećava linearno (polinomno) sa složenošću problema, dok se kod pretraživanja kompletnog prostora stanja metodom sirove snage vrijeme izvršavanja povećava eksponencijalno. Na ovaj se način jasno pokazalo da heuristički algoritmi smanjuju složenost problema za čitav red kompleksnosti.

Mala napomena. Kao što je vidljivo iz prezentiranih rezultata, za potrebe testiranja uzet je različit broj iteracija prilikom izvođenja algoritma mravlje kolonije te se za manji broj iteracija algoritam očito brže izvršavao. No, ispod određene granice algoritam više nije davao optimalne rezultate s najkraćom mogućom stazom već dovoljno dobre rezultate, što je u biti i cilj ovog algoritma. U ovom slučaju što se broj iteracija više smanjio od 50 to je rezultat bio podoptimalniji.

Početne primjene klase algoritama mravlje kolonije su bile u domeni NP-teških kombinatoričkih optimizacijskih algoritama. Najveći dio istraživanja se još uvijek nalazi u ovoj domeni te se njihov kompletan pregled može pronaći u [13]. Druga primjena koja se mogla pronaći u počecima ACO algoritama je rješavanje problema usmjeravanja (engl. routing) u telekomunikacijskim mrežama. Posebno uspješan primjer algoritma u ovoj domeni je AntNet [15]. Trenutno istraživanje kod ACO algoritama je posvećeno razvoju teorijske osnove kao i primjene ove heurističke metode u novi izazovnim problemima, poput: klasifikacije, procesiranja slike, inteligentni testni sustavi, otkrivanje znanja u skupovima podataka, itd. [16]

20

Slika 5: Rezultati izvođenja za različite metode rješavanja problema putujućeg trgovca

7 8 9 10

0

1

2

3

4

5

6

7

8

9

10

Problem putujućeg trgovca

Vremena izvođenja

BFACO (50)ACO (100)ACO (200)

Broj gradova

Pro

sje

čno

vri

jem

e iz

vođ

en

ja (

s)

Page 24: Heurističke metode pretrage

4.Zaključak

4. Zaključak

Heuristika je općenit naziv za metodu koja možda neće uvijek polučiti najboljim rezultatom, no zagarantirano će naći dobro rješenje u razumnom vremenskom periodu. U ovom se slučaju žrtvovanjem kompletnosti znatno povećala efikasnost.

U praktičnom dijelu uratka prezentirani su rezultati dobiveni implementacijom jedne takve heurističke metode – optimizacijskog algoritma mravlje kolonije. Za ovaj algoritam je karakteristično da se imitiranjem prirodnih procesa mravlje kolonije na poprilično uspješan način rješavaju problemi koji se mogu opisati kao problem proputovanja.

U našem se slučaju navedeni heuristički algoritam iskoristio za rješavanje problema putujućeg putnika te se iz dobivenih rezultata jasno moglo iščitati da se kombinatorička složenost problema smanjila s eksponencijalne na polinomnu.

Upravo su iz tog razloga heurističke metode posebno korisne u rješavanju teških problema koji se inače ne bi mogli riješiti na bilo koji drugi način i/ili čije bi rješavanje zahtjevalo beskonačno ili jako dugo vremena za računanje.

21

Page 25: Heurističke metode pretrage

5.Literatura

5. Literatura

[1] Luger, G. F.: „Artificial Intelligence: Structures and Strategies for Complex Problem Solving”, Addison Wesley, 2005.

[2] Osman, I. H.: „Meta-heuristics: Theory & Applications”, Springer, 1996.

[3] Eddy, S. R.: „What is dynamic programming?”, Nature Biotechnology, 2004.

[4] Nocedal, J.; Wright, S. J.: „Numerical Optimization”, Springer, 2006.

[5] Pearl, J.: „Heuristics: Intelligent Search Strategies for Computer Problem Solving”, Addison-Wesley, 1984.

[6] Schaeffer, J.: „The history heuristic and alpha-beta search enhancements in practice”, IEEE, 1989.

[7] Russell, S. J.; Norvig, P.: „Artificial Intelligence: A Modern Approach”, Prentice Hall, 2009.

[8] Pearl, J.; Korf, R. E.: „Search techniques”, Annual Review of Computer Science”, 1987.

[9] Bolc, L.; Cytowski, J.: „Search Methods for Artificial Intelligence”, Academic Press, 1992.

[10] Muller, M.: „Global and Local Game Tree Search”, Information Sciences, 2001.

[11] Dorigo, M.; Birattari, M.; Stützle, T.: „Ant Colony Optimization – Artificial Ants as a Computational Intelligence Technique”, IEEE, 2006.

[12] Garey, M. R.; Johnson, D. S.: „Computers and Intractability: A Guide to the Theory of NP-Completeness”, W. H. Freeman & Co., 1979.

[13] Dorigo, M.; Stützle, T.: „Ant Colony Optimization”, MIT Press, 2004.

[14] Karaboga, D.; Basturk, B.: "A powerful and efficient algorithm for numerical function optimization: artificial bee colony (ABC) algorithm", Journal of Global Optimization, 2007.

[15] Di Caro, G.; Dorigo, M.: „AntNet: Distributed stigmergetic control for communications networks”, Journal of Artificial Intelligence Research, 1998.

[16] Sim, K. M.; Sun, W. H.: „Ant colony optimization for routing and load-balancing: survey and new directions”, IEEE, 2003.

22

Page 26: Heurističke metode pretrage

Dodatak A:Programski kod

Dodatak A: Programski kod

A.1. TSP.py#!/usr/bin/python

# -*- coding: utf-8 -*-

import itertools

import random

import sys

import time

from optparse import OptionGroup

from optparse import OptionParser

class TravelingSalesmanProblem:

def __init__(self, cities, distances):

"""

Instanciranje bazne klase za računanje problema putujućeg putnika

"""

self.cities = cities

self.distances = distances

def pathEdges(self, path):

"""

Računa sve bridove puta sastavljenog od gradova

"""

return zip(path, path[1:])

def pathDistance(self, path):

"""

Računa ukupnu dužinu puta

"""

23

Page 27: Heurističke metode pretrage

Dodatak A:Programski kod

retVal = 0

for edge in self.pathEdges(path):

retVal += self.distances[edge[0]][edge[1]]

return retVal

def allEdges(self):

"""

Računa sve moguće bridove između bilo koja dva grada

"""

for edge in itertools.combinations(self.cities, 2):

yield edge

yield (edge[1], edge[0])

def allPaths(self):

"""

Računa sve moguće putove između svih gradova

"""

for path in itertools.permutations(self.cities):

if path[0] < path[-1]:

yield path

def edgesToPath(self, edges):

"""

Računa put iz zadanih bridova

"""

path = []

for edge in edges:

path.append(edge[0])

path.append(edges[-1][1])

return path

24

Page 28: Heurističke metode pretrage

Dodatak A:Programski kod

class BruteForce(TravelingSalesmanProblem):

def __init__(self, cities, distances):

"""

Predstavlja klasu za računanje problema korištenjem brute-force metode

"""

TravelingSalesmanProblem.__init__(self, cities, distances)

def solve(self):

"""

Računa rješenje problema (najmanji ukupan put)

"""

start = time.time()

minDistance = None

minPath = None

for path in self.allPaths():

distance = self.pathDistance(path)

if minDistance is None or distance < minDistance:

minDistance = distance

minPath = path

delta = time.time() - start

return minDistance, minPath, delta

class AntColonyOptimization(TravelingSalesmanProblem):

def __init__(self, cities, distances, ants, iterations, initialPheromone, evaporation):

"""

Predstavlja klasu za računanje problema korištenjem ACO metode

"""

TravelingSalesmanProblem.__init__(self, cities, distances)

25

Page 29: Heurističke metode pretrage

Dodatak A:Programski kod

self.ants = ants

self.iterations = iterations

self.initialPheromone = initialPheromone

self.evaporation = evaporation

self.pheromoneMap = None

def initPheromoneMap(self):

"""

Postavlja inicijalne vrijednosti feromona po svim rubovima

"""

self.pheromoneMap = {}

for edge in self.allEdges():

self.pheromoneMap[edge] = self.initialPheromone

def decayPheromones(self):

"""

Dekrementira vrijednost feromona po svim rubovima

"""

for key in self.pheromoneMap.keys():

self.pheromoneMap[key] *= (1 - self.evaporation)

def leavePheromones(self, path):

"""

Inkrementira vrijednost feromona po svim rubovima zadanog puta

"""

delta = 1.0 / self.pathDistance(path)

for edge in self.pathEdges(path):

self.pheromoneMap[edge] += delta

def getEdgeValue(self, edge):

"""

Vraća heurističku vrijednost zadanog ruba

"""

26

Page 30: Heurističke metode pretrage

Dodatak A:Programski kod

distance = self.distances[edge[0]][edge[1]]

pheromone = self.pheromoneMap[edge]

return pheromone / distance

def selectEdge(self, edges):

"""

Vraća heuristički odabran rub od svih mogućih rubova

"""

sumValues = 0

edgeValues = {}

edgeProbabilities = {}

for edge in edges:

edgeValues[edge] = self.getEdgeValue(edge)

sumValues += edgeValues[edge]

for edge, value in edgeValues.items():

edgeProbabilities[edge] = value / sumValues

sortedEdges = map(lambda x: x[1],

sorted(

map(lambda edge: (1.0 - edgeProbabilities[edge], edge), edges)))

probability = random.random()

cummulative = 0.0

for edge in sortedEdges:

cummulative += edgeProbabilities[edge]

if cummulative > probability:

return edge

return sortedEdges[-1]

27

Page 31: Heurističke metode pretrage

Dodatak A:Programski kod

def antRun(self):

"""

Vraća heuristički generiran put jednog mrava

"""

availableCities = list(self.cities)

selectedEdges = []

currentCity = availableCities[random.randint(0, len(self.cities) - 1)]

availableCities.remove(currentCity)

while availableCities:

availableEdges = [ (currentCity, city) for city in availableCities]

selectedEdge = self.selectEdge(availableEdges)

currentCity = selectedEdge[1]

availableCities.remove(currentCity)

availableEdges.remove(selectedEdge)

selectedEdges.append(selectedEdge)

path = self.edgesToPath(selectedEdges)

return path

def solve(self):

"""

Računa rješenje problema (najmanji ukupan put) korištenjem ACO metode

"""

start = time.time()

minDistance = None

minPath = None

self.initPheromoneMap()

for iteration in xrange(self.iterations):

28

Page 32: Heurističke metode pretrage

Dodatak A:Programski kod

paths = []

for ant in xrange(self.ants):

path = self.antRun()

distance = self.pathDistance(path)

if minDistance is None or distance < minDistance:

minDistance = distance

minPath = path

self.decayPheromones()

for path in paths:

self.leavePheromones(path)

delta = time.time() - start

return minDistance, minPath, delta

def parseCmdLine():

"""

Parsira argumente komandne linije korištenjem OptionParser instance

"""

usage = "%s [options]" % sys.argv[0]

parser = OptionParser(usage=usage)

general = OptionGroup(parser, "General")

general.add_option("-s", dest="seed", default=None, type="int",

help="random seed")

general.add_option("-c", dest="cities", default=10, type="int",

help="number of cities (default: 10)")

29

Page 33: Heurističke metode pretrage

Dodatak A:Programski kod

general.add_option("-m", dest="maximumDistance", default=20, type="int",

help="maximum distance between cities (default: 20)")

aco = OptionGroup(parser, "Ant colony optimization")

aco.add_option("-a", dest="ants", default=100, type="int",

help="number of ants (default: 100)")

aco.add_option("-p", dest="pheromone", default=0.1, type="float",

help="initial pheromone amount (default: 0.1)")

aco.add_option("-e", dest="evaporation", default=0.1, type="float",

help="pheromone evaporation level (default: 0.1)")

aco.add_option("-i", dest="iterations", default=100, type="int",

help="iterations used in heuristics (default: 100)")

parser.add_option_group(general)

parser.add_option_group(aco)

(args, _) = parser.parse_args()

return args

def main():

"""

Predstavlja glavnu metodu programa (ispisuje vrijeme izvođenja obje metode i rješenja)

"""

args = parseCmdLine()

cities = xrange(args.cities)

30

Page 34: Heurističke metode pretrage

Dodatak A:Programski kod

distances = []

random.seed(args.seed)

for i in xrange(args.cities):

distances.append([0] * args.cities)

for i in xrange(args.cities):

for j in xrange(i, args.cities):

distances[j][i] = distances[i][j] = random.randint(1, args.maximumDistance) if i!= j else 0

brute = BruteForce(cities, distances)

print brute.solve()

aco = AntColonyOptimization(cities, distances, args.ants, args.iterations, args.pheromone, args.evaporation)

print aco.solve()

if __name__ == '__main__':

main()

31