Add BFS search algorithm
parent
8e003bf239
commit
b742df468b
|
@ -3,6 +3,8 @@
|
||||||
USING: help.markup help.syntax ;
|
USING: help.markup help.syntax ;
|
||||||
IN: path-finding
|
IN: path-finding
|
||||||
|
|
||||||
|
{ <astar> <bfs> } related-words
|
||||||
|
|
||||||
HELP: astar
|
HELP: astar
|
||||||
{ $description "This tuple must be subclassed and its method " { $link cost } ", "
|
{ $description "This tuple must be subclassed and its method " { $link cost } ", "
|
||||||
{ $link heuristic } ", and " { $link neighbours } " must be implemented. "
|
{ $link heuristic } ", and " { $link neighbours } " must be implemented. "
|
||||||
|
@ -53,6 +55,16 @@ HELP: <astar>
|
||||||
"may not be as efficient as subclassing the " { $link astar } " tuple."
|
"may not be as efficient as subclassing the " { $link astar } " tuple."
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
HELP: <bfs>
|
||||||
|
{ $values
|
||||||
|
{ "neighbours" "an assoc" }
|
||||||
|
{ "astar" "a astar tuple" }
|
||||||
|
}
|
||||||
|
{ $description "Build an astar object from the " { $snippet "neighbours" } " assoc. "
|
||||||
|
"When used with " { $link find-path } ", this astar tuple will use the breadth-first search (BFS) "
|
||||||
|
"path finding algorithm which is a particular case of the general A* algorithm."
|
||||||
|
} ;
|
||||||
|
|
||||||
HELP: find-path
|
HELP: find-path
|
||||||
{ $values
|
{ $values
|
||||||
{ "start" "a node" }
|
{ "start" "a node" }
|
||||||
|
@ -74,12 +86,12 @@ HELP: considered
|
||||||
"which have been examined during the A* exploration."
|
"which have been examined during the A* exploration."
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
ARTICLE: "astar" "A* algorithm"
|
ARTICLE: "path-finding" "Path finding using the A* algorithm"
|
||||||
"The " { $vocab-link "path-finding" } " vocabulary implements a graph search algorithm for finding the least-cost path from one node to another." $nl
|
"The " { $vocab-link "path-finding" } " vocabulary implements a graph search algorithm for finding the least-cost path from one node to another using the A* algorithm." $nl
|
||||||
"The " { $link astar } " tuple may be derived from and its " { $link cost } ", " { $link heuristic } ", and " { $link neighbours } " methods overwritten, or the " { $link <astar> } " word can be used to build such an object from quotations." $nl
|
"The " { $link astar } " tuple may be derived from and its " { $link cost } ", " { $link heuristic } ", and " { $link neighbours } " methods overwritten, or the " { $link <astar> } " or " { $link <bfs> } " words can be used to build a new tuple." $nl
|
||||||
"Make an A* object:"
|
"Make an A* object:"
|
||||||
{ $subsections <astar> }
|
{ $subsections <astar> <bfs> }
|
||||||
"Find a path between nodes:"
|
"Find a path between nodes:"
|
||||||
{ $subsections find-path } ;
|
{ $subsections find-path } ;
|
||||||
|
|
||||||
ABOUT: "astar"
|
ABOUT: "path-finding"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
! Copyright (C) 2010 Samuel Tardieu.
|
! Copyright (C) 2010 Samuel Tardieu.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: arrays assocs combinators hashtables kernel literals math math.functions
|
USING: arrays assocs combinators hashtables kernel literals math math.functions
|
||||||
math.vectors path-finding sequences sorting splitting strings tools.test ;
|
math.vectors memoize path-finding sequences sorting splitting strings tools.test ;
|
||||||
IN: path-finding.tests
|
IN: path-finding.tests
|
||||||
|
|
||||||
! Use a 10x9 maze (see below) to try to go from s to e, f or g.
|
! Use a 10x9 maze (see below) to try to go from s to e, f or g.
|
||||||
|
@ -97,8 +97,10 @@ M: maze cost
|
||||||
|
|
||||||
! In this version, we will use the quotations-aware version through <astar>.
|
! In this version, we will use the quotations-aware version through <astar>.
|
||||||
|
|
||||||
|
MEMO: routes ( -- hash ) $[ { "ABD" "BC" "C" "DCE" "ECF" } [ unclip swap 2array ] map >hashtable ] ;
|
||||||
|
|
||||||
: n ( pos -- neighbours )
|
: n ( pos -- neighbours )
|
||||||
$[ { "ABD" "BC" "C" "DCE" "ECF" } [ unclip swap 2array ] map >hashtable ] at ;
|
routes at ;
|
||||||
|
|
||||||
: c ( from to -- cost )
|
: c ( from to -- cost )
|
||||||
"" 2sequence H{ { "AB" 1 } { "AD" 2 } { "BC" 5 } { "DC" 2 } { "DE" 1 } { "EC" 2 } { "EF" 1 } } at ;
|
"" 2sequence H{ { "AB" 1 } { "AD" 2 } { "BC" 5 } { "DC" 2 } { "DE" 1 } { "EC" 2 } { "EF" 1 } } at ;
|
||||||
|
@ -112,3 +114,9 @@ M: maze cost
|
||||||
|
|
||||||
! No path from D to B -- all nodes reachable from D must have been examined
|
! No path from D to B -- all nodes reachable from D must have been examined
|
||||||
[ f "CDEF" ] [ "DB" test2 ] unit-test
|
[ f "CDEF" ] [ "DB" test2 ] unit-test
|
||||||
|
|
||||||
|
! Find a path using BFS. There are no path from F to A, and the path from D to
|
||||||
|
! C does not include any other node.
|
||||||
|
|
||||||
|
[ f ] [ "FA" first2 routes <bfs> find-path ] unit-test
|
||||||
|
[ "DC" ] [ "DC" first2 routes <bfs> find-path >string ] unit-test
|
||||||
|
|
|
@ -69,6 +69,11 @@ M: astar-simple cost cost>> call( n1 n2 -- c ) ;
|
||||||
M: astar-simple heuristic heuristic>> call( n1 n2 -- c ) ;
|
M: astar-simple heuristic heuristic>> call( n1 n2 -- c ) ;
|
||||||
M: astar-simple neighbours neighbours>> call( n -- neighbours ) ;
|
M: astar-simple neighbours neighbours>> call( n -- neighbours ) ;
|
||||||
|
|
||||||
|
TUPLE: bfs < astar neighbours ;
|
||||||
|
M: bfs cost 3drop 1 ;
|
||||||
|
M: bfs heuristic 3drop 0 ;
|
||||||
|
M: bfs neighbours neighbours>> at ;
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
: find-path ( start target astar -- path/f )
|
: find-path ( start target astar -- path/f )
|
||||||
|
@ -79,3 +84,6 @@ PRIVATE>
|
||||||
|
|
||||||
: considered ( astar -- considered )
|
: considered ( astar -- considered )
|
||||||
in-closed-set>> members ;
|
in-closed-set>> members ;
|
||||||
|
|
||||||
|
: <bfs> ( neighbours -- astar )
|
||||||
|
[ bfs new ] dip >>neighbours ;
|
||||||
|
|
Loading…
Reference in New Issue