-
Notifications
You must be signed in to change notification settings - Fork 5
/
dijkstra_local.go
54 lines (50 loc) · 2.19 KB
/
dijkstra_local.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
package ch
const (
Infinity = float64(^uint(0) >> 1)
// Infinity = Infinity
)
// shortestPathsWithMaxCost Internal implementation of Dijkstra's algorithm to compute witness paths
func (graph *Graph) shortestPathsWithMaxCost(source int64, maxcost float64, previousOrderPos int64) {
// Heap to store traveled distance
pqComparator := &distanceHeap{}
pqComparator.Push(&graph.Vertices[source])
// Instead of inializing distances to Infinity every single shortestPathsWithMaxCost(...) call we can do following
// Set dist[source] -> 0 (as usual)
graph.Vertices[source].distance.distance = 0
// Set order position to previously contracted (excluded from graph) vertex
graph.Vertices[source].distance.previousOrderPos = previousOrderPos
// Set source to identifier of vertex for which shortestPathsWithMaxCost(...) has been called
graph.Vertices[source].distance.previousSourceID = source
for pqComparator.Len() != 0 {
vertex := pqComparator.Pop()
// Do not consider any vertex has been excluded earlier
if vertex.contracted {
continue
}
// Once a vertex is settled with a shortest path score greater than max cost, search stops.
if vertex.distance.distance > maxcost {
return
}
// Edge relaxation
vertexList := vertex.outIncidentEdges
for i := range vertexList {
temp := vertexList[i].vertexID
cost := vertexList[i].weight
tempPtr := &graph.Vertices[temp]
// Do not consider any vertex has been excluded earlier
if tempPtr.contracted {
continue
}
alt := vertex.distance.distance + cost
if tempPtr.distance.distance > alt || // usual condition for Dijkstra's algorithm
vertex.distance.previousOrderPos != tempPtr.distance.previousOrderPos || // Optional condition: if previous shortestPathsWithMaxCost(...) call has changed shortest path tree
vertex.distance.previousSourceID != tempPtr.distance.previousSourceID { // Optional condition: if previous shortestPathsWithMaxCost(...) call has changed shortest path tree
// Update new shortest distance
tempPtr.distance.distance = vertex.distance.distance + cost
tempPtr.distance.previousOrderPos = previousOrderPos
tempPtr.distance.previousSourceID = source
pqComparator.Push(tempPtr)
}
}
}
}