From 72f87ec1eb6f8b3e312a3fee1f39c389cb929e8d Mon Sep 17 00:00:00 2001 From: aitsuki Date: Thu, 27 Jan 2022 22:17:24 +0800 Subject: [PATCH] Remove the 'close' and 'opened' fields. --- astar.go | 59 ++++++++++++++++++-------------------------------------- 1 file changed, 19 insertions(+), 40 deletions(-) diff --git a/astar.go b/astar.go index a3af081..388ef51 100644 --- a/astar.go +++ b/astar.go @@ -23,46 +23,24 @@ type node struct { cost float64 rank float64 parent *node - open bool - closed bool index int } // nodeMap is a collection of nodes keyed by Pather nodes for quick reference. type nodeMap map[Pather]*node -// get gets the Pather object wrapped in a node, instantiating if required. -func (nm nodeMap) get(p Pather) *node { - n, ok := nm[p] - if !ok { - n = &node{ - pather: p, - } - nm[p] = n - } - return n -} - // Path calculates a short path and the distance between the two Pather nodes. // // If no path is found, found will be false. func Path(from, to Pather) (path []Pather, distance float64, found bool) { - nm := nodeMap{} - nq := &priorityQueue{} - heap.Init(nq) - fromNode := nm.get(from) - fromNode.open = true - heap.Push(nq, fromNode) - for { - if nq.Len() == 0 { - // There's no path, return found false. - return - } - current := heap.Pop(nq).(*node) - current.open = false - current.closed = true + fromNode := &node{pather: from} + closeset := nodeMap{from: fromNode} + openset := &priorityQueue{fromNode} + heap.Init(openset) + for openset.Len() > 0 { + current := heap.Pop(openset).(*node) - if current == nm.get(to) { + if current.pather == to { // Found a path to the goal. p := []Pather{} curr := current @@ -74,22 +52,23 @@ func Path(from, to Pather) (path []Pather, distance float64, found bool) { } for _, neighbor := range current.pather.PathNeighbors() { - cost := current.cost + current.pather.PathNeighborCost(neighbor) - neighborNode := nm.get(neighbor) - if cost < neighborNode.cost { - if neighborNode.open { - heap.Remove(nq, neighborNode.index) - } - neighborNode.open = false - neighborNode.closed = false + neighborNode, exists := closeset[neighbor] + if !exists { + neighborNode = &node{pather: neighbor} + closeset[neighbor] = neighborNode } - if !neighborNode.open && !neighborNode.closed { + cost := current.cost + current.pather.PathNeighborCost(neighbor) + if !exists || cost < neighborNode.cost { neighborNode.cost = cost - neighborNode.open = true neighborNode.rank = cost + neighbor.PathEstimatedCost(to) neighborNode.parent = current - heap.Push(nq, neighborNode) + if exists { + heap.Fix(openset, neighborNode.index) + } else { + heap.Push(openset, neighborNode) + } } } } + return }