Upload
others
View
1
Download
0
Embed Size (px)
Citation preview
UNIVERZA V MARIBORU
FAKULTETA ZA ELEKTROTEHNIKO,
RAČUNALNIŠTVO IN INFORMATIKO
Anton Štuhec
ISKANJE NAJKRAJŠE POTI MED DVEMA TOČKAMA Z
ALGORITMOM A*
Diplomska naloga
Maribor, september 2008
i
UNIVERZA V MARIBORUFAKULTETA ZA ELEKTROTEHNIKO,RAČUNALNIŠTVO IN INFORMATIKO2000 Maribor, Smetanova ul. 17
Diplomska naloga visokošolskega strokovnega študijskega programa
ISKANJE NAJKRAJŠE POTI MED DVEMA TOČKAMA Z
ALGORITMOM A*
Študent: Anton ŠTUHEC
Študijski program: visokošolski strokovni, Računalništvo in informatika
Smer: Programska oprema
Mentor: red. prof. dr. Borut ŽALIK
Komentor: doc. dr. David Podgorelec
Maribor, september 2008
ii
iii
ZAHVALA
Zahvaljujem se mentorju dr. Borutu Žaliku za
pomoč in vodenje pri opravljanju diplomske
naloge. Prav tako se zahvaljujem vsem članom
Laboratorija za geometrijsko modeliranje in
algoritme multimedije.
Posebna zahvala velja staršem, ki so mi
omogočili študij.
iv
ISKANJE NAJKRAJŠE POTI MED DVEMA TOČKAMA Z ALGORITMOM A*
Ključne besede: iskanje najkrajše poti, Dijkstrov algoritem, algoritem BFS, algoritem A*, hevristična funkcija
UDK: 004.92:514(043.2)
Povzetek
Cilj naloge je preučiti hevristični algoritem A* in ga uporabiti za iskanje najkrajše poti
med dvema točkama na površju. Implementirali smo ga v programskem jeziku C++ v
obliki programske knjižnice, primerne za vključitev v program za prikazovanje površja.
Omogočili bomo izbiranje med večimi hevrističnimi funkcijami in nabori parametrov le-
teh ter s primerjavo rezultatov poizkušali poiskati čim optimalnejše nastavitve. Nalogo
pričnemo s predstavitvijo drugih rešitev problema iskanja najkrajše poti in opisom
predhodnikov algoritma A*. Omenimo zgodovino ter nastanek algoritma, nadaljujemo pa
z opisom postopka. Opišemo hevristične funkcije, implementirane v programu, na koncu
pa komentiramo dobljene rezultate.
v
SEARCH FOR THE SHORTEST PATH
BETWEEN TWO POINTS WITH A* ALGORITHM
Key words: Shortest path search, Dijkstra algorithm, BFS algorithm, A* algorithm, heuristic function
UDK: 004.92:514(043.2)
Abstract
Our goal is to analyze the A* algorithm to determine possible improvements and to
implement it in programming language C++. The work begins with presentation of other
solutions of our problem and with a description of ancestors of the A* algorithm. We
mention history of algorithm, proceed with description of the procedure and its properties.
Then we describe heuristic functions, which we have implemented in program, and
possible improvements, followed by description how the task was realized. At the end we
show the results of algorithm A*.
vi
VSEBINA
1Uvod...............................................................................................................................1
2Predstavitev algoritmov iskanja najkrajše poti...............................................................3
1.1 Dijkstrov algoritem ................................................................................................. 3
1.2 Algoritem BFS ........................................................................................................ 4
3Algoritem A*..................................................................................................................8
1.3 Zgodovina algoritma A* ......................................................................................... 8
1.4 Opis algoritma A* ................................................................................................... 8
................................................................................................................................... 11
1.5 Hevristične funkcije .............................................................................................. 12
1.5.1 Razdalja Manhattan ....................................................................................... 12
1.5.2 Diagonalna razdalja ....................................................................................... 13
1.5.3 Evklidska razdalja .......................................................................................... 14
4Načrtovanje algoritma za iskanje najkrajše poti med točkama površja........................16
1.6 Priprava mape ....................................................................................................... 16
1.7 Implementacija ..................................................................................................... 17
1.7.1 Algoritem A* ................................................................................................. 17
1.7.2 Hevristične funkcije ....................................................................................... 18
1.7.3 Testna aplikacija ............................................................................................ 18
1.7.4 Volos .............................................................................................................. 20
5Analiza in rezultati........................................................................................................21
6Sklep.............................................................................................................................32
LITERATURA...............................................................................................................33
1
1 Uvod
V sodobnem načinu življenja, ko nam vedno znova primanjkuje čas in je le-ta
najdragocenejši, moramo vsako delo opraviti kar najhitreje. Pri tem nam je v veliko pomoč
tehnika, ki pa potrebuje dobre in optimizirane algoritme. Velikokrat se v tehniki in v
življenju pojavi potreba prehoda iz ene do druge točke, kar lahko predstavlja veliko
porabljenega časa in napora. Za pohitritev in poenostavljanje so bili razviti algoritmi za
iskanje najkrajše poti [7]. Ti algoritmi se med drugim uporabljajo pri iskanju poti v
komunikacijah, v igrah, v upravljanju robotiziranih vozil ter za pomoč pri potovanju ljudi.
Algoritmi za iskanje najkrajše poti še vedno predstavljajo velik zalogaj tudi za današnje
hitre računalnike, saj je hitrost algoritma odvisna od števila točk, ki jih algoritem mora
pregledati, le-to pa je lahko v praksi zelo visoko. Zato algoritme poskušamo optimizirati.
Glavni cilj optimizacije je zmanjšati število točk za pregledovanje na tolikšno število,
kolikor je točk v najdeni najkrajši poti. V ta namen poizkušamo vnaprej predvidevati
mogoče ovire.
Namen naloge je preučiti enega izmed najbolj priljubljenih algoritmov za iskanje
najkrajše poti – algoritem A*. Osredotočili se bomo na iskanje poti med dvema točkama na
površju. Algoritem uporablja za odločanje o smeri iskanja hevristično metodo iskanja z
izbiro najboljšega (angl. best-first search) in vedno najde najkrajšo pot od začetne do
končne točke, če ta obstaja. Pri implementaciji je potrebno preučiti možnosti za
optimizacijo programske kode, uporabiti podatkovne strukture ter algoritem spisati v taki
obliki, da se potem lahko vključi v kak program. Podatki o površju so lahko v kateri koli
obliki, zato mora biti algoritem prilagodljiv. Zaradi primerjanja rezultatov lahko algoritem
uporablja različne hevristične funkcije, zato je potrebno vgraditi možnost različnih
hevristik. Spreminjamo hevristične funkcije in opazujemo dobljene rezultate, s čimer lahko
določimo, katera funkcija se bolje obnaša. Za delovanje algoritma potrebujemo tudi
ustrezne podatke, ki jih moramo pravilno zbrati in jih na najenostavnejši način na koncu
tudi predstaviti, kot najdemo najkrajšo pot.
2
Diplomska naloga je sestavljena iz šestih poglavij. Po uvodnem poglavju predstavimo
druge rešitve problema iskanja najkrajše poti in podrobneje opišemo Dijkstrov algoritem in
algoritem BFS, ki predstavljata najpomembnejša predhodnika algoritma A*. V tretjem
poglavju predstavimo algoritem A*. Najprej omenimo zgodovino ter nastanek, nato pa
opišemo delovanje in lastnosti algoritma. Sledi opis vloge hevristične funkcije in njenih
lastnosti, nakar se osredotočimo na tri izbrane funkcije, ki smo jih uporabili v programu. V
nadaljevanju naloge opišemo postopek izdelave algoritma, od načrtovanja in priprave
mape do izdelave testne aplikacije. Nato prikažemo dobljene rezultate ter analiziramo
obnašanje algoritma z različnimi hevrističnimi funkcijami. Na koncu povzamemo delo.
3
2 Predstavitev algoritmov iskanja najkrajše poti
Iskanje najkrajše poti je eden izmed problemov teorije grafov [4]. Najkrajšo pot
dobimo tako, da poiščemo najmanjšo vsoto povezav med vozlišči v grafu. V primeru, ko
iščemo najkrajšo pot med točkama na površju, moramo točke površja predstaviti kot
vozlišča v grafu, povezave na površju pa kot povezave med vozlišči grafa. Zaradi
razgibanosti terena povezavam dodamo uteži, ki nam predstavljajo prehodnost terena.
Težje prehoden je teren, večjo utež damo povezavi, oziroma, če je teren neprehoden,
nastavimo utež na neprehodno. Največkrat uporabljeni algoritmi pri iskanju najkrajše poti
so:
• Dijkstrov algoritem [1, 3],
• Belmanov in Fordov algoritem [1],
• A* iskalni algoritem [1, 2, 3],
• Floyd-Warshallov algoritem [1] ter
• Johnsonov algoritem [1].
1.1 Dijkstrov algoritem
Algoritem je razvil Nizozemec Edsger Dijkstra leta 1959 [8]. Rešuje problem iskanja
najkrajše poti v usmerjenem grafu z nenegativnimi obtežitvami med povezavami in
zagotovo najde najkrajšo pot, če le-ta obstaja. Algoritem gradi seznam pregledanih vozlišč,
v katerem so vozlišča, ki predstavljajo najkrajšo pot od začetnega do trenutnega vozlišča.
Cena premika v naslednjo vozlišče je vsota uteži od začetnega do trenutnega vozlišča.
Slika 1 prikazuje delovanje algoritma v 2D prostoru. Vidimo začetno točko v črni barvi,
končno točko pa v rdeči. Črtice prikazujejo delovanje algoritma. Bolj je barva rumena, bolj
je točka oddaljena od začetne točke.
4
Slika 1: Delovanje Dijsktrovega algoritma na 2D mreži
1.2 Algoritem BFS
Algoritem BFS (angl. Best-First-Search) deluje na podoben način kot Dijkstrov, vendar
za ocenjevanje oddaljenosti do končne točke uporablja hevristično funkcijo [5]. Namesto
izbiranja točke, ki je bližje začetni, izbere tisto, ki je bližje končni točki poti. Algoritem
BFS ne zagotavlja najkrajše poti, vendar deluje po zaslugi hevristične funkcije veliko
hitreje kot Dijkstrov algoritem. Iz seznama nepregledanih točk vzame točko, potem s
pomočjo hevristične funkcije izračuna sosedom te točke oceno ter se premakne na točko z
najnižjo oceno. Na primer, če je končna točka južneje od trenutne točke, se algoritem
5
usmeri na poti, ki vodijo južno. Slika 2 prikazuje pot med začetno točko v črni barvi in
končno točko v rdeči, ki jo izračunamo s pomočjo algoritma BFS. Rumeni kvadratki so
točke z višjo hevristično oceno nadaljnje poti do končne točke, sive pa predstavljajo točke
z nizko hevristično oceno.
Slika 2:Delovanje algoritma BFS na 2D mreži
Algoritem BFS izgubi hitrost, ko imamo na poti ovire. Postane požrešen, saj preverja
vedno več točk tudi tedaj, ko ni na pravi poti. Ker algoritem samo ocenjuje pot do končne
točke in ne ocenjuje premika v naslednjo točko, se lahko premika v tisti smeri, ki je
najdaljša. Algoritem ne zagotavlja, da bo našel najkrajšo pot, je pa kljub temu zelo
pomemben, saj je podajanje informacije o smeri premika na način, ki ga uvaja ta algoritem,
osnova za delovanje mnogih drugih, zmogljivejših algoritmov.
6
Na slikah 3 in 4 sta prikazana Dijkstrov algoritem in algoritem BFS na mapi z ovirami.
Pri Dijkstrovem algoritmu so svetlejši kvadratki bolj oddaljeni od začetne točke, pri BFS
pa rumeni kvadratki pomenijo višjo hevristično oceno nadaljevanja poti do končne točke.
Slika 3:Delovanje Dijkstrovega algoritma na 2D mreži z oviro.
7
Slika 4:Delovanje algoritma BFS na 2D mreži z oviro.
8
3 Algoritem A*
1.3 Zgodovina algoritma A*
Iskalni algoritem A* je bil prvič opisan leta 1968, vendar ne v taki obliki, kot jo
poznamo danes [8]. Takrat se je imenoval algoritem A in je deloval samo na oceni premika
v naslednjo točko brez hevristične funkcije. Podoben je bil Dijkstrovemu algoritmu, vendar
je deloval na vseh ocenah, tudi na negativnih. Sedanja izvedba algoritma je sestavljena iz
ocene premika g(s), ki predstavlja oceno poti od trenutne v naslednjo točko ter hevristične
funkcije h(s), ki nam da dolžino poti od trenutne točke do končne točke. Ti dve oceni nam
predstavljata ocenitveno funkcijo f(s), na podlagi katere se algoritem odloča o naslednjem
vozlišču. Algoritem A* nam bo poiskal najkrajšo pot med začetno in končno točko, če ta
pot obstaja, in to naredil relativno hitro v primerjavi z ostalimi algoritmi.
1.4 Opis algoritma A*
Algoritem A* je algoritem, ki si za iskanje poti pomaga s hevristično funkcijo, kar
pomeni, da ne išče poti na slepo, ampak izračuna najboljšo smer za raziskovanje, kar ga
naredi tako fleksibilnega [6]. Osnovni gradniki algoritma so:
1. Graf – prostor kjer algoritem išče najkrajšo pot med začetno in končno
točko. Graf je lahko sestavljena iz objektov, ki so različnih oblik. Ločimo
jih glede na število robov objektov (štirikotni, šesterokotni, trikotni ...).
2. Vozlišče – struktura, ki predstavlja objekt na mapi in vsebuje informacije
za delovanje algoritma.
3. Ocenitvena funkcija sestavljata jo ocena premika, ki predstavlja dolžino
prepotovane poti in hevristična funkcija, ki predstavlja dolžino načrtovane
poti.
9
Graf vsebuje vozlišča, ki posredujejo informacijo o lokaciji vozlišča in povezave
med njimi. Ocenitveno funkcijo sestavljata ocena premika iz trenutne v naslednjo točko, ki
je dolžina prepotovane poti in hevristična funkcija, ki nam pove oceno od trenutne do
končne točke. Izračun ocenitvene funkcije je pomemben, saj nam predstavlja kakovost
premika, s tem pa tudi kakovost algoritma. V algoritem vključimo odprti in zaprti seznam.
Odprti seznam vsebuje vozlišča, ki še niso bila obiskana, zaprti pa vozlišča, ki so že bila
obiskana.
Zahtevnost algoritma A* je odvisna od hevristične funkcije. V najslabšem primeru je
zahtevnost eksponentna funkcija dolžine rešitve, ki predstavlja najkrajšo pot. Če
hevristična funkcija h(s) zadovoljuje pogoj |h(s) - h*(s)| ≤ O(log h*(s)), kjer je h*(s)
optimalna hevristična funkcija ali natančna ocena poti od s do končne točke, potem je
časovna zahtevnost algoritma polinomska. Povedano z drugimi besedami, napaka
hevristične funkcije ne sme rasti hitreje od logaritma optimalne hevristične funkcije, da
vrne pravo razdaljo od s do končne točke [2].
Pri napravah, ki so omejene s pomnilnikom, pa je pomembna tudi prostorska
zahtevnost. V najslabšem primeru je zveza med dolžino rešitve in številom točk, ki si jih
moramo zapomniti, eksponentna. Rešitve se pojavijo v razširitvi algoritma A* z različnimi
imeni kot so: IDA* (angl. iterative deepening A*), MA* (angl. Memory bounded A*),
SMA* (angl. simplified memory bounded A*) [8].
Pri iterativnem poglabljanju (IDA*) in SMA* hitro dobimo približek rešitve, ki ga
kasneje, če imamo čas, izboljšujemo. Princip je v tem, da omejimo ocenitveno funkcijo f.
Točke s preveliko vrednostjo f ne dodajamo v odprti seznam. V naslednjih ciklih se
povečuje število točk v odprtem seznamu, pri čemer pa opazujemo, ali se cena poti
izboljšuje. Prednost je, da hitro dobimo približek poti in porabimo sorazmerno malo
spomina [10].
Če je hevristična funkcija sprejemljiva, kar pomeni, da je ocena od trenutne do
končne točke točna, potem pomeni, da je A* optimalen algoritem. Če se uporablja zaprta
množica, ki je množica omejenih točk, potem mora biti hevristična funkcija monotona, da
10
bo A* optimalni algoritem. Hevristična funkcija je monotona, če imamo povezave točk od
A do C in od A do B do C, potem bo ocena A do C vedno manjša ali enaka vsoti ocen od A
do B in od B do C. Monotonost je enaka trikotniški neenakosti. Za vse y, ki so sosedi x,
mora veljati g(x)+h(x) <= g(y)+h(y).
Psevdokod algoritma A*
1. P – začetno vozlišče
2. Izračunamo f ( f = g + h) za P.
3. Dodamo P v odprti seznam.
4. Vzamemo B iz odprtega seznama (B je vozlišče z najmanjšo vrednostjo f).
- Če je B enak končnemu vozlišču, potem izhod (pot je najdena).
- Če je odprti seznam prazen, potem izhod (poti ni mogoče najti).
5. Za vsakega soseda S vozlišča B ponavljamo:
- Izračunamo f vozlišča S.
- Če je S v odprtem ali zaprtem seznamu
o Če ima S nižjo oceno f, potem prepišemo oceno f in starša,
o drugače dodamo v odprti seznam.
6. B prestavimo iz odprtega v zaprti seznam. Ponavljamo od točke 4, dokler ne
pridemo do končne točke.
Slika 5 nam prikazuje delovanje algoritma A* v 2D prostoru. Začetno točko nam
prikazuje moder kvadrat, končno pa rdeč. Sivi kvadrati nam predstavljajo neprehodno
območje. Vsak kvadrat ima zapisan rezultat ocenitvene funkcije zgoraj levo, ki je seštevek
obeh ocen premika. Spodaj levo je zapisana ocena premika od začetne točke, spodaj desno
pa hevristična ocena do končne točke. Puščice kažejo na starša, kvadrati obrobljeni z
zeleno in rumenim krogom pa nam predstavljajo najdeno pot.
11
Slika 5: Delovanje algoritma A* v 2D prostoru
12
1.5 Hevristične funkcije
Hevristična funkcija h(s) pove algoritmu približek minimalne ocene poti od vsake točke
s do končne točke. Za algoritem je zelo pomembna izbira hevristične funkcije. Hevristična
funkcija se uporablja za vodenje algoritma. Glede na dobljen rezultat funkcije lahko
sklepamo o hitrosti in pravilnosti algoritma.
• Če je hevristična funkcija 0 (h(s) = 0), potem algoritem deluje samo z oceno
premika, kar ga spremeni v Dijkstrov algoritem.
• Če je h(s) vedno manjši ali enak oceni premika od s do končne točke, potem
zagotovo algoritem najde najkrajšo pot.
• Če je h(s) vedno enak oceni premika od s do končne točke, potem algoritem
sledi najboljši poti in ne pregleduje nepotrebnih vozlišč, kar naredi
algoritem hitrejši.
• Če je h(s) včasih večji od ocene premika od s do končne točke, potem A* ne
zagotavlja, da najde najkrajšo pot.
• Če je h(s) vedno večji od ocene premika od s do končne točke, potem se A*
spremeni v algoritem BFS.
Po ugotovitvi, kaj želimo od algoritma, lahko glede na razmerje med oceno premika in
hevristično oceno to tudi dosežemo. Če hočemo hiter algoritem, mora biti razmerje čim
manjše, če pa hočemo zelo natančen algoritem, razmerje povečamo. V nalogi bomo opisali
tri najbolj znane hevristične funkcije.
1.5.1 Razdalja Manhattan
Oceno dobimo tako, da seštejemo vsa vozlišča od trenutnega do končnega, pri čemer se
premikamo samo vodoravno in navpično, izpustimo vse diagonalne premike ter ne
upoštevamo nobenih neprehodnih območij. V (3.1) nam n pomeni trenutno točko
končnaTočka pa je končna točka. Slika 5 prikazuje premike, dobljene s pomočjo
13
hevristične funkcije razdalja Manhattan. Rumeni kvadratki pomenijo nižjo oceno, črni pa
višjo.
h(n) = abs(n.x – končnaTočk.x) + abs(n.y – končnaTočka.y) (3.1)
Slika 6:Delovanje algoritma na 2D mreži ob uporabi hevristične funkcije razdalja Manhattan.
1.5.2 Diagonalna razdalja
Če na mapi omogočamo diagonalne premike, potem moramo izbrati drugačno
hevristično funkcijo. Funkcija sešteva vse, tako diagonalne kot vodoravne in navpične
premike. Oceno dobimo tako, da vzamemo največjo absolutno razliko med koordinatama
trenutne in končne točke (3.2). Slika 6 nam prikazuje premike s pomočjo hevristične
funkcije diagonalna razdalja.
14
h(n) = max ( abs( n.x - končnaTočka.x ), abs( n.y - končnaTočka.y ) ) (3.2)
Slika 7:Delovanje algoritma na 2D mreži ob uporabi hevristične funkcije diagonalna razdalja.
1.5.3 Evklidska razdalja
Ko je v mapi omogočeno, da se lahko premikamo v katerikoli smeri, lahko uporabimo
evklidsko razdaljo, ki nam kot rezultat vrne kvadratni koren kvadriranih razlik koordinat
trenutne in končne točke (3.3). Pri uporabi te funkcije imamo lahko probleme, saj je
evklidska razdalja vedno manjša od razdalje, dobili bomo najkrajšo pot, vendar bo
algoritem porabil več časa. Slika 7 prikazuje premike s pomočjo hevristične funkcije
evklidske razdalje.
15
h(n) = sqrt( (n.x – končnaTočka.x)2 + (n.y – končnaTočka.y)2 ) (3.3)
Slika 8: Delovanje algoritma na 2D mreži ob uporabi hevristične funkcije evklidska razdalja.
16
4 Načrtovanje algoritma za iskanje najkrajše poti med
točkama površja
V tem poglavju bomo opisali razvoj, ugotovitve in načine, kako smo se lotili izdelave
algoritma. Algoritem mora na podlagi danih točk grafa, začetne in končne točke izračunati
najoptimalnejšo pot ter jo vrniti v predpisani obliki, da se lahko potem pot prikaže.
1.6 Priprava mape
Podatke o terenu lahko dobimo iz različnih virov. Lahko je to višinska slika ali
tekstovna datoteka. Zaradi možnosti uporabe različnih virov smo naredili javno funkcijo,
ki dodaja točko za točko v strukturo, kjer so zapisane vse informacije o točkah. Strukturo
smo poimenovali vozlišče ter ji dodali naslednje parametre:
- koordinati točke,
- višinsko koordinato,
- status za prehodnost ali neprehodnost,
- starša,
- status, v katerem seznamu se točka nahaja (odprt, zaprt), in
- oceno premika.
Površje smo predstavili v vektorju, v katerega dodajamo vozlišča. Pomembno pri
postavitvi terena je, da dobimo meje terena, da jih v nadaljevanju ne prekoračimo in da
vsako točko enolično označimo s takimi parametri, da do nje lahko dostopamo. Po vnosu
vseh točk moramo izbrati še začetno in končno točko, med katerima želimo določiti
najkrajšo pot.
17
1.7 Implementacija
1.7.1 Algoritem A*
Po uspešnem vnosu terena in preverjanju začetnega in končnega vozlišča se začne
izvajati algoritem. Najprej začetno vozlišče vstavimo v odprti seznam. Potem ponavljamo
naslednje korake, dokler imamo v odprtem seznamu kakšen element.
1. V vsakem koraku uredimo odprti seznam tako, da je vozlišče z najmanjšo oceno
premika na prvem mestu.
2. Vzamemo prvo vozlišče iz odprtega seznama in ga določimo kot trenutnega.
3. Če je trenutno vozlišče enako končnemu, zaključimo algoritem.
4. Drugače vse sosede vozlišča, ki imajo status prehoden in niso v zaprtem
seznamu, vstavimo v odprti seznam, jim določimo za starša trenutno vozlišče in
izračunamo ocene premika od trenutnega vozlišča. Če je sosednje vozlišče že v
odprtem seznamu, moramo pogledati, če je ocena premika manjša. V tem
primeru nastavimo starša na trenutno vozlišče in zamenjamo oceno premika v
tej smeri.
Ko algoritem pride do končnega vozlišča, se rekonstruira pot. Vzamemo končno točko,
jo damo v vrsto, vzamemo starša končni točki in ga damo v vrsto. To ponavljamo, dokler
starš ni začetna točka.
Oceno premika izračunamo s pomočjo ocene premika v smeri naslednje točke in
hevristične ocene premika od trenutne do končne točke. Za oceno premika v smeri
naslednje točke smo določili konstanti. Za vodoravni in navpični premik smo določili
konstanto 10, za diagonalni pa 14. Konstanti smo pomnožili z absolutno razliko med
višinskima koordinatama teh dveh točk. Za izračun hevristične ocene smo dali uporabniku
na izbiro tri hevristične funkcije. Te so razdalja Manhattan, diagonalna razdalja in
evklidska razdalja. Možnost izbire hevristične funkcije se dopušča zato, ker nekje deluje
bolje ena funkcija, drugje pa druga.
Za odprti seznam smo uporabili v programskem jeziku C++ vgrajene strukture, ki jih
lahko urejamo. V vsakem koraku elemente seznama urejamo v naraščajočem vrstnem redu
18
glede na seštevek ocene premika v smeri nasledjne točke in hevristične ocene od trenutne
do končne točke, da ne porabljamo časa z iskanjem naslednje točke.
V nadaljevanju algoritma pregledamo vse sosede trenutne točke. Ker vemo koordinati
točke x in y, lahko s prištevanjem in odštevanjem k tem koordinatam dobimo vseh 8
sosedov. Pri tem moram preverjati, da ne prestopim mej mape, kajti če je točka na robu,
potem ima samo tiste sosede, ki obstajajo. Za vsakega soseda, ki ni na zaprtem seznamu in
je ta sosed na območju, ki je prehodno, je potrebno potem izračunati oceno premika v tej
smeri. To izračunamo s prej omenjenim postopkom. Če točka ni na odprtem seznamu, mu
pripišemo potrebne parametre, za starša mu nastavimo trenutno točko ter ga vstavimo na
odprti seznam. Če pa je sosed na odprtem seznamu, mu izračunamo oceno premika v tej
smeri in če je manjša kot je bila prejšnja ocena, mu pripišemo sedanjo oceno, starš tega
soseda pa je trenutna točka. Algoritem ponavlja postopek, dokler trenutna točka ni enaka
končni točki ali pa dokler odprti seznam ni prazen.
Po končanem algoritmu se z vračanjem prebere dobljena pot, ki se vstavlja v seznam.
Pot dobimo tako, da zadnjo točko vstavimo v seznam, pogledamo starša tej točki in tako
dolgo iščemo starša naslednji točki, da ne pridemo do začetne točke algoritma.
1.7.2 Hevristične funkcije
Hevristične funkcije smo implementirali v metodi, ki računa hevristično oceno premika
od trenutne do končne točke. Kot vhodne parametre prejme indekse točk, kot izhod pa vrne
hevristično oceno za dane parametre. Vhodna parametra sta točki, od katere pa do katere
računamo oceno. V algoritmu računamo oceno od trenutne točke do končne. V sami
funkciji najprej preko indeksov dostopimo do koordinat točk, nato pa glede na izbiro
hevristične funkcije izračunamo oceno premika. Ker celoten algoritem deluje na mapi, za
izračun ocene uporabljamo samo koordinati x in y.
1.7.3 Testna aplikacija
Ker algoritem kot samostojni program vrne rezultate v določeni strukturi in ob veliko
podatkih te rezultate težko primerjamo, smo izdelali testno aplikacijo, ki nam podano mapo
prikaže v tridimenzionalni obliki in z barvo označi pot, ki jo algoritem izračuna. Testno
19
aplikacijo smo izdelali v programskem jeziku C# s Framework 2.0 in knjižnicami DirectX.
Omejili smo se na prikaz terena, dobljenega z višinskimi slikami v bitni obliki. Višinsko
sliko naložimo v metodi LoadHeightData, ki prebere višino in širino slike in zaporedoma
vstavlja koordinate v dvodimenzionalno polje.
Slika 8 prikazuje površje v testni aplikaciji. Za izris poti na prikazanem površju smo
morali točke poti prebrati iz tekstovne datoteke, ki jo je algoritem ustvaril ob končanem
postopku. Po prebiranju poti iz datoteke se v metodi določanja točk določi barva glede na
to, ali je ta točka na poti ali ne. Če je točka del poti, se ji dodeli roza barva.
Slika 9: Prikaz površja s testno aplikacijo
20
1.7.4 Volos
Volos je program, ki omogoča čimbolj realističen prikaz pokrajine in objektov ob
uporabi obstoječe strojne opreme srednjega razreda. Kot podlaga za zgradbo pokrajine
uporablja digitalni model reliefa, hkrati pa omogoča določanje geometrije pokrajine preko
zunanjega urejevalnika. Poleg prikazovanja pokrajine sistem omogoča prikazovanje drugih
objektov, ki jih najdemo na površju (hiše, drevesa, daljnovodi, ...). Volos omogoča tudi
realističen prikaz gibajočih se objektov, pogled istega objekta iz več različnih kotov in
možnost simulacije krmiljenja naprav preko posebnih uporabniških vmesnikov [12].
21
5 Analiza in rezultati
V tem poglavju bomo podali rezultate in ugotovitve diplomske naloge. Rezultati se
navezujejo na hitrost algoritma glede na izbiro hevristične funkcije. Dobljeni rezultati so
bili pridobljeni na dveh mapah v velikosti 128 točk × 128 točk in 900 × 900 točk. Nazadnje
bomo podali rezultate, dobljene na digitalnem reliefu Slovenije, v katerem je okoli
2.127.000 višinskih točk. Vse rezultate smo pridobivali z izvedljivim programom,
prevedenim v produkcijskem (ang. release) načinu.
Prva implementacija algoritma brez sprememb je, kot je bilo predvideno, bila zelo
počasna in je za realno reševanje problema bila neuporabna. Kot ozko grlo se je pojavil
del, kjer smo iz mape iskali točko. Pri mapi 128 ×128 točk je izračun najkrajše poti s
hevristično funkcijo Manhattan trajal 8 sekund, pri mapi 900 × 900 točk pa 20 sekund. S
hevristično funkcijo diagonalne razdalje je izračun pri mapi 128 × 128 točk trajal 8
sekund, pri mapi 900 × 900 točk pa 21 sekund. Pri evklidski razdalji je program potreboval
za manjšo mapo 10 sekund za večjo pa 24 sekund. Za vsa merjenja smo vzeli za začetno
točko (0, 0) za končno pa točko z največjima koordinatama x in y.
Slike od 9 do 11 prikazujejo najdeno pot z osnovnim algoritmom na mapi 128 × 128
točk brez izboljšav in s tremi različnimi hevrističnimi funkcijami. Kot vidimo, so poti
različne. Vendar algoritem s spreminjanjem hevristične funkcije ni deloval hitreje, saj je
pri vsaki rešitvi našel pot, v kateri je bilo enako število točk (222), pri tem pa je tudi
pregledal enako število točk (223).
22
Slika 10: Izris poti, dobljene s hevristično funkcijo razdalje Manhattan z algoritmom brez izboljšav in brez upoštevanja višinske komponente.
Slika 11: Izris poti, dobljene s hevristično funkcijo diagonalne razdalje z algoritmom brez izboljšav in brez upoštevanja višinske komponente.
23
Slika 12:Izris poti, dobljene s hevristično funkcijo evklidske razdalje z algoritmom brez izboljšav in brez upoštevanja višinske komponente.
Hevristično funkcijo smo pomnožili z absolutno razliko višinske koordinate trenutne in
končne točke. V enačbah 5.1, 5.2 in 5.3 nam s predstavlja trenutno točko končnaTočka pa
končno točko.
h(s) = abs( s.x – končnaTočka.x) + abs ( s.y – končnaTočka.y) * abs ( s.z – končnaTočka.z) (5.1)
h(s) = max ( abs(s.x –končnaTočka.x) , abs(s.y – končnaTočka.y) ) * abs (s.z – končnaTočka.z ) (5.2)
h(s) = sqrt ( (s.x – končnaTočka.x)2 + (s.y – končnaTočka.y) 2 ) * abs (s.z – končnaTočka.z) (5.3)
Na slikah 12 do 20 je pot označena z roza barvo, pregledane točke pa so označene z
modro. Pri delovanju algoritma s hevristično funkcijo razdalje Manhattan (slika 12) pot
vsebuje 261 točk, algoritem pa jih je pregledal 5318.
24
Slika 13:Izris poti, dobljene s hevristično funkcijo razdalje Manhattan in z upoštevanjem višinske komponente.
Če pri enakih vrednostih parametrov poizkušamo s hevristično funkcijo diagonalne
razdalje (slika 13), dobimo naslednje rezultate. Število točk v poti je 261, pregledali pa
smo 4893 točk. Kot vidimo, smo pregledli manj točk, kar pa pomeni tudi hitrejše delovanje
algoritma. Iz slike (slika 13) se vidi, da je algoritem izbral pot v drugi smeri, kot pri
uporabi hevristične funkcije razdalje Manhattan (slika 12).
25
Slika 14: Izris poti, dobljene s hevristično funkcijo diagonalne razdalje in z upoštevanjem višinske komponente.
26
Enak preizkus smo naredili tudi za hevristično funkcijo evklidska razdalja (slika 14).
Število točk v poti je bilo 287, pregledali pa smo jih 5114. Kot vidimo, je algoritem s
hevristično funkcijo evklidska razdlja pregledal največ točk.
Slika 15: Izris poti, dobljene s hevristično funkcijo evklidske razdalje in z upoštevanjem višinske komponente. .
Po dobljenih rezultatih lahko sklepamo, da je hevristična funkcija preslaba, saj nam
algoritem pregleda preveč točk, kar ga upočasni. Vidi se tudi, da se hevristična funkcija
preveč odloča glede na višino. Če hočemo prepotovati neko pot v naravi, se odločamo o
smeri glede višine iz trenutne v naslednjo točko in ne iz trenutne do končne, kot je delovala
sedanja hevristična funkcija. To poskušamo realizirati tako, da absolutno razliko višine
med trenutno in naslednjo točko pomnožimo z oceno premika iz trenutne v naslednjo točko
(enačbi 5.4 in 5.5). Hevristične funkcije ostanejo enake kot v prejšnjem poizkusu.
g(s) = abs(s.z – s+1.z) * 10 za navpične in vodoravne premike (5.4)
g(s) = abs(s.z – s+1.z) * 14 za diagonalne premike (5.5)
27
Za hevristično funkcijo razdalja Manhattan (slika 15) algoritem pregleda 835 točk in
najde pot, v kateri je 311 točk. Za hevristično funkcijo diagonalne razdalje (slika 16)
algoritem pregleda 1295 točk, najde pa pot, v kateri je 255 točk. Pri hevristični funkciji
evklidska razdalja (slika 17) algoritem najde pot z 292 točkami, pri tem pa pregleda 859
točk.
Slika 16: Izris poti, dobljene z upoštevanjem višinske komponente in z dopolnitvijo hevristične funkcije razdalje Manhattan
28
Slika 17: Izris poti dobljene z upoštevanjem višinske komponente in z dopolnitvijo hevristične funkcije diagonalne razdalje
Slika 18: Izris poti dobljene z upoštevanjem višinske komponente in z dopolnitvijo hevristične funkcije evklidske razdalje
29
Kot vidimo iz rezultatov, nam je ta izboljšava prinesla pohitritev algoritma, ker je
pregledal manj točk, vendar pa se je zato zvečalo število točk v najdeni poti. V naslednjem
preizkusu smo razširili hevristične funkcije s tretjo koordinato. Hevristična funkcija vrne
oceno premika od trenutne do končne točke z absolutnimi razlikami vseh treh koordinat x,
y, z (enačbe 5.6, 5.7 in 5.8). Ocena premika iz trenutne v naslednjo točko je ostala enaka
kot v prejšnjem primeru.
h(s) = abs( s.x – končnaTočka.x) + abs ( s.y – končnaTočka.y) + abs ( s.z – končnaTočka.z) (5.6)
h(s) = max ( abs(s.x –končnaTočka.x) , abs(s.y – končnaTočka.y) ) + abs (s.z – končnaTočka.z ) (5.7)
h(s) = sqrt ( (s.x – končnaTočka.x)2 + (s.y – končnaTočka.y) 2 + abs (s.z – končnaTočka.z)2 ) (5.8)
Po tej spremembi nam algoritem s hevristično funkcijo razdalja Manhattan (slika 18) vrne pot z 241 točkami, pregleda pa 417 točk. Pri delovanju s hevristično funkcijo diagonalna razdalja (slika 19) pregleda 1218 točk in vrne pot z 236 točkami. Za delovanje s hevristično funkcijo evklidska razdalja pa pregleda 276 točk in vrne pot z 222 točkami.
Slika 19: Izris poti, dobljene s hevristično funkcijo razdalje Manhattan in z vključevanjem višinske komponente brez
obtežitve
30
Slika 20: Izris poti, dobljene s hevristično funkcijo diagonalne razdalje in z vključevanjem višinske komponente brez obtežitve
Slika 21: Izris poti, dobljene s hevristično funkcijo evklidske razdalje in z vključevanjem višinske komponente brez obtežitve
31
Povzamemo spreminjanje hevristične ocene. Prva sprememba je bila množenje
hevristične funkcije z absolutno razliko med trenutno in končno točko. Druga sprememba
je bila množenje premika iz trenutne točke v naslednjo z absolutno razliko med tema
točkama, tretja pa dodajanje absolutne razlike med trenutno in končno točko v hevristično
funkcijo. V Tabeli 1 prikažemo zbrane rezultate v odstotkih, ki jih dobimo, če delimo
število točk v poti s številom pregledanih točk.
Tabela 1: Rezultati učinkovitosti algoritma na mapi 128 × 128 točk, glede na število pregledanih točk in številom točk v poti
Sprememba\Hev. fun. Razdalja Manhattan Diagonalna razdalja Evklidska razdaljaSprememba 1 0,4% 0,5% 0,5%Sprememba 2 39% 19% 26%Sprememba 3 57% 19% 80%
Kot vidimo iz tabele, se je najbolje odrezala hevristična funkcija evklidske razdalje s tretjo
spremembo.
32
6 Sklep
Algoritem A* je zelo razširjen pri iskanju poti v igrah in na terenu. Od njegovih
predhodnikov se razlikuje v tem, da poti ne išče na slepo, ampak s pomočjo hevristične
funkcije dobi približno smer poti. Zaradi njegove prilagodljivosti, ki jo dosežemo s
hevristično funkcijo, lahko algoritem dobro deluje na različnih mapah.
Algoritem smo razvili z namenom vključitve v programsko okolje Volos [12].
Implementirali smo ga kot knjižnico v programskem jeziku C++. Nalogo smo pričeli s
pregledom obstoječih rešitev problema iskanja najkrajše poti med dvema točkama ter
nekatere tudi opisali. V nadaljevanju smo opisali algoritem A* ter podali njegove lastnosti.
Opisali smo postopek implementacije, omenili pomen hevrističnih funkcij in s pomočjo
testne aplikacije prikazali dobljene rezultate.
Ob zaključku lahko povemo, da je algoritem A* res uporaben, hiter in prilagodljiv, kar
smo lahko videli iz rezultatov testne aplikacije in samega programa Volos, kjer je vključen.
33
LITERATURA
[1] Cormen, T. H., C. E. Leiserson, R. L. Rivest, C. Stein, »Introduction to
Algorithms«, MIT Press in McGraw-Hill, London, 2001.
[2] Russell, S.J., P. Norvig, »Artifical Intelligence: A Modern Approach«, Prentice
Hall, Englewood Cliffs, New Jersey, 2000.
[3] Shapiro Stuard C. »Encyclopedia of Artificial Intelligence«, John Wiley &
Sons, New York, 1992.
[4] Nilsson J. Nils »Artificial intelligence A new synthesis«, Morgan Kaufmann, Hong
Kong, 1998.
[5] http://www-cs-students.stanford.edu/~amitp/gameprog.html#paths (22.09.2008).
[6] http://www.policyalmanac.org/games/aStarTutorial.htm (22.09.2008).
[7] http://en.wikipedia.org/wiki/Shortest_path_problem (22.09.2008).
[8] Hart, P. E., Nilsson, N. J., Raphael, B., »A Formal Basis for the Heuristic Determination of Minimum Cost Paths« 1968, IEEE Transactions on Systems Science and Cybernetics SSC4 (2): pp. 100–107
[9] E. W. Dijkstra »A note on two problems in connexion with graphs«, (1959),
pp. 269–271.
[10] http://luks.fe.uni-lj.si/sl/studij/SUIS/seminarji/gradb/toc.htm (22.09.2008).
34
[11] http://www.riemers.net/eng/Tutorials/DirectX/Csharp/Series1/tut8.php
(22.09.2008).
[12] http://gemma.uni-mb.si/volos/index_SI.html (22.09.2008).