Teekonnaotsingu algoritmide visualiseerija

vaata, kuidas erinevad otsingualgoritmid võistlevad samal ruudustikul, rinne rinde järel

Interaktiivse simulatsiooni laadimine...

Õppetund

Teooria — Teekonnaotsingu algoritmide visualiseerija

Kolm rippmenüü neljast algoritmist on üks ja sama algoritm. Need kõik järjestavad uurimist ootavad ruudud ühe avaldisega f(n) = g(n) + h(n) — seni läbitud maksumus pluss eeldatav järelejäänud maksumus — ning erinevad vaid selle poolest, kumb kahest liidetavast alles jäetakse. Jäta h ära ja saad Dijkstra algoritmi. Eira g-d ja saad Greedy Best-Firsti. Neljas, laiuti otsing, on see, milleks Dijkstra taandub, kui iga samm maksab sama palju.

Mida iga sümbol tähendab

g(n)
odavaima algusest ruuduni n seni leitud teekonna maksumus. Külgsuunas või vertikaalne samm maksab 1; diagonaalne samm maksab √2, sest sammu mõõdetakse pikkusena, mitte ei loeta üheks käiguks.
h(n)
hinnang veel ees seisvale maksumusele. Dijkstra algoritmi ja laiuti otsingu puhul pole see mitte lihtsalt kasutamata — see on null, ja just see teeb neist samanäolise avaldise, kust üks liidetav on puudu.
f(n)
järjestamisvõti: vähima väärtusega f ruut on see, mida uuritakse järgmisena. See trükitakse ruudustiku kohale, asendades valemis käesoleva ruudu enda arvud, et algoritmi ääsja tehtud valik oleks nähtav, mitte lihtsalt väidetav.
frontier
merevaigukollased ruudud — avastatud, kuid veel uurimata. Laiendatud sõlmed loendab sellest hulgast lahkunud ruute, mis teeb sellest tehtud töö, mitte vastuse kvaliteedi mõõdu.

Kust valem tuleb

  1. Enne algoritmi valimist lepi kokku, mida tähendab „lühim“. Tee maksumus on selle sammupikkuste summa: külgsuunas või vertikaalse käigu puhul 1, diagonaali puhul √2. Ruute ei loendata; vahemaad liidetakse.
  2. Nüüd tsükkel, mis on kõigi nelja puhul identne: võta rindest üks ruut, märgi see külastatuks ning paku iga läbitav naaber uuendatud väärtusega g tagasi rindesse. Pane tähele, mida see tsükkel kunagi ei maini — heuristikut, sihi suunda ega seda, millise algoritmi sa valisid.
  3. Nii et ainus otsus, mis jääb teha, on see, milline ruut välja võtta, ja see taandub ühele avaldisele. Järjesta avaldise g + h järgi ja saad A*-otsingu. Sea h = 0 ning järjestamine toimub pelgalt seni läbitud maksumuse järgi — see on Dijkstra algoritm, mis laieneb ringidena väljapoole, sest tal pole aimugi, kus siht asub. Eira selle asemel g-d ja järjestamine toimub pelgalt hinnangu järgi — Greedy Best-First, mis tormab sihi poole ja nõustub mis tahes teekonnaga, mille kaudu kohale jõudis.
  4. Laiuti otsing ei järjesta üldse: esimesena sisse, esimesena välja. Kui suvand Luba diagonaalid on välja lülitatud, maksab iga samm täpselt 1, seega ruutude saabumise järjekord on ühtlasi kasvava g järjekord — ja seetõttu uurib laiuti otsing täpselt seda sama, mida Dijkstra algoritm. Saad seda kinnitada ilma ruudustikku uuesti genereerimata: vaheta nende kahe vahel ja Laiendatud sõlmed ei liigu paigastki. Lülita diagonaalid sisse ja see argument langeb ära, sest diagonaal maksab 1 asemel √2 ning saabumise järjekord ei vasta enam maksumusele.

Kuidas nähtut lugeda

Prioriteedihinnang asub ruudustiku kohal, kuhu on sisse kantud käesoleva ruudu enda g ja h, nii et saad lugeda järjestust, mis andis viimase valiku. Selle all on kaks loendurit: Laiendatud sõlmed ja Tee pikkus. Merevaigukollane on rinne, indigosinine on juba külastatud. Algoritmi muutmine ei genereeri uut ruudustikku ja just see teebki võrdluse väärtuslikuks — samal neljasuunalisel paigutusel pole Dijkstra algoritmi Laiendatud sõlmed kunagi väiksem kui A*-otsingul ning Greedy Best-Firsti oma on vaid murdosa kumbagi omast.

