Kas ir A* algoritms? Definīcija, darbības princips un piemēri
Uzzini, kas ir A* algoritms, kā tas atrisina īsākā ceļa meklēšanu, darbības princips, heuristikas piemēri un salīdzinājums ar Dijkstra un Floida–Varšala.
A* ir soļu kopums (algoritms), ko datori var izmantot, lai noteiktu, kā ātri nokļūt no vienas vietas uz otru. Ja jums ir saraksts ar vietām un to, cik grūti ir nokļūt no vienas vietas uz otru, izmantojot A*, jūs varat ātri atrast ātrāko ceļu. Tas ir saistīts ar Dijkstras algoritmu, bet veic gudrus minējumus, lai tas netērētu tik daudz laika, mēģinot atrast lēno ceļu. Tā ir laba soļu sērija, ja vēlaties tikai ceļu starp divām vietām. Ja vēlaties uzzināt daudzus ceļus no vienas kartes, tad ir ātrāki veidi, kas atrod visas atbildes uzreiz, piemēram, Floida-Varšala algoritms. A* nedarbosies, ja vienā ceļojumā vēlaties apmeklēt vairākas vietas (ceļojošā pārdevēja problēma).
Kopsavilkums — kas tas ir un kāpēc tas darbojas
A* ir grafu meklēšanas algoritms, kas meklē optimālu ceļu no sākuma stāvokļa līdz mērķim, izmantojot divu veidu informāciju:
- g(n) — faktiskās izmaksas no starta līdz mezglam n;
- h(n) — heurstika (aptuvenās) izmaksas no mezgla n līdz mērķim.
A* izvērtē funkciju f(n) = g(n) + h(n). Tas paplašina mezglus ar zemāko f(vērtību), kas ļauj ātri koncentrēties uz daudzsološākajiem ceļiem un izlaist acīmredzami sliktus virzienus.
Kā A* darbojas — soli pa solim
- Sāk ar atvērtu sarakstu (open set), kurā ir starta mezgls ar g=0 un f=h(start).
- Kamēr atvērtais saraksts nav tukšs:
- Izvēlas mezglu n no atvērta saraksta ar mazāko f(n).
- Ja n ir mērķis — rekonstruē ceļu un beidz meklēšanu.
- Citādi, pārvieto n uz slēgto sarakstu (closed set) un apskata visus n blakusesošos mezglus.
- Katrai blakussaiņotajai virsotnei m aprēķina jaunu iespējamo g vērtību (g(n)+izmaksas(n→m)). Ja šī g vērtība ir labāka, atjauno m g, f un atzīmē n kā priekšteci; ja m nav atvērtajā sarakstā, pievieno to.
Svarīgi jēdzieni
- Heuristika (h): aptuvenā attāluma novērtējums līdz mērķim. Lai A* garantētu optimālu risinājumu, heuristika ir jābūt admissible (nepārvērtē reālo minimālās izmaksas) — piemēram, tīram attālumam kā heurstika nekad nevajadzētu būt lielākam par īsto ceļa izmaksu.
- Konsistence (monotonicitāte): heuristika ir konsistentā, ja h(n) ≤ cost(n,m) + h(m) katram n→m. Konsistence nodrošina, ka reiz apmeklēts mezgls vairs netiks "labots" vēlāk, kas uzlabo efektivitāti.
- Optimalitāte: ar admissible heurstiku A* atrod optimālu ceļu.
- Pilnība: ar derīgu heurstiku un galīgu grafu A* atradīs risinājumu, ja tas eksistē.
Piemēri un bieži lietojuma gadījumi
- Ceļa meklēšana režģī (piemēram, spēļu, robotikas maršrutēšana). Bieži izmantotā heuristika ir Manhattan distance (ja kustības tikai četros virzienos) vai Euklida distance (ja atļautas diagonāles).
- Robotikas un autopilota maršrutēšana, grafu ceļu plānošana, kartēšanas risinājumi.
- Tīklošana un maršrutēšanas problēmas, kur nepieciešams ātrs optimāls maršruts starp diviem punktiem.
Salīdzinājums ar citiem algoritmiem
- Dijkstras algoritms: Dijkstra ir A* īpašs gadījums, kad heuristika h(n)=0 visiem n. Dijkstra garantē īsāko ceļu, taču parasti prasa vairāk laika, jo neizmanto mērķa virziena informāciju.
- Floyd–Warshall / visi-pāru algoritmi: ja vajag atrast ceļus starp visiem pāriem, tie var būt efektīvāki. A* ir labāks, ja meklējat ceļu tikai starp diviem punktiem.
- Ceļojošā pārdevēja problēma: A* nav piemērots vienā braucienā apmeklēt vairākas adreses optimāli — tam ir speciāli koģinājumi un heuristikas, bet TSP ir citāda rakstura problēma (saite).
Trūkumi un praktiskie ierobežojumi
- Atmiņas patēriņš: A* glabā atvērto un slēgto mezglu kopas, kas var prasīt daudz atmiņas ļoti lielos grafos.
- Heuristikas kvalitāte: ja heuristika ir slikta (pārlieku zema vai 0), A* var būt lēns kā Dijkstra; ja heuristika pārvērtē, A* var zaudēt optimalitāti.
- Nefektīvs, ja jāapmeklē daudz mērķu vienā ceļojumā — tam ir piemērotāki speciāli algoritmi vai apstrādes paņēmieni.
Varianti un uzlabojumi
- Weighted A*: paaugstina heurstiku ar svaru w>1, kas samazina meklēšanas laiku, taču var zaudēt optimalitāti.
- IDA* (iterative deepening A*): izmanto mazāk atmiņas, veicot iteratīvu dziļuma ierobežojumu meklēšanu ar f-robežām.
- D* (Dynamic A*): pielāgojas, ja grafā mainās izmaksas — noderīgs dinamiskā vidē (robotika).
- Uzlabojumi maršrutēšanai lielos reālos tīklos: landmarks, contraction hierarchies, multi-level grafi utt.
Praktisks piemērs (vienkāršs)
Iedomāsimies 2D režģi, kur kustamies pa četriem virzieniem, katra pāreja izmaksā 1. Ja sākums ir (0,0) un mērķis (5,3), visvienkāršākā admissible heuristika ir Manhattan distance: h(x,y) = |x-5| + |y-3|. A* sāksies pie (0,0) ar f = g(0,0)+h = 0 + 8, un pakāpeniski paplašinās pozīcijas, kuras samazina f, līdz atradīs optimālo ceļu.
Nobeigums
A* ir spēcīgs un elastīgs algoritms optimālu ceļu meklēšanai starp diviem punktiem, ja pieejama laba heuristika. Tas kombinē īsto izmaksu informāciju ar prognozēm par atlikušajām izmaksām, tādēļ bieži vien daudz ātrāk atrod risinājumu nekā neheuristiskie meklēšanas algoritmi. Tomēr jāņem vērā atmiņas prasības un tas, ka A* nav labākais rīks problēmām, kur jāapmeklē daudzi mērķi vai jārisina speciālas kombinatoriskas optimizācijas problēmas.
Soļi
A* vispirms ir nepieciešams saraksts ar visām vietām, uz kurām var aizbraukt, un pēc tam - saraksts, cik tālu ir ceļš starp tām. Pēc tam tas jums pateiks ātrāko ceļu, kā nokļūt no vietas A uz vietu Z.
Piemēram, teiksim, ka A ir savienots ar vietām B un C, un B un C ir savienoti ar D un E. D un E ir savienoti ar Z. Ir četri iespējamie ceļi, kā nokļūt no A uz Z. Jūs varat doties A-B-D-Z, A-C-D-Z, A-B-E-Z vai A-C-E-Z. Dators, kas izmanto A*, vispirms aplūko, cik grūti ir nokļūt no A uz B un no A uz C. Tās ir šo vietu "izmaksas". Vietas izmaksas nozīmē, cik grūti ir nokļūt no A uz šo vietu. Pēc abu izmaksu pierakstīšanas dators noskaidro, cik grūti ir nokļūt no B uz D, un pieskaita to B izmaksām. Tas pieraksta to kā D izmaksas. Tad dators paskatās, cik grūti ir nokļūt no C uz D, un pieskaita to C izmaksām. Tās ir citas D izmaksas, un, ja tās ir mazākas par jau esošajām, tas nomaina vecās izmaksas. Dators vēlas zināt tikai labāko ceļu, tāpēc tas ignorē ceļu ar lielākām izmaksām. Tas atcerēsies tikai vienu no A-B-D un A-C-D, atkarībā no tā, kurš ir ātrāks.
Dators dodas tālāk un atrod ātrāko ceļu uz E. Visbeidzot, tas dodas no D uz Z un atrod izmaksas, un no E uz Z un atrod izmaksas. Tas iegūst galīgās Z izmaksas, un tās ir vismazākās izmaksas, ko tas var iegūt. Tagad dators zina, kurš ceļš ir ātrākais, un tam ir atbilde. Dators var veikt līdzīgu soļu virkni, bet ar daudz vairāk vietām. Katru reizi tas apskatīs vietu, kas ir vistuvāk A, un saskaitīs izmaksas šīs vietas kaimiņiem.
Iepriekš minēto soļu virkni sauc par Dijkstras algoritmu. Dijkstras algoritms var būt lēns, jo tas aplūko daudzas vietas, kas no Z var atrasties nepareizā virzienā. Ja datoram jautātu, kā nokļūt no vienas pilsētas uz tuvējo pilsētu, Dijkstras algoritms varētu beigties ar meklēšanu citā valstī.
A* atrisina šo problēmu. A* ļauj datoram norādīt, cik tālu būs no katras vietas līdz galam. Dators var izmantot šo minējumu, lai aptuveni noteiktu, cik tālu būs jānoiet no konkrētas vietas līdz Z. Tā vietā, lai izvēlētos tikai vietu, kas ir vistuvāk A, dators apskatīs to, kurā, iespējams, būs mazākais kopējais attālums. Šo kopsummu tā atrod, pieskaitot izmaksas paredzamajam atlikušajam attālumam. Šādā veidā tas var meklēt tikai virzienā, kurā situācija, iespējams, uzlabosies. Nekas, ja minējums nav perfekts, taču pat vienkāršs slikts minējums var padarīt programmu daudz ātrāku. Ja mēģināt atrast ceļu starp divām vietām reālajā pasaulē, labs minējums ir tikai attālums starp tām taisnā līnijā. Reālais ceļš pa ceļiem būs garāks, bet tas ļauj programmai to uzminēt, un tā neies nepareizā virzienā.
Matemātikas vai datorzinātņu literatūrā šis minējums bieži vien ir vietas funkcija, un to sauc par heiristiku. Katra vieta ir virsotne, un katrs ceļš starp divām vietām ir mala. Tie ir vārdi no grafu teorijas.
Meklēt