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  }