public LinkedList<HHStaticEdge> dijkstraPath( HHStaticGraph graph, int sourceId, int targetId, int lvl) { HHStaticVertex source = graph.getVertex(sourceId); HHStaticVertex target = graph.getVertex(targetId); int numSettled = 0; // clear queue queue[FWD].clear(); discoveredVertices[FWD].clear(); // enqueue source and target DiscoveredVertex s = new DiscoveredVertex(source, null, null, new HeapKey(0, 0, source.getNeighborhood(0))); queue[FWD].insert(s); discoveredVertices[FWD].put(source.getId(), s); while (!queue[FWD].isEmpty()) { DiscoveredVertex u = queue[FWD].extractMin(); numSettled++; if (u.vertex.getId() == target.getId()) { LinkedList<HHStaticEdge> edges = new LinkedList<HHStaticEdge>(); while (u.parent != null) { edges.addFirst(u.edgeToParent); u = u.parent; } return edges; } for (HHStaticEdge e : u.vertex.getAdjacentEdges(lvl)) { if (e.getDirection(FWD) && !e.isShortcut()) { DiscoveredVertex v = discoveredVertices[FWD].get(e.getTarget().getId()); HeapKey key = new HeapKey(u.key.distance + e.getWeight(), 0, 0); if (v == null) { v = new DiscoveredVertex(e.getTarget(), e, u, key); queue[FWD].insert(v); discoveredVertices[FWD].put(v.vertex.getId(), v); } else if (key.compareTo(v.key) < 0) { queue[FWD].decreaseKey(v, key); v.parent = u; v.edgeToParent = e; } } } } return null; }
private int shortestPathDtNoDowngradedNo( HHStaticGraph graph, int sourceId, int targetId, LinkedList<HHStaticEdge> buffFwd, LinkedList<HHStaticEdge> buffBwd, LinkedList<HHStaticEdge> buffSearchSpace) { HHStaticVertex source = graph.getVertex(sourceId); HHStaticVertex target = graph.getVertex(targetId); // tentative shortest distance (upper bound) int d = Integer.MAX_VALUE; DiscoveredVertex minSearchScopeHit = null; // clear queue queue[FWD].clear(); queue[BWD].clear(); discoveredVertices[FWD].clear(); discoveredVertices[BWD].clear(); // enqueue source and target DiscoveredVertex s = new DiscoveredVertex(source, null, null, new HeapKey(0, 0, source.getNeighborhood(0))); DiscoveredVertex t = new DiscoveredVertex(target, null, null, new HeapKey(0, 0, target.getNeighborhood(0))); queue[FWD].insert(s); queue[BWD].insert(t); discoveredVertices[FWD].put(source.getId(), s); discoveredVertices[BWD].put(target.getId(), t); int direction = FWD; while (!queue[FWD].isEmpty() || !queue[BWD].isEmpty()) { // switch search direction if queue of current direction is empty if (queue[direction].isEmpty()) { direction = (direction + 1) % 2; } // dequeue vertex u DiscoveredVertex u = queue[direction].extractMin(); u.heapIdx = HEAP_IDX_SETTLED; // abort criteria for current direction if (u.key.distance > d) { queue[direction].clear(); continue; } // adjust lower bound if u was settled in both directions DiscoveredVertex u_ = discoveredVertices[(direction + 1) % 2].get(u.vertex.getId()); if (u_ != null && u_.heapIdx == HEAP_IDX_SETTLED) { int d_ = u.key.distance + u_.key.distance; if (d_ < d) { minSearchScopeHit = u; d = d_; } } if (u.key.gap >= INFINITY_2) { u.key.gap = u.vertex.getNeighborhood(u.key.level); } // relax adjacent edges for (HHStaticEdge e : u.vertex.getAdjacentEdges(u.key.level)) { // if edge is not in graph for current direction -> skip if (!e.getDirection(direction)) continue; int gap_ = u.key.gap; // switch to next level int lvl = u.key.level; while (e.getWeight() > gap_ && lvl < u.vertex.getLevel()) { lvl++; gap_ = u.vertex.getNeighborhood(lvl); } // check if edge's level is high enough if (!e.isLvlGEQ(lvl)) { continue; } // restriction 1 (only local search) if (e.getWeight() > gap_) { continue; } // restriction 2 (don't leave core) if (u.vertex.getNeighborhood(lvl) < INFINITY_2 && e.getTarget().getNeighborhood(lvl) == INFINITY_1) { continue; } if (gap_ < INFINITY_2) { gap_ = gap_ - e.getWeight(); } // only for debug buffSearchSpace.add(e); // adjust v's heap key, enqueue if not already on heap HeapKey key = new HeapKey(u.key.distance + e.getWeight(), lvl, gap_); DiscoveredVertex v = discoveredVertices[direction].get(e.getTarget().getId()); if (v != null) { if (key.compareTo(v.key) < 0) { queue[direction].decreaseKey(v, key); v.parent = u; v.edgeToParent = e; } } else { v = new DiscoveredVertex(e.getTarget(), e, u, key); discoveredVertices[direction].put(v.vertex.getId(), v); queue[direction].insert(v); } } direction = (direction + 1) % 2; } if (d != Integer.MAX_VALUE) { if (minSearchScopeHit != null) { // this if check can never happen only for the warning settings // and the broken window story.. addEdgesToAllParents( discoveredVertices[FWD].get(minSearchScopeHit.vertex.getId()), buffFwd); addEdgesToAllParents( discoveredVertices[BWD].get(minSearchScopeHit.vertex.getId()), buffBwd); } } return d; }