-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathastar.go
76 lines (63 loc) · 1.24 KB
/
astar.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package astar
type Cost int
type Node interface {
Nbs() []Node
DistanceTo(other Node) Cost
EstimateTo(other Node) Cost
}
func Astar(node0, goal Node) (path []Node) {
var (
closedset = map[Node]struct{}{}
parents = map[Node]Node{}
g = map[Node]Cost{node0: 0}
f0 = node0.EstimateTo(goal)
openq = new(QMap)
)
openq.Init()
openq.Add(node0, f0)
for openq.Len() > 0 {
x := openq.Pop()
if x == goal {
consPath(goal, parents, &path)
return path
}
closedset[x] = struct{}{}
for _, y := range x.Nbs() {
if _, closed := closedset[y]; closed {
continue
}
gEstimated := g[x] + x.DistanceTo(y)
yQueued, updating := openq.Get(y)
if updating {
if gEstimated >= g[y] {
continue
}
}
parents[y] = x
g[y] = gEstimated
fy := gEstimated + y.EstimateTo(goal)
if updating {
openq.Update(yQueued, fy)
} else {
openq.Add(y, fy)
}
}
}
return
}
func consPath(node Node, parents map[Node]Node, path *[]Node) {
for {
parent, ok := parents[node]
if !ok {
break
}
*path = append(*path, node)
node = parent
}
reverse(*path)
}
func reverse(path []Node) {
for i, j := 0, len(path)-1; i < j; i, j = i+1, j-1 {
path[i], path[j] = path[j], path[i]
}
}