-
Notifications
You must be signed in to change notification settings - Fork 201
/
Copy pathdijkstras.coffee
92 lines (84 loc) · 1.76 KB
/
dijkstras.coffee
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
PriorityQueue = ->
@_nodes = []
@enqueue = (priority, key) ->
@_nodes.push
key : key
priority : priority
@sort()
return
@dequeue = ->
@_nodes.shift().key
@sort = ->
@_nodes.sort = (a, b) ->
a.priority - b.priority
return
@isEmpty = ->
!@_nodes.length
return
Graph = ->
INFINITY = 1 / 0
@vertices = {}
@addVertex = (name, edges) ->
@vertices[name] = edges
return
@shortestPath = (start, finish) ->
nodes = new PriorityQueue
distances = {}
previous = {}
path = []
smallest = undefined
vertex = undefined
neighbor = undefined
alt = undefined
for vertex of @vertices
if vertex is start
distances[vertex] = 0
nodes.enqueue(0, vertex)
else
distances[vertex] = INFINITY
nodes.enqueue(INFINITY, vertex)
previous[vertex] = null
while not nodes.isEmpty()
smallest = nodes.dequeue()
if smallest is finish
path = []
while previous[smallest]
path.push smallest
smallest = previous[smallest]
break
if not smallest or distances[smallest] is INFINITY
continue
for neighbor of @vertices[smallest]
alt = distances[smallest] + @vertices[smallest][neighbor]
if alt < distances[neighbor]
distances[neighbor] = alt
previous[neighbor] = smallest
nodes.enqueue alt, neighbor
path
return
g = new Graph()
g.addVertex 'A',
B: 7
C: 8
g.addVertex 'B',
A: 7
F: 2
g.addVertex 'C',
A: 8
F: 6
G: 4
g.addVertex 'D', F: 8
g.addVertex 'E', H: 1
g.addVertex 'F',
B: 2
C: 6
D: 8
G: 9
H: 3
g.addVertex 'G',
C: 4
F: 9
g.addVertex 'H',
E: 1
F: 3
console.log g.shortestPath('A', 'H').concat(['A']).reverse()