Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 4010446
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 20, 20262026-05-20T09:00:02+00:00 2026-05-20T09:00:02+00:00

This is a code that I got from the site here and I’d like

  • 0

This is a code that I got from the site here and I’d like to know whether this implementation of A* is correct. I have looked at it and compare it with the wikipedia page and it seems valid.. The reason why I ask is because in the site it says there is still a bug in this code, I tried finding it but can’t find any. I want to change it though so that it takes an origin and destination as input parameter

<?php

class AStarSolver
{
    function solve(&$s)
    {
        include_once('PQueue.class.php');
        $o = new PQueue();
        $l = array();
        $c = array();
        $p = array();
        $a = $s->getStartIndex();
        $z = $s->getGoalIndex();
        $d = $s->goalDistance($a);

        $n0 = array('g'=>0, 'h'=>$d, 'i'=>$a, 'p'=>NULL, 'f'=>$d);
        $o->push($n0, -$d);
        $l[$a] = TRUE;

        while (! $o->isEmpty())
        {
            $n = $o->pop();

            if ($n['i'] == $z)
            {
                while ($n)
                {
                    $p[] = $n['i'];
                    $n = $n['p'];
                }
                break;
            }

            foreach ($s->getNeighbors($n['i']) as $j => $w)
            {
                if ((isset($l[$j]) || isset($c[$j])) && isset($m) && $m['g'] <= $n['g']+$w)
                    continue;

                $d = $s->goalDistance($j);
                $m = array('g'=>$n['g']+$w, 'h'=>$d, 'i'=>$j, 'p'=>$n, 'f'=>$n['g']+$w+$d);

                if (isset($c[$j]))
                    unset($c[$j]);

                if (! isset($l[$j]))
                {
                    $o->push($m, -$m['f']);
                    $l[$j] = TRUE;
                }
            }
            $c[$n['i']] = $n;
        }
        return $p;
    }

}

?>

The code to the Pqueue can be found here

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-20T09:00:03+00:00Added an answer on May 20, 2026 at 9:00 am

    The site suggests that the bug might be in the PQueue class.

    In PQueue::pop this

    $j+1 < $m
    

    is a test whether the heap node at $i has one child (at $j) or two (at $j and $j+1).

    But $m here is count($h) only on the first iteration through the loop, since the --$m in the loop condition is evaluated every time.

    Move that --$m next to the array_pop where it belongs, and that will be one less bug.


    Now for AStarSolver.

    The variables are (relative to Wikipedia pseudocode):

    • $o – open set as priority queue;
    • $l – open set as map keyed by index;
    • $c – closed set as map keyed by index;
    • $n – current node (x);
    • $m – neighbour node (y) ?;
    • $j – neighbour node index.

    Problems that I see:

    • $n = $o->pop() isn’t followed by unset($l[$n['i']]). Since both $o and $l represent the same set, they should be kept in sync.

    • According to Wikipedia the closed set is only used if the heuristic is monotone (and I think a distance heuristic is monotone), and in that case, once a node is added to the closed set, it is never visited again. This code seems to implement some other pseudocode, which does remove nodes from the closed set. I think this defeats the purpose of the closed set, and the first condition in the inner loop should be

      if (isset($c[$j]) || isset($l[$j]) && isset($m) && $m['g'] <= $n['g']+$w)

      Then we can remove the unset($c[$j]).

    • $m['g'] in this condition should be the g-score of the current neighbour indexed by $j. But $m has whatever value is left over from the previous loop: the node corresponding to $j on a previous iteration.

      What we need is a way to find a node and its g-score by node index. We can store the node in the $l array: instead of $l[$j] = TRUE we do $l[$j] = $m and the above condition becomes

      if (isset($c[$j]) || isset($l[$j]) && $l[$j]['g'] <= $n['g']+$w)

    • Now the tricky bit. If the node we just found is not in the open set, we add it there (that’s the $o->push and $l[$j] =).

      However, if it is in the open set we just found a better path to it, so we must update it. The code doesn’t do this and it’s tricky because the priority queue doesn’t provide a routine for increasing the priority of an element. However, we can rebuild the priority queue completely and the last bit of code in the inner loop becomes

      if (! isset($l[$j])) {
         $o->push($m, -$m['f']);
         $l[$j] = $m; // add a new element
      } else {
         $l[$j] = $m; // replace existing element
         $o = new PQueue();
         foreach ($l as $m)
            $o->push($m, -$m['f']);
      }

      This is not terribly efficient, but it’s a starting point. Changing an element in a priority queue isn’t efficient anyway, because you first have to find it.


    Even without these changes the algorithm does find a path, just not the best path. You can see it in the mentioned mazes:

    • In the crazy maze in the third inner circuit: the taken upper path around is slightly longer than the lower path would have been because of the obstacles on the left.

    • In the big maze in the upper-right part of the path there’s an unnecessary loop up.


    Since this was on my mind, I implemented my own version of the algorithm and posted it in an answer to your previous question.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I've got some code that looks like this: using (DBDataContext dc = new DBDataContext(ConnectionString))
I've got HTML code that roughly looks like this: <li id=someid-11> <img src=... alt=alt
So I have this code that takes care of command acknowledgment from remote computers,
I've got a image selector/cropper with code taken from this site They create the
I've got a problem with inheritance and generics. This is the code that illustrates
I got some legacy code that has this: <?PHP if(isset($_GET['pagina'])==homepage) { ?> HtmlCode1 <?php
I have this code that performs an ajax call and loads the results into
I'm a newbie to python and the app engine. I have this code that
I have this jQuery code that queries an API on a keyup event (via
I have this legacy code that I am working with and there is code

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.