@Override public synchronized LeastCostPathCalculator createPathCalculator(final Network network, final TravelDisutility travelCosts, final TravelTime travelTimes) { if (this.usePreProcessData) { PreProcessDijkstra preProcessDijkstra = this.preProcessData.get(network); if (preProcessDijkstra == null) { preProcessDijkstra = new PreProcessDijkstra(); preProcessDijkstra.run(network); this.preProcessData.put(network, preProcessDijkstra); } return new Dijkstra(network, travelCosts, travelTimes, preProcessDijkstra); } return new Dijkstra(network, travelCosts, travelTimes); } }
checkNodeBelongToNetwork(fromNode); checkNodeBelongToNetwork(toNode); augmentIterationId(); // this call makes the class not thread-safe this.person = person2; this.vehicle = vehicle2; this.deadEndEntryNode = getPreProcessData(toNode).getDeadEndEntryNode(); RouterPriorityQueue<Node> pendingNodes = (RouterPriorityQueue<Node>) createRouterPriorityQueue(); initFromNode(fromNode, toNode, startTime, pendingNodes); Node foundToNode = searchLogic(fromNode, toNode, pendingNodes); DijkstraNodeData outData = getData(foundToNode); double arrivalTime = outData.getTime(); return constructPath(fromNode, foundToNode, startTime, arrivalTime);
/** * Initializes the first node of a route. * * @param fromNode * The Node to be initialized. * @param toNode * The Node at which the route should end. * @param startTime * The time we start routing. * @param pendingNodes * The pending nodes so far. */ /*package*/ void initFromNode(final Node fromNode, final Node toNode, final double startTime, final RouterPriorityQueue<Node> pendingNodes) { DijkstraNodeData data = getData(fromNode); visitNode(fromNode, data, pendingNodes, startTime, 0, null); }
/** * Expands the given Node in the routing algorithm; may be overridden in * sub-classes. * * @param outNode * The Node to be expanded. * @param toNode * The target Node of the route. * @param pendingNodes * The set of pending nodes so far. */ protected void relaxNode(final Node outNode, final Node toNode, final RouterPriorityQueue<Node> pendingNodes) { DijkstraNodeData outData = getData(outNode); double currTime = outData.getTime(); double currCost = outData.getCost(); if (this.pruneDeadEnds) { PreProcessDijkstra.DeadEndData ddOutData = getPreProcessData(outNode); for (Link l : outNode.getOutLinks().values()) { relaxNodeLogic(l, pendingNodes, currTime, currCost, toNode, ddOutData); } } else { // this.pruneDeadEnds == false for (Link l : outNode.getOutLinks().values()) { relaxNodeLogic(l, pendingNodes, currTime, currCost, toNode, null); } } }
final DijkstraNodeData data = getData(n); if (!data.isVisited(getIterationId())) { visitNode(n, data, pendingNodes, currTime + travelTime, currCost + travelCost, l); return true; final double totalCost = currCost + travelCost; if (totalCost < nCost) { revisitNode(n, data, pendingNodes, currTime + travelTime, totalCost, l); return true; } else if (totalCost == nCost) { revisitNode(n, data, pendingNodes, currTime + travelTime, totalCost, l); return true;
@Test public void testPersonAvailableForDisutility_Dijkstra() { Fixture f = new Fixture(); Dijkstra router = new Dijkstra(f.network, f.costFunction, new FreeSpeedTravelTime()); router.calcLeastCostPath( f.network.getNodes().get(Id.create("2", Node.class)), f.network.getNodes().get(Id.create("1", Node.class)), 07*3600, f.person, f.vehicle); // hopefully there was no Exception until here... Assert.assertEquals(22, f.costFunction.cnt); // make sure the costFunction was actually used }
/** * Logic that was previously located in the relaxNode(...) method. * By doing so, the FastDijkstra can overwrite relaxNode without copying the logic. */ /*package*/ void relaxNodeLogic(final Link l, final RouterPriorityQueue<Node> pendingNodes, final double currTime, final double currCost, final Node toNode, final PreProcessDijkstra.DeadEndData ddOutData) { if (this.pruneDeadEnds) { if (canPassLink(l)) { Node n = l.getToNode(); PreProcessDijkstra.DeadEndData ddData = getPreProcessData(n); /* IF the current node n is not in a dead end * OR it is in the same dead end as the fromNode * OR it is in the same dead end as the toNode * THEN we add the current node to the pending nodes */ if ((ddData.getDeadEndEntryNode() == null) || (ddOutData.getDeadEndEntryNode() != null) || ((this.deadEndEntryNode != null) && (this.deadEndEntryNode.getId() == ddData.getDeadEndEntryNode().getId()))) { addToPendingNodes(l, n, pendingNodes, currTime, currCost, toNode); } } } else { if (canPassLink(l)) { addToPendingNodes(l, l.getToNode(), pendingNodes, currTime, currCost, toNode); } } }
@Override public Path calcLeastCostPath(final Node fromNode, final Node toNode, final double startTime, final Person person, final Vehicle vehicle) { this.fastRouter.initialize(); this.routingNetwork.initialize(); RoutingNetworkNode routingNetworkFromNode = this.routingNetwork.getNodes().get(fromNode.getId()); RoutingNetworkNode routingNetworkToNode = this.routingNetwork.getNodes().get(toNode.getId()); return super.calcLeastCostPath(routingNetworkFromNode, routingNetworkToNode, startTime, person, vehicle); }
/** * Returns the data for the given Node. Creates a new AStarNodeData if none exists yet. * * @param n The node for which to return the data for.. * @return The data to the given Node */ @Override protected AStarNodeData getData(final Node n) { return (AStarNodeData) super.getData(n); }
/*package*/ @Override void checkNodeBelongToNetwork(Node node) { if (node instanceof ImaginaryNode) { ImaginaryNode imaginaryNode = (ImaginaryNode) node; for (InitialNode initialNode : imaginaryNode.initialNodes) super.checkNodeBelongToNetwork(initialNode.node); } else super.checkNodeBelongToNetwork(node); }
/** * Returns the data for the given node. Creates a new NodeData if none exists * yet. * * @param n * The Node for which to return the data. * @return The data for the given Node */ protected DijkstraNodeData getData(final Node n) { DijkstraNodeData r = this.nodeData.get(n.getId()); if (null == r) { r = createNodeData(); this.nodeData.put(n.getId(), r); } return r; }
@Override /*package*/ RouterPriorityQueue<? extends Node> createRouterPriorityQueue() { /* * Re-use existing BinaryMinHeap instead of creating a new one. For large networks (> 10^6 nodes and links) this reduced * the computation time by 40%! cdobler, oct'15 */ if (this.routingNetwork instanceof ArrayRoutingNetwork) { int size = this.routingNetwork.getNodes().size(); if (this.heap == null || this.maxSize != size) { this.maxSize = size; this.heap = new BinaryMinHeap<>(maxSize); return this.heap; } else { this.heap.reset(); return this.heap; } // int maxSize = this.routingNetwork.getNodes().size(); // return new BinaryMinHeap<ArrayRoutingNetworkNode>(maxSize); } else { return super.createRouterPriorityQueue(); } }
/*package*/ static Path createPath(Dijkstra dijsktra, Node fromNode, Node toNode) { Path path = dijsktra.calcLeastCostPath(fromNode, toNode, 0., null, null); if (path == null) return path; for(Node node : path.nodes) log.info("\t\t" + node.getId()); for(Link link : path.links) log.info("\t\t" + link.getId()); log.info(path.travelCost); log.info(path.travelTime); return path; }
/** * Resets all nodes in the network as if they have not been visited yet. */ private void resetNetworkVisited() { for (Node node : this.network.getNodes().values()) { DijkstraNodeData data = getData(node); data.resetVisited(); } }
@Override protected LeastCostPathCalculator getLeastCostPathCalculator(final Network network) { FreespeedTravelTimeAndDisutility travelTimeCostCalculator = new FreespeedTravelTimeAndDisutility(new PlanCalcScoreConfigGroup()); return new Dijkstra(network, travelTimeCostCalculator, travelTimeCostCalculator); }
/** * Constructs the path after the algorithm has been run. * * @param fromNode * The node where the path starts. * @param toNode * The node where the path ends. * @param startTime * The time when the trip starts. */ protected Path constructPath(Node fromNode, Node toNode, double startTime, double arrivalTime) { List<Node> nodes = new ArrayList<>(); List<Link> links = new ArrayList<>(); nodes.add(0, toNode); Link tmpLink = getData(toNode).getPrevLink(); if (tmpLink != null) { while (tmpLink.getFromNode() != fromNode) { links.add(0, tmpLink); nodes.add(0, tmpLink.getFromNode()); tmpLink = getData(tmpLink.getFromNode()).getPrevLink(); } links.add(0, tmpLink); nodes.add(0, tmpLink.getFromNode()); } DijkstraNodeData toNodeData = getData(toNode); Path path = new Path(nodes, links, arrivalTime - startTime, toNodeData.getCost()); return path; }
@Test public void testRouteLeg() { Fixture f = new Fixture(); FreespeedTravelTimeAndDisutility freespeed = new FreespeedTravelTimeAndDisutility(-6.0/3600, +6.0/3600, 0.0); LeastCostPathCalculator routeAlgo = new Dijkstra(f.s.getNetwork(), freespeed, freespeed); Person person = PopulationUtils.getFactory().createPerson(Id.create(1, Person.class)); Activity fromAct = PopulationUtils.createActivityFromCoord("h", new Coord(0, 0)); fromAct.setLinkId(Id.create("1", Link.class)); Activity toAct = PopulationUtils.createActivityFromCoord("h", new Coord(0, 3000)); toAct.setLinkId(Id.create("3", Link.class)); final NetworkRoutingModule routingModule = new NetworkRoutingModule( TransportMode.car, f.s.getPopulation().getFactory(), f.s.getNetwork(), routeAlgo); Facility fromFacility = new ActivityWrapperFacility( fromAct ) ; Facility toFacility = new ActivityWrapperFacility( toAct ) ; List<? extends PlanElement> result = routingModule.calcRoute(fromFacility, toFacility, 7.0*3600, person) ; Assert.assertEquals(1, result.size() ); Leg leg = (Leg)result.get(0) ; Assert.assertEquals(100.0, leg.getTravelTime(), 1e-8); Assert.assertTrue(leg.getRoute() instanceof NetworkRoute); }
final Fixture f = new Fixture(); FreespeedTravelTimeAndDisutility freespeed = new FreespeedTravelTimeAndDisutility(-6.0/3600, +6.0/3600, 0.0); LeastCostPathCalculator routeAlgo = new Dijkstra(f.s.getNetwork(), freespeed, freespeed);