Note that there are some explanatory texts on larger screens.

plurals
  1. POAdding non monotonic heuristics to A* php implimentation
    text
    copied!<p>I'm using aaz's <a href="https://stackoverflow.com/questions/5112111/a-search-algorithm-in-php/5169905#5169905">A* search algorithm in PHP</a> to help me find the shortest route accross a 3D graph of nodes.</p> <p>It does it well but what it returns is the first route it finds which may not be the optimum. As the node set is 3D, the heuristic is non monotonic. How would I go about adapting this implimentation to search for the optimum route not just the shortest?</p> <pre><code>class astar extends database { // Binary min-heap with element values stored separately var $map = array(); var $r; // Range to jump var $d; // distance between $start and $target var $x; // x co-ords of $start var $y; // y co-ords of $start var $z; // z co-ords of $start function heap_float(&amp;$heap, &amp;$values, $i, $index) { for (; $i; $i = $j) { $j = ($i + $i%2)/2 - 1; if ($values[$heap[$j]] &lt; $values[$index]) break; $heap[$i] = $heap[$j]; } $heap[$i] = $index; } function heap_push(&amp;$heap, &amp;$values, $index) { $this-&gt;heap_float($heap, $values, count($heap), $index); } function heap_raise(&amp;$heap, &amp;$values, $index) { $this-&gt;heap_float($heap, $values, array_search($index, $heap), $index); } function heap_pop(&amp;$heap, &amp;$values) { $front = $heap[0]; $index = array_pop($heap); $n = count($heap); if ($n) { for ($i = 0;; $i = $j) { $j = $i*2 + 1; if ($j &gt;= $n) break; if ($j+1 &lt; $n &amp;&amp; $values[$heap[$j+1]] &lt; $values[$heap[$j]]) ++$j; if ($values[$index] &lt; $values[$heap[$j]]) break; $heap[$i] = $heap[$j]; } $heap[$i] = $index; } return $front; } function a_star($start, $target) { $open_heap = array($start); // binary min-heap of indexes with values in $f $open = array($start =&gt; TRUE); // set of indexes $closed = array(); // set of indexes $g[$start] = 0; $d[$start] = 0; $h[$start] = $this-&gt;heuristic($start, $target); $f[$start] = $g[$start] + $h[$start]; while ($open) { $i = $this-&gt;heap_pop($open_heap, $f); unset($open[$i]); $closed[$i] = TRUE; if ($i == $target) { $path = array(); for (; $i != $start; $i = $from[$i]) $path[] = $i; return array_reverse($path); } foreach ($this-&gt;neighbors($i) as $j =&gt; $rng) if (!array_key_exists($j, $closed)) if (!array_key_exists($j, $open) || $d[$i] + $rng &lt; $d[$j]) { $d[$j] = $d[$i]+$rng; $g[$j] = $g[$i] + 1; $h[$j] = $this-&gt;heuristic($j, $target); $f[$j] = $g[$j] + $h[$j]; $from[$j] = $i; if (!array_key_exists($j, $open)) { $open[$j] = TRUE; $this-&gt;heap_push($open_heap, $f, $j); } else $this-&gt;heap_raise($open_heap, $f, $j); } } return FALSE; } function jumpRange($i, $j){ $sx = $this-&gt;map[$i]-&gt;x; $sy = $this-&gt;map[$i]-&gt;y; $sz = $this-&gt;map[$i]-&gt;z; $dx = $this-&gt;map[$j]-&gt;x; $dy = $this-&gt;map[$j]-&gt;y; $dz = $this-&gt;map[$j]-&gt;z; return sqrt((($sx-$dx)*($sx-$dx)) + (($sy-$dy)*($sy-$dy)) + (($sz-$dz)*($sz-$dz)))/9460730472580800; } function heuristic($i, $j) { $rng = $this-&gt;jumpRange($i, $j); return ceil($rng/$this-&gt;r); } function neighbors($sysID) { $neighbors = array(); foreach($this-&gt;map as $solarSystemID=&gt;$system) { $rng = $this-&gt;jumpRange($sysID,$solarSystemID); $j = ceil($rng/$this-&gt;r); $this-&gt;map[$solarSystemID]-&gt;h = $j; if($j == 1 &amp;&amp; $this-&gt;map[$solarSystemID]-&gt;s) { $neighbors[$solarSystemID] = $rng; } } arsort($neighbors); return $neighbors; } function fillMap() { $res = $this-&gt;query("SELECT * FROM mapSolarSystems WHERE SQRT( ( ($this-&gt;x-x)*($this-&gt;x-x) ) + ( ($this-&gt;y-y)*($this-&gt;y-y) ) + ( ($this-&gt;z-z)*($this-&gt;z-z) ) )/9460730472580800 &lt;= '$this-&gt;d'","SELECT"); while($line=mysql_fetch_object($res)) { $this-&gt;map[$line-&gt;solarSystemID] = $line; $this-&gt;map[$line-&gt;solarSystemID]-&gt;h = 0; $this-&gt;map[$line-&gt;solarSystemID]-&gt;s = false; } $res = $this-&gt;query("SELECT solarSystemID FROM staStations UNION SELECT solarSystemID FROM staConqureable","SELECT"); while($line=mysql_fetch_object($res)) { if(isset($this-&gt;map[$line-&gt;solarSystemID])) $this-&gt;map[$line-&gt;solarSystemID]-&gt;s = true; } } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload