/** Introduces the necessary shortcuts for endNode v in the graph. */ int addShortcuts(int v) { shortcuts.clear(); findShortcuts(addScHandler.setNode(v)); int tmpNewShortcuts = 0; for (Shortcut sc : shortcuts.keySet()) { boolean updatedInGraph = false; // check if we need to update some existing shortcut in the graph EdgeSkipIterator iter = vehicleOutExplorer.setBaseNode(sc.from); while (iter.next()) { if (iter.isShortcut() && iter.getAdjNode() == sc.to && prepareEncoder.canBeOverwritten(iter.getFlags(), sc.flags) && iter.getDistance() > sc.weight) { iter.setFlags(sc.flags); iter.setSkippedEdges(sc.skippedEdge1, sc.skippedEdge2); iter.setDistance(sc.weight); setOrigEdgeCount(iter.getEdge(), sc.originalEdges); updatedInGraph = true; break; } } if (!updatedInGraph) { EdgeSkipIterState edgeState = g.shortcut(sc.from, sc.to); edgeState.setDistance(sc.weight).setFlags(sc.flags); edgeState.setSkippedEdges(sc.skippedEdge1, sc.skippedEdge2); setOrigEdgeCount(edgeState.getEdge(), sc.originalEdges); tmpNewShortcuts++; } } return tmpNewShortcuts; }
/** * Calculates the priority of endNode v without changing the graph. Warning: the calculated * priority must NOT depend on priority(v) and therefor findShortcuts should also not depend on * the priority(v). Otherwise updating the priority before contracting in contractNodes() could * lead to a slowishor even endless loop. */ int calculatePriority(int v) { // set of shortcuts that would be added if endNode v would be contracted next. findShortcuts(calcScHandler.setNode(v)); // System.out.println(v + "\t " + tmpShortcuts); // # huge influence: the bigger the less shortcuts gets created and the faster is the // preparation // // every endNode has an 'original edge' number associated. initially it is r=1 // when a new shortcut is introduced then r of the associated edges is summed up: // r(u,w)=r(u,v)+r(v,w) now we can define // originalEdgesCount = σ(v) := sum_{ (u,w) ∈ shortcuts(v) } of r(u, w) int originalEdgesCount = calcScHandler.originalEdgesCount; // for (Shortcut sc : tmpShortcuts) { // originalEdgesCount += sc.originalEdges; // } // # lowest influence on preparation speed or shortcut creation count // (but according to paper should speed up queries) // // number of already contracted neighbors of v int contractedNeighbors = 0; int degree = 0; EdgeSkipIterator iter = calcPrioAllExplorer.setBaseNode(v); while (iter.next()) { degree++; if (iter.isShortcut()) contractedNeighbors++; } // from shortcuts we can compute the edgeDifference // # low influence: with it the shortcut creation is slightly faster // // |shortcuts(v)| − |{(u, v) | v uncontracted}| − |{(v, w) | v uncontracted}| // meanDegree is used instead of outDegree+inDegree as if one endNode is in both directions // only one bucket memory is used. Additionally one shortcut could also stand for two // directions. int edgeDifference = calcScHandler.shortcuts - degree; // according to the paper do a simple linear combination of the properties to get the priority. // this is the current optimum for unterfranken: return 10 * edgeDifference + originalEdgesCount + contractedNeighbors; }