A* search algorithm: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
Thundergnat (talk | contribs) m (Automated syntax highlighting fixup (second round - minor fixes)) |
||
Line 35: | Line 35: | ||
{{trans|Python}} |
{{trans|Python}} |
||
<syntaxhighlight lang=11l>F AStarSearch(start, end, barriers) |
<syntaxhighlight lang="11l">F AStarSearch(start, end, barriers) |
||
F heuristic(start, goal) |
F heuristic(start, goal) |
||
V D = 1 |
V D = 1 |
||
Line 116: | Line 116: | ||
=={{header|C}}== |
=={{header|C}}== |
||
<syntaxhighlight lang=c> |
<syntaxhighlight lang="c"> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
#include <stdio.h> |
#include <stdio.h> |
||
Line 396: | Line 396: | ||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
<syntaxhighlight lang=csharp> |
<syntaxhighlight lang="csharp"> |
||
using System; |
using System; |
||
using System.Collections.Generic; |
using System.Collections.Generic; |
||
Line 663: | Line 663: | ||
=={{header|C++}}== |
=={{header|C++}}== |
||
<syntaxhighlight lang=cpp> |
<syntaxhighlight lang="cpp"> |
||
#include <list> |
#include <list> |
||
#include <algorithm> |
#include <algorithm> |
||
Line 847: | Line 847: | ||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
<syntaxhighlight lang=lisp>;; * Using external libraries with quicklisp |
<syntaxhighlight lang="lisp">;; * Using external libraries with quicklisp |
||
(eval-when (:load-toplevel :compile-toplevel :execute) |
(eval-when (:load-toplevel :compile-toplevel :execute) |
||
(ql:quickload '("pileup" "iterate"))) |
(ql:quickload '("pileup" "iterate"))) |
||
Line 1,023: | Line 1,023: | ||
=={{header|D}}== |
=={{header|D}}== |
||
ported from c++ code |
ported from c++ code |
||
<syntaxhighlight lang= |
<syntaxhighlight lang="d"> |
||
import std.stdio; |
import std.stdio; |
||
Line 1,198: | Line 1,198: | ||
=={{Header|FreeBASIC}}== |
=={{Header|FreeBASIC}}== |
||
<syntaxhighlight lang=freebasic> |
<syntaxhighlight lang="freebasic"> |
||
'############################### |
'############################### |
||
'### A* search algorithm ### |
'### A* search algorithm ### |
||
Line 1,465: | Line 1,465: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
<syntaxhighlight lang=go>// Package astar implements the A* search algorithm with minimal constraints |
<syntaxhighlight lang="go">// Package astar implements the A* search algorithm with minimal constraints |
||
// on the graph representation. |
// on the graph representation. |
||
package astar |
package astar |
||
Line 1,578: | Line 1,578: | ||
return h[last] |
return h[last] |
||
}</syntaxhighlight> |
}</syntaxhighlight> |
||
<syntaxhighlight lang=go>package main |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 1,643: | Line 1,643: | ||
The simplest standalone FIFO priority queue is implemented after Sleator and Tarjan in Louis Wasserman's ''"Playing with Priority Queues"''[https://themonadreader.files.wordpress.com/2010/05/issue16.pdf]. |
The simplest standalone FIFO priority queue is implemented after Sleator and Tarjan in Louis Wasserman's ''"Playing with Priority Queues"''[https://themonadreader.files.wordpress.com/2010/05/issue16.pdf]. |
||
<syntaxhighlight lang=haskell>{-# language DeriveFoldable #-} |
<syntaxhighlight lang="haskell">{-# language DeriveFoldable #-} |
||
module PQueue where |
module PQueue where |
||
Line 1,673: | Line 1,673: | ||
The simple graph combinators: |
The simple graph combinators: |
||
<syntaxhighlight lang=haskell>import PQueue |
<syntaxhighlight lang="haskell">import PQueue |
||
import Data.Map (Map(..)) |
import Data.Map (Map(..)) |
||
import qualified Data.Map as Map |
import qualified Data.Map as Map |
||
Line 1,697: | Line 1,697: | ||
Finally, the search algorythm, as given in Wikipedia. |
Finally, the search algorythm, as given in Wikipedia. |
||
<syntaxhighlight lang=haskell>get :: (Ord k, Bounded a) => Map k a -> k -> a |
<syntaxhighlight lang="haskell">get :: (Ord k, Bounded a) => Map k a -> k -> a |
||
get m x = Map.findWithDefault maxBound x m |
get m x = Map.findWithDefault maxBound x m |
||
Line 1,741: | Line 1,741: | ||
Example |
Example |
||
<syntaxhighlight lang=haskell>distL1 (x,y) (a,b) = max (abs $ x-a) (abs $ y-b) |
<syntaxhighlight lang="haskell">distL1 (x,y) (a,b) = max (abs $ x-a) (abs $ y-b) |
||
main = let |
main = let |
||
Line 1,776: | Line 1,776: | ||
Implementation: |
Implementation: |
||
<syntaxhighlight lang= |
<syntaxhighlight lang="j"> |
||
barrier=: 2 4,2 5,2 6,3 6,4 6,5 6,5 5,5 4,5 3,5 2,4 2,:3 2 |
barrier=: 2 4,2 5,2 6,3 6,4 6,5 6,5 5,5 4,5 3,5 2,4 2,:3 2 |
||
price=: _,.~_,~100 barrier} 8 8$1 |
price=: _,.~_,~100 barrier} 8 8$1 |
||
Line 1,808: | Line 1,808: | ||
Task example: |
Task example: |
||
<syntaxhighlight lang= |
<syntaxhighlight lang="j"> Asrch'' |
||
┌──┬───┐ |
┌──┬───┐ |
||
│11│0 0│ |
│11│0 0│ |
||
Line 1,839: | Line 1,839: | ||
=={{header|Java}}== |
=={{header|Java}}== |
||
<syntaxhighlight lang=java> |
<syntaxhighlight lang="java"> |
||
package astar; |
package astar; |
||
Line 2,097: | Line 2,097: | ||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
Animated.<br />To see how it works on a random map go [http://paulo-jorente.de/tests/astar/ here] |
Animated.<br />To see how it works on a random map go [http://paulo-jorente.de/tests/astar/ here] |
||
<syntaxhighlight lang=javascript> |
<syntaxhighlight lang="javascript"> |
||
var ctx, map, opn = [], clsd = [], start = {x:1, y:1, f:0, g:0}, |
var ctx, map, opn = [], clsd = [], start = {x:1, y:1, f:0, g:0}, |
||
goal = {x:8, y:8, f:0, g:0}, mw = 10, mh = 10, neighbours, path; |
goal = {x:8, y:8, f:0, g:0}, mw = 10, mh = 10, neighbours, path; |
||
Line 2,215: | Line 2,215: | ||
</pre> |
</pre> |
||
Implementation using recursive strategy |
Implementation using recursive strategy |
||
<syntaxhighlight lang=javascript> |
<syntaxhighlight lang="javascript"> |
||
function manhattan(x1, y1, x2, y2) { |
function manhattan(x1, y1, x2, y2) { |
||
return Math.abs(x1 - x2) + Math.abs(y1 - y2); |
return Math.abs(x1 - x2) + Math.abs(y1 - y2); |
||
Line 2,294: | Line 2,294: | ||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
The graphic in this solution is displayed in the more standard orientation of origin at bottom left and goal at top right. |
The graphic in this solution is displayed in the more standard orientation of origin at bottom left and goal at top right. |
||
<syntaxhighlight lang= |
<syntaxhighlight lang="julia">using LightGraphs, SimpleWeightedGraphs |
||
const chessboardsize = 8 |
const chessboardsize = 8 |
||
Line 2,346: | Line 2,346: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
<syntaxhighlight lang=kotlin> |
<syntaxhighlight lang="kotlin"> |
||
import java.lang.Math.abs |
import java.lang.Math.abs |
||
Line 2,464: | Line 2,464: | ||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
<syntaxhighlight lang=lua> |
<syntaxhighlight lang="lua"> |
||
-- QUEUE ----------------------------------------------------------------------- |
-- QUEUE ----------------------------------------------------------------------- |
||
Queue = {} |
Queue = {} |
||
Line 2,683: | Line 2,683: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
Implementation of the Wikipedia pseudocode. |
Implementation of the Wikipedia pseudocode. |
||
<syntaxhighlight lang= |
<syntaxhighlight lang="nim"> |
||
# A* search algorithm. |
# A* search algorithm. |
||
Line 2,839: | Line 2,839: | ||
A very close/straightforward implementation of the Wikipedia pseudocode. |
A very close/straightforward implementation of the Wikipedia pseudocode. |
||
<syntaxhighlight lang=ocaml> |
<syntaxhighlight lang="ocaml"> |
||
module IntPairs = |
module IntPairs = |
||
struct |
struct |
||
Line 2,997: | Line 2,997: | ||
=={{header|Ol}}== |
=={{header|Ol}}== |
||
<syntaxhighlight lang=scheme> |
<syntaxhighlight lang="scheme"> |
||
; level: list of lists, any except 1 means the cell is empty |
; level: list of lists, any except 1 means the cell is empty |
||
; from: start cell in (x . y) mean |
; from: start cell in (x . y) mean |
||
Line 3,066: | Line 3,066: | ||
{{out}} |
{{out}} |
||
<syntaxhighlight lang=scheme> |
<syntaxhighlight lang="scheme"> |
||
(define level '( |
(define level '( |
||
(1 1 1 1 1 1 1 1 1 1) |
(1 1 1 1 1 1 1 1 1 1) |
||
Line 3,167: | Line 3,167: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
<syntaxhighlight lang=perl>#!/usr/bin/perl |
<syntaxhighlight lang="perl">#!/usr/bin/perl |
||
use strict; # https://rosettacode.org/wiki/A*_search_algorithm |
use strict; # https://rosettacode.org/wiki/A*_search_algorithm |
||
Line 3,230: | Line 3,230: | ||
===Extra Credit=== |
===Extra Credit=== |
||
<syntaxhighlight lang=perl>#!/usr/bin/perl |
<syntaxhighlight lang="perl">#!/usr/bin/perl |
||
use strict; # https://rosettacode.org/wiki/A*_search_algorithm |
use strict; # https://rosettacode.org/wiki/A*_search_algorithm |
||
Line 3,326: | Line 3,326: | ||
Note that the 23 visited nodes does not count walls, but with them this algorithm exactly matches the 35 of Racket. |
Note that the 23 visited nodes does not count walls, but with them this algorithm exactly matches the 35 of Racket. |
||
<!--<syntaxhighlight lang= |
<!--<syntaxhighlight lang="phix">(phixonline)--> |
||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">grid</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #008000;">""" |
<span style="color: #004080;">sequence</span> <span style="color: #000000;">grid</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #008000;">""" |
||
x::::::: |
x::::::: |
||
Line 3,421: | Line 3,421: | ||
lowest cost and a simple dictionary to avoid re-examination/inifinte recursion. |
lowest cost and a simple dictionary to avoid re-examination/inifinte recursion. |
||
<!--<syntaxhighlight lang= |
<!--<syntaxhighlight lang="phix">(phixonline)--> |
||
<span style="color: #000080;font-style:italic;">--set_rand(3) -- (for consistent output)</span> |
<span style="color: #000080;font-style:italic;">--set_rand(3) -- (for consistent output)</span> |
||
<span style="color: #008080;">constant</span> <span style="color: #000000;">optimal</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span><span style="color: #0000FF;">,</span> |
<span style="color: #008080;">constant</span> <span style="color: #000000;">optimal</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span><span style="color: #0000FF;">,</span> |
||
Line 3,603: | Line 3,603: | ||
=={{header|PowerShell}}== |
=={{header|PowerShell}}== |
||
<syntaxhighlight lang=powershell>function CreateGrid($h, $w, $fill) { |
<syntaxhighlight lang="powershell">function CreateGrid($h, $w, $fill) { |
||
$grid = 0..($h - 1) | ForEach-Object { , (, $fill * $w) } |
$grid = 0..($h - 1) | ForEach-Object { , (, $fill * $w) } |
||
return $grid |
return $grid |
||
Line 3,731: | Line 3,731: | ||
=={{header|Picat}}== |
=={{header|Picat}}== |
||
<syntaxhighlight lang= |
<syntaxhighlight lang="picat">% Picat's tabling system uses an algorithm like Dijkstra's to find an optimal solution. |
||
% Picat's planner supports A* search with heuristics. |
% Picat's planner supports A* search with heuristics. |
||
% See the program for the 15-puzzle at https://rosettacode.org/wiki/15_puzzle_solver#Picat |
% See the program for the 15-puzzle at https://rosettacode.org/wiki/15_puzzle_solver#Picat |
||
Line 3,770: | Line 3,770: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
<syntaxhighlight lang=python>from __future__ import print_function |
<syntaxhighlight lang="python">from __future__ import print_function |
||
import matplotlib.pyplot as plt |
import matplotlib.pyplot as plt |
||
Line 3,880: | Line 3,880: | ||
This code is lifted from: [https://jeapostrophe.github.io/2013-04-15-astar-post.html this blog post]. Read it, it's very good. |
This code is lifted from: [https://jeapostrophe.github.io/2013-04-15-astar-post.html this blog post]. Read it, it's very good. |
||
<syntaxhighlight lang=racket>#lang scribble/lp |
<syntaxhighlight lang="racket">#lang scribble/lp |
||
@(chunk |
@(chunk |
||
<graph-sig> |
<graph-sig> |
||
Line 4,116: | Line 4,116: | ||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
{{trans|Sidef}} |
{{trans|Sidef}} |
||
<syntaxhighlight lang= |
<syntaxhighlight lang="raku" line># 20200427 Raku programming solution |
||
class AStarGraph { |
class AStarGraph { |
||
Line 4,222: | Line 4,222: | ||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
<syntaxhighlight lang=rexx>/*REXX program solves the A* search problem for a (general) NxN grid. */ |
<syntaxhighlight lang="rexx">/*REXX program solves the A* search problem for a (general) NxN grid. */ |
||
parse arg N sCol sRow . /*obtain optional arguments from the CL*/ |
parse arg N sCol sRow . /*obtain optional arguments from the CL*/ |
||
if N=='' | N=="," then N=8 /*No grid size specified? Use default.*/ |
if N=='' | N=="," then N=8 /*No grid size specified? Use default.*/ |
||
Line 4,329: | Line 4,329: | ||
=={{header|SequenceL}}== |
=={{header|SequenceL}}== |
||
<syntaxhighlight lang=sequencel> |
<syntaxhighlight lang="sequencel"> |
||
import <Utilities/Set.sl>; |
import <Utilities/Set.sl>; |
||
import <Utilities/Math.sl>; |
import <Utilities/Math.sl>; |
||
Line 4,447: | Line 4,447: | ||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
<syntaxhighlight lang=ruby>class AStarGraph { |
<syntaxhighlight lang="ruby">class AStarGraph { |
||
has barriers = [ |
has barriers = [ |
||
Line 4,570: | Line 4,570: | ||
{{works with|Bourne Again SHell}} |
{{works with|Bourne Again SHell}} |
||
<syntaxhighlight lang=bash> |
<syntaxhighlight lang="bash"> |
||
#!/bin/bash |
#!/bin/bash |
||
Line 4,960: | Line 4,960: | ||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
{{trans|Sidef}} |
{{trans|Sidef}} |
||
<syntaxhighlight lang=ecmascript>var Equals = Fn.new { |p1, p2| p1[0] == p2[0] && p1[1] == p2[1] } |
<syntaxhighlight lang="ecmascript">var Equals = Fn.new { |p1, p2| p1[0] == p2[0] && p1[1] == p2[1] } |
||
var Contains = Fn.new { |pairs, p| |
var Contains = Fn.new { |pairs, p| |
||
Line 5,096: | Line 5,096: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
<syntaxhighlight lang=zkl> // we use strings as hash keys: (x,y)-->"x,y", keys are a single pair |
<syntaxhighlight lang="zkl"> // we use strings as hash keys: (x,y)-->"x,y", keys are a single pair |
||
fcn toKey(xy){ xy.concat(",") } |
fcn toKey(xy){ xy.concat(",") } |
||
Line 5,151: | Line 5,151: | ||
throw(Exception.AssertionError("A* failed to find a solution")); |
throw(Exception.AssertionError("A* failed to find a solution")); |
||
}</syntaxhighlight> |
}</syntaxhighlight> |
||
<syntaxhighlight lang=zkl>class [static] AStarGraph{ # Define a class board like grid with barriers |
<syntaxhighlight lang="zkl">class [static] AStarGraph{ # Define a class board like grid with barriers |
||
var [const] barriers = |
var [const] barriers = |
||
T( T(3,2),T(4,2),T(5,2), // T is RO List |
T( T(3,2),T(4,2),T(5,2), // T is RO List |
||
Line 5,178: | Line 5,178: | ||
} |
} |
||
}</syntaxhighlight> |
}</syntaxhighlight> |
||
<syntaxhighlight lang=zkl>graph:=AStarGraph; |
<syntaxhighlight lang="zkl">graph:=AStarGraph; |
||
route,cost := AStarSearch(T(0,0), T(7,7), graph); |
route,cost := AStarSearch(T(0,0), T(7,7), graph); |
||
println("Route: ", route.apply(fcn(xy){ String("(",toKey(xy),")") }).concat(",")); |
println("Route: ", route.apply(fcn(xy){ String("(",toKey(xy),")") }).concat(",")); |