Het klopt dat zodra je A expand je de optimale afstand hebt. Dat is zo mits je een permissive heuristic gebruikt, zoals A* vereist. (Je kunt overigens een non-permissive heuristic gebruiken, maar dan moet je punten meer dan eens evalueren. Dit kan een gunstige trade-off zijn voor sommige problemen, maar de heuristiek die jij beschreef is permissive.).oisyn schreef op maandag 12 december 2022 @ 22:59:
Dan krijgt de A via de node links van hem een prioriteit van 9, terwijl hij via de rechterkant 7 blijft. Mijn redenatie was dus, A kan nooit eerder op een slechter pad worden afgehandeld.
Dat betekent niet dat een punt maar 1 keer in de queue terecht kan komen. Hier is nog een voorbeeld:
Saaa... aaaa..E
Het is hopelijk duidelijk dat alle a's dezelfde prioriteit krijgen (7). Dat betekent dat de volgorde waarin je de a's bezoekt niet vast staat: je zou eerst naar rechts kunnen gaan, of eerst naar onder. Stel dat je eerst naar onder gaat, en daarna pas naar rechts, dan bezoek je eerst de volgende drie nodes:
SPQa... 123R..E
De nodes met labels 1, 2, 3, zijn bezocht en hebben afstand 1, 2, 3. P, Q, R zitten allen in de queue. Maar punt q heeft een prioriteit 9: afstand 4 + heuristiek 5. De afstand is 4 omdat 'ie gezien is vanuit het punt met afstand 3. In realiteit heeft het kortste pad lengte 2, maar om dat te beseffen moet je nog punt P bezoeken, en dat heb je nog niet gedaan. Zodra je punt P bezoek realiseer je je dat de afstand tot Q slechts 2 is, en de afstand plus heuristiek wordt dan verlaagd van 9 naar 7 (afstand 2 + heuristiek 5). Op dat moment zit Q dus twee keer in de priority queue: met prioriteit 9 en 7. Als je de oude entry niet verwijdert bezoek je 'm eerst met prioriteit 7 (correct) en daarna met prioriteit 9.
Nogmaals, dit “probleem” heb je niet als je eerst de bestaande entry uit je priority queue verwijderd of de prioriteit verlaagd, maar de meeste implementaties doen dat niet omdat het in de praktijk meestal trager is dan ze laten zitten en negeren wanneer je ze uit de queue haalt (en b.v. de std::priority_queue in C++ heeft geen ondersteuning voor het verlagen van prioriteiten (of verhogen, want C++ is een max-priority queue)).