github.com/LdDl/ch@v1.7.8/dijkstra_local.go (about) 1 package ch 2 3 const ( 4 Infinity = float64(^uint(0) >> 1) 5 // Infinity = Infinity 6 ) 7 8 // shortestPathsWithMaxCost Internal implementation of Dijkstra's algorithm to compute witness paths 9 func (graph *Graph) shortestPathsWithMaxCost(source int64, maxcost float64, previousOrderPos int64) { 10 // Heap to store traveled distance 11 pqComparator := &distanceHeap{} 12 pqComparator.Push(&graph.Vertices[source]) 13 14 // Instead of inializing distances to Infinity every single shortestPathsWithMaxCost(...) call we can do following 15 // Set dist[source] -> 0 (as usual) 16 graph.Vertices[source].distance.distance = 0 17 // Set order position to previously contracted (excluded from graph) vertex 18 graph.Vertices[source].distance.previousOrderPos = previousOrderPos 19 // Set source to identifier of vertex for which shortestPathsWithMaxCost(...) has been called 20 graph.Vertices[source].distance.previousSourceID = source 21 22 for pqComparator.Len() != 0 { 23 vertex := pqComparator.Pop() 24 // Do not consider any vertex has been excluded earlier 25 if vertex.contracted { 26 continue 27 } 28 // Once a vertex is settled with a shortest path score greater than max cost, search stops. 29 if vertex.distance.distance > maxcost { 30 return 31 } 32 // Edge relaxation 33 vertexList := vertex.outIncidentEdges 34 for i := range vertexList { 35 temp := vertexList[i].vertexID 36 cost := vertexList[i].weight 37 tempPtr := &graph.Vertices[temp] 38 // Do not consider any vertex has been excluded earlier 39 if tempPtr.contracted { 40 continue 41 } 42 alt := vertex.distance.distance + cost 43 if tempPtr.distance.distance > alt || // usual condition for Dijkstra's algorithm 44 vertex.distance.previousOrderPos != tempPtr.distance.previousOrderPos || // Optional condition: if previous shortestPathsWithMaxCost(...) call has changed shortest path tree 45 vertex.distance.previousSourceID != tempPtr.distance.previousSourceID { // Optional condition: if previous shortestPathsWithMaxCost(...) call has changed shortest path tree 46 // Update new shortest distance 47 tempPtr.distance.distance = vertex.distance.distance + cost 48 tempPtr.distance.previousOrderPos = previousOrderPos 49 tempPtr.distance.previousSourceID = source 50 pqComparator.Push(tempPtr) 51 } 52 } 53 } 54 }