github.com/LdDl/ch@v1.7.8/vertex.go (about) 1 package ch 2 3 // Vertex All information about vertex 4 type Vertex struct { 5 inIncidentEdges []incidentEdge 6 outIncidentEdges []incidentEdge 7 distance Distance 8 9 vertexNum int64 10 Label int64 11 12 orderPos int64 13 delNeighbors int 14 importance int 15 contracted bool 16 } 17 18 // OrderPos Returns order position (in terms of contraction hierarchies) of vertex 19 func (vertex *Vertex) OrderPos() int64 { 20 return vertex.orderPos 21 } 22 23 // SetOrderPos Sets order position (in terms of contraction hierarchies) for vertex 24 func (vertex *Vertex) SetOrderPos(orderPos int64) { 25 vertex.orderPos = orderPos 26 } 27 28 // Importance Returns importance (in terms of contraction hierarchies) of vertex 29 func (vertex *Vertex) Importance() int { 30 return vertex.importance 31 } 32 33 // SetImportance Sets order position (in terms of contraction hierarchies) for vertex 34 func (vertex *Vertex) SetImportance(importance int) { 35 vertex.importance = importance 36 } 37 38 // MakeVertex Create vertex with label 39 func MakeVertex(label int64) *Vertex { 40 return &Vertex{ 41 Label: label, 42 delNeighbors: 0, 43 distance: NewDistance(), 44 contracted: false, 45 } 46 } 47 48 // computeImportance Update importance of vertex 49 func (vertex *Vertex) computeImportance() { 50 // Worst possible shortcuts number through the vertex is: NumWorstShortcuts = NumIncomingEdges*NumOutcomingEdges 51 shortcutCover := len(vertex.inIncidentEdges) * len(vertex.outIncidentEdges) 52 // Number of total incident edges is: NumIncomingEdges+NumOutcomingEdges 53 incidentEdgesNum := len(vertex.inIncidentEdges) + len(vertex.outIncidentEdges) 54 // Edge difference is between NumWorstShortcuts and TotalIncidentEdgesNum 55 edgeDiff := shortcutCover - incidentEdgesNum 56 // [+] Spatial diversity heuristic: for each vertex maintain a count of the number of neighbors that have already been contracted [vertex.delNeighbors], and add this to the summary importance 57 // note: the more neighbours have already been contracted, the later this vertex will be contracted in further. 58 // [+] Bidirection edges heuristic: for each vertex check how many bidirected incident edges vertex has. 59 // note: the more bidirected incident edges == less important vertex is. 60 vertex.importance = edgeDiff + incidentEdgesNum + vertex.delNeighbors - vertex.bidirectedEdges() 61 } 62 63 // bidirectedEdges Number of bidirected edges 64 func (vertex *Vertex) bidirectedEdges() int { 65 hash := make(map[int64]struct{}, len(vertex.inIncidentEdges)) 66 for _, e := range vertex.inIncidentEdges { 67 hash[e.vertexID] = struct{}{} 68 } 69 ans := 0 70 for i := range vertex.outIncidentEdges { 71 if _, ok := hash[vertex.outIncidentEdges[i].vertexID]; ok { 72 ans++ 73 } 74 } 75 return ans 76 } 77 78 // Distance Information about contraction between source vertex and contraction vertex 79 // distance - used in Dijkstra local searches 80 // previousOrderPos - previous contraction order (shortest path tree) 81 // previousSourceID - previously found source vertex (shortest path tree) 82 type Distance struct { 83 previousOrderPos int64 84 previousSourceID int64 85 distance float64 86 } 87 88 // NewDistance Constructor for Distance 89 func NewDistance() Distance { 90 return Distance{ 91 previousOrderPos: -1, 92 previousSourceID: -1, 93 distance: Infinity, 94 } 95 } 96 97 // FindVertex Returns index of vertex in graph 98 // 99 // labelExternal - User defined ID of vertex 100 // If vertex is not found then returns (-1; false) 101 // 102 func (graph *Graph) FindVertex(labelExternal int64) (idx int64, ok bool) { 103 idx, ok = graph.mapping[labelExternal] 104 if !ok { 105 return -1, ok 106 } 107 return 108 }