Documentation ¶
Overview ¶
Package astar implements the A* path finding algorithm. The main function is FindPath. Please find a description here: https://en.wikipedia.org/wiki/A*_search_algorithm
Index ¶
- func FindReversePath(open, closed GraphOps, end *Node, heuristic Heuristic) error
- func GraphVal() int
- type ConstantHeuristic
- type Error
- type Graph
- func (g *Graph) Add(node *Node)
- func (g *Graph) Apply(fn func(*Node) error) error
- func (g *Graph) Has(node *Node) bool
- func (g *Graph) Len() int
- func (g *Graph) PopCheapest() *Node
- func (g *Graph) Push(node *Node, estimate int)
- func (g *Graph) Remove(node *Node)
- func (g *Graph) ToString(heuristic Heuristic) string
- func (g *Graph) UpdateIfBetter(node, prev *Node, newCost int)
- type GraphOps
- type Heap
- type HeapElement
- type HeapedGraph
- func (g *HeapedGraph) Add(node *Node)
- func (g *HeapedGraph) Apply(fn func(*Node) error) error
- func (g *HeapedGraph) Has(node *Node) bool
- func (g *HeapedGraph) Len() int
- func (g *HeapedGraph) PopCheapest() *Node
- func (g *HeapedGraph) Push(node *Node, estimate int)
- func (g *HeapedGraph) Remove(findNode *Node)
- func (g *HeapedGraph) ToString(heuristic Heuristic) string
- func (g *HeapedGraph) UpdateIfBetter(node, prev *Node, newCost int)
- type Heuristic
- type Node
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func FindReversePath ¶
FindReversePath finds a reverse path from the start node to the end node. Follow the prev member of the end node to traverse the path backwards. To use this function, in the beginning, the open list must contain the start node and the closed list must be empty.
This function may panic. If you want panics to be handled internally, use FindPath instead.
Types ¶
type ConstantHeuristic ¶
type ConstantHeuristic struct {
// contains filtered or unexported fields
}
ConstantHeuristic can be used to construct a simple heuristic function with constant (as: never changing for any one node, but differing between nodes) costs for reaching the end node. Use AddNode to add a node with estimated cost and use Heuristic to retrieve the heuristic function. That heuristic function then simply remembers the constant costs provided for each node. Omce the heuristic function has been retrieved, its data can no longer be modified. Adding a node would start the creation of a new heuristic function.
func (*ConstantHeuristic) AddNode ¶
func (s *ConstantHeuristic) AddNode(node *Node, estimate int) error
AddNode adds a new node with estimated constant cost data. If the node is already there with a different estimate, this will error out.
func (*ConstantHeuristic) Heuristic ¶
func (s *ConstantHeuristic) Heuristic(defaultValue int) Heuristic
Heuristic obtains a heuristic function for the provided data. If a node cannot be found in the available data, return the default value. This is suitable for use with FindPath. The gathered data is cleared so that adding new nodes won't influence the function's data.
type Error ¶
type Error struct {
// contains filtered or unexported fields
}
Error is the error type that can be returned by the astar package. It is used to determine which errors occurred inside the package and which ones occurred outside of it.
type Graph ¶
Graph is a collection of nodes. Note that there are no guarantees for the nodes to be connected. Ensuring that is the user's task. Each nodes is assigned to its estimate. That means a node's estimate will never be able to change once added. Get a graph via NewGraph.
func (*Graph) PopCheapest ¶
PopCheapest retrieves one of the cheapest nodes and removes it. This will return nil if the graph is empty.
func (*Graph) Push ¶
Push adds a node to the graph, including its estimate. If the node already exists, this a no-op.
func (*Graph) Remove ¶
Remove removes a node from the graph. If the node does not exist, this a no-op.
func (*Graph) ToString ¶
ToString provides a string representation of the graph. The nodes are sorted according to their user-defined names. If you provide a heuristic != nil, the value that heuristic provides for each node is also provided at the end of a line. Providing nil will use the stored estimates.
func (*Graph) UpdateIfBetter ¶
UpdateIfBetter updates a node's best connection if that is cheaper than any previously found one. It takes the node to update, the new possible best predecessor and the cost for reaching that predecessor.
type GraphOps ¶
type GraphOps interface { // Len specifies how many elements there are in the graph. Len() int // Has checks whether a node is in the graph. Has(node *Node) bool // Add adds a node to a graph without an estimate. Add(node *Node) // Push adds a node to a graph with an estimate. Push(node *Node, estimate int) // Remove removes a specific node from a graph. Remove(node *Node) // PopCheapest retrieves and removes the cheapest node from the graph. Cost is equal to the // node's cost added to its estimate. PopCheapest() *Node // Apply applies a function to all nodes in the graph. That function may error out. Apply(func(*Node) error) error // UpdateIfBetter updates a node's best connection if that is cheaper than any previously found // one. It takes the node to update, the new possible best predecessor and the cost for reaching // that predecessor. UpdateIfBetter(*Node, *Node, int) }
GraphOps is an interface needed for a graph to be usable with the path finding functions in this module. See the method documentation of the actual Graph type for what the individual methods do in detail.
func CreateRegular2DGrid ¶ added in v0.2.0
func CreateRegular2DGrid( size [2]int, connections [][2]int, graphType string, defaultCost int, ) (GraphOps, map[[2]int]*Node, error)
CreateRegular2DGrid creates a regular 2D grid of connected nodes in a graph suitable for path finding. All nodes have a default cost of zero assigned.
Provide the number of nodes in each direction via the `size` argument. Provide a list of displacements that connect a node to its neighbours via the `connections` argument. For example, to connect horizontally and vertically only, pass the following as input:
[][2]int{ [2]int{-1, 0}, [2]int{0, -1}, [2]int{1, 0}, [2]int{0, 1}, }
Also provide the name of the type of graph you want to obtain as input. This can be "default" or "heaped". The heaped graph has a better performance but is a more complex data structure.
CreateRegular2DGrid returns three values:
- A graph object suitable for paht finding via FindPath.
- A map from node positions to node pointers, this makes modifying the nodes easy, e.g. to set the costs.
- An error value in case there were problems.
func NewGraph ¶
NewGraph obtains a new graph. No arguments are required. This function returns a normal graph based on a Go map. That structure has sub-optimal performance but works. Specify the estimated number of nodes as argument to boost performance. See Graph for details.
func NewHeapedGraph ¶
NewHeapedGraph obtains a new heaped graph. Specify the estimated number of nodes as argument to boost performance. See HeapedGraph for details.
type Heap ¶
type Heap []HeapElement
Heap is a collection of nodes on a minimum heap. It implements Go's heap.Interface. It is used by the heapable graph to store the actual nodes. Don't use this data structre on its own.
func (*Heap) Less ¶
Less determines whether one value is smaller than another one. This is needed for Go's heap interface.
func (*Heap) Pop ¶
func (h *Heap) Pop() interface{}
Pop removes a value from the heap. This is needed for Go's heap interface.
func (*Heap) Push ¶
func (h *Heap) Push(x interface{})
Push adds a value to the heap. This is needed for Go's heap interface. Don't use it directly, use Add to add nodes. This one will panic if you provide an incorrect type thanks to Go's lack of generics.
type HeapElement ¶
HeapElement is an element of a heap.
type HeapedGraph ¶
type HeapedGraph struct {
Heap Heap
}
HeapedGraph is a collection of nodes. Note that there are no guarantees for the nodes to be connected. Ensuring that is the user's task. Each nodes is assigned to its estimate. That means a node's estimate will never be able to change once added. Get a heaped graph via NewHeapedGraph. This uses a Heap as storage backend.
func (*HeapedGraph) Add ¶
func (g *HeapedGraph) Add(node *Node)
Add adds a node to the graph. If the node already exists, this a no-op. This panics if the node already has a different graph set.
func (*HeapedGraph) Apply ¶
func (g *HeapedGraph) Apply(fn func(*Node) error) error
Apply apples a function to all nodes in the graph.
func (*HeapedGraph) Has ¶
func (g *HeapedGraph) Has(node *Node) bool
Has determines whether a graph contains a specific node.
func (*HeapedGraph) PopCheapest ¶
func (g *HeapedGraph) PopCheapest() *Node
PopCheapest retrieves one of the cheapest nodes and removes it. This will return nil if the graph is empty.
func (*HeapedGraph) Push ¶
func (g *HeapedGraph) Push(node *Node, estimate int)
Push adds a node to the graph, including its estimate. If the node already exists, this a no-op.
func (*HeapedGraph) Remove ¶
func (g *HeapedGraph) Remove(findNode *Node)
Remove removes a node from the graph. If the node does not exist, this a no-op. This function is inefficient but not needed for the algorithm in general.
func (*HeapedGraph) ToString ¶
func (g *HeapedGraph) ToString(heuristic Heuristic) string
ToString provides a string representation of the graph. The nodes are sorted according to their user-defined names. If you provide a heuristic != nil, the value that heuristic provides for each node is also provided at the end of a line. Providing nil will use the stored estimates.
func (*HeapedGraph) UpdateIfBetter ¶
func (g *HeapedGraph) UpdateIfBetter(node, prev *Node, newCost int)
UpdateIfBetter updates a node's best connection if that is cheaper than any previously found one. It takes the node to update, the new possible best predecessor and the cost for reaching that predecessor.
type Heuristic ¶
Heuristic is a function that estimates the remaining cost to reach the end for a node. It must always return an integer cost value, even for nodes it does not know. For the algorithm to be guaranteed to return the least-cost path, the heuristic must never over-estimate the actual costs. In many cases, the direct, line-of-sight distance is a good heuristic.
func CreateConstantHeuristic2D ¶ added in v0.2.0
func CreateConstantHeuristic2D( posMap map[[2]int]*Node, dest [2]int, defaultVal int, ) (Heuristic, error)
CreateConstantHeuristic2D creates a constant heuristic for a regular 2D grid. It takes a map from node positions to node pointers and the desired end position and returns a simple, constant heuristic that estimates the remaining cost as the line-of-sight distance to the desired destination. Heuristics must return a value for all nodes, even ones they don't remember. For such nodes, it returns `defaultVal`.
type Node ¶
type Node struct { // Public members follow. // ID identifies the node. It is just a nice representation for the user and not used by the // algorithm. ID string // Cost specifies the cost of accessing this node from one connected to it. Cost int // Payload is some arbitrary user-defined payload that can be used with the heuristic, for // example. Type checks are the user's obligation. Payload interface{} // contains filtered or unexported fields }
Node is a node for a connected graph along which to travel. Use NewNode to create one. It *will* be modified while the algorithm is being executed but FindPath reverts it to its original state at the end.
func ExtractPath ¶
ExtractPath follows the connection from the end to the beginning and returns it. It begins at end and follows the prev member until it reaches start or until there is no prev member. In the latter case, an error is returned. Specify whether you want the original path, which is in reverse order, or the path from the original start to the end.
func FindPath ¶
FindPath finds the path between the start and end node. It is a convenience wrapper around FindReversePath. FindPath takes a graph in the form of a set of nodes, a start node, and an end node. It returns errors in case there are problems with the input or during execution. The path is returned in the correct order. This is achieved by using the normal algorithm and reversing the path at the end.
This function requires you to provide one of the graph types from this package as the `graph` argument. Use NewGraph or NewHeapedGraph to obtain a suitable data structure. If you want to use your own implementation of a GraphOps, you will need to use FindReversePath instead.
This implementation modifies the original nodes during execution! In the end, the nodes are reverted to null states (private members set to the appropriate zero values), which allows you to use the same input graph again with FindPath.
FindPath also takes a heuristic that estimates the cost for moving from a node to the end. In the easiest case, this can be built using ConstantHeuristic. This heuristic is evaluated exactly once for a node when adding that node to an internal graph.
This function is guaranteed to handle panics from this package and not to propagate the panic.
func NewNode ¶
NewNode creates a new node. Provide an id string that describes this node for the user. Also provide a non-negative cost value. If the cost is negative, an error is returned. For performance reasons, specify the number of expected neighbours. A non-positive value means you are not sure or don't want to optimise this part, which is fine, too.
func (*Node) AddConnection ¶
AddConnection adds a connection to a node. If the connection already exists, this is a no-op.
func (*Node) AddPairwiseConnection ¶
AddPairwiseConnection adds a connection to a node and from that node back to the receiver.. If the connection already exists, this is a no-op.
func (*Node) RemoveConnection ¶
RemoveConnection removes a connection to a node. If the speicified node does not connect to this node, this is a no-op.