Eeldab
Eeldab sammu maksumusi, mis pole kunagi negatiivsed, ning ruudustikku, mis otsingu ajal ei muutu. Algus on alati ülemine vasak ruut ja siht alumine parem. Ruudu sulgemine on lõplik — tsükkel ei kaalu ühtegi ruutu uuesti — ja see on turvaline vaid seetõttu, et ükski hilisem teekond ei saa saabuda odavamalt, kui iga samm lisab mittenegatiivse hulga.
Ei kehti, kui
Laiendatud sõlmed on arv, mis muutub kõige dramaatilisemalt, ning see pole kvaliteedi mõõt. Vali Greedy Best-First: samal ruudustikul uurib see vaid murdosa sellest, mida A*-otsing, ning enamikul paigutustel tagastab see pikema Tee pikkus. Genereeri mõned uued ruudustikud ja jälgi, kuidas kaks loendurit liiguvad vastassuundades. Vähema hulga ruutude uurimine näitab vaid seda, kui kõvasti algoritm töötas, mitte seda, kui hea oli selle vastus.

miks heuristikud on olulised 🖖

Valem f(n)=g(n)+h(n) paneb A*-i eelistama sõlmi, mis on seni odavad ja tunduvad sihtpunktile lähedal. Kui h ei ülehinda kunagi järelejäänud kulu, säilitab A* oma lühima tee garantii; tugevam lubatav h uurib vähem ebavajalikke lahtreid. Vaheta algoritmi rippmenüüd, et näha, mis juhtub, kui jätta ära heuristik (Dijkstra), senine kulu (Greedy) või kogu hindamine (BFS).

Üks tsükkel, neli iseloomu 🖖

Kõik neli algoritmi kordavad täpselt sama tsüklit: võtavad ootenimekirjast kõige paljutõotavama ruudu (merevaigukarva otsingurinne), märgivad selle külastatuks (indigosinine) ja lisavad läbitavad naaberruudud nimekirja. Erinevus seisneb ainult selles, mille järgi nad ruudu paljutõotavust hindavad. Tulemusi näitab laiendatud tippude arv, mis ei muutu sugugi ootuspäraselt. Tühjal võrestikul laiendab A* kõiki ruute, sest Manhattani kauguse korral on iga monotoonse, nurka viiva tee f-väärtus sama ning eelistamiseks pole alust. Takistuste lisamisel see arv väheneb.

Diagonaalid võivad garantii rikkuda 🖖

Lülita sisse 'Luba diagonaal' koos Manhattani heuristikuga ja A* võib vaikselt tagastada tee, mis pole lühim. Diagonaalne samm maksab siin vaid √2 ≈ 1.41, kuid Manhattani kaugus arvestab selle kui 2 — nii heuristik ülehindab, muutub lubamatuks ja optimaalsuse garantii kaob. Vaheta Eukleidilisele, mis ei ületa kunagi otsejoone kaugust, ja lühim tee tuleb tagasi.

Õpitee

Loe tööd, mitte sekundeid

Allikad (3)

Näiteülesanded

  • avatud ruudustik - 20x20 võrestikust on kümnendik tõkestatud, kuid A* laiendab endiselt enamikku sellest: iga monotoonse tee korral on f = 38, seega ei murra viiki miski.
  • labürindilaadne - Takistusterohkus muudab A* kiiremaks. Tõkestustihedus 0,28 kaotab viigid, mis teevad avatud võrestiku kulukaks, ning otsing piirdub umbes poolte vabade ruutudega.
  • nõrk heuristik - Avatud 4-naabrusega võrestikul annab Manhattani kaugus täpse hinnangu, Eukleidiline kaugus aga hindab seda alati alt. Seetõttu on Eukleidiline kaugus kahest lubatavast heuristikust nõrgem. Sama tee, kuid umbes kolmandiku võrra rohkem ruute.
  • Dijkstra uurib - Sama 24x24 võrestik sama tihedusega 0,22 nagu näites „Halb heuristik“, kuid ilma heuristikata. Eesmärgi asukohta arvestamata laiendab Dijkstra algoritm umbes poole võrra rohkem ruute kui A*.
  • greedy lõks - Ahnelt parim-enne otsing hindab ruute ainult h järgi, sööstab otse eesmärgi poole ja laiendab alla poole A* laiendatud ruutudest. Enamasti leiab see ka pikema tee. Selles kogu kompromiss seisnebki.
  • bfs + diagonaalid - Laiutiotsingul puudub info eesmärgi asukoha kohta, mistõttu jõuab see peaaegu iga vaba ruuduni. Diagonaalliikumise korral loeb algoritm diagonaali üheks sammuks, seega minimeerib ta sammude arvu, mitte vahemaad.