21 package org.matsim.core.router;
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.List;
28 import org.apache.logging.log4j.LogManager;
29 import org.apache.logging.log4j.Logger;
88 private final static Logger
log = LogManager.getLogger(
Dijkstra.class);
124 final boolean pruneDeadEnds;
172 this.nodeData =
new HashMap<>((int)(network.
getNodes().size() * 1.1), 0.95f);
174 if (preProcessData != null) {
176 this.pruneDeadEnds =
false;
177 log.warn(
"The preprocessing data provided to router class Dijkstra contains no data! Please execute its run(...) method first!");
178 log.warn(
"Running without dead-end pruning.");
180 this.pruneDeadEnds =
true;
183 this.pruneDeadEnds =
false;
192 if (modeRestriction == null) {
193 this.modeRestriction = null;
195 this.modeRestriction = modeRestriction.toArray(
new String[modeRestriction.size()]);
220 checkNodeBelongToNetwork(fromNode);
221 checkNodeBelongToNetwork(toNode);
224 this.person = person2;
225 this.vehicle = vehicle2;
227 if (this.pruneDeadEnds) {
232 initFromNode(fromNode, toNode, startTime, pendingNodes);
234 Node foundToNode = searchLogic(fromNode, toNode, pendingNodes, person2, vehicle2 );
236 if (foundToNode == null)
return null;
239 double arrivalTime = outData.
getTime();
242 return constructPath(fromNode, foundToNode, startTime, arrivalTime);
250 void checkNodeBelongToNetwork(
Node node) {
252 throw new IllegalArgumentException(
"The nodes passed as parameters are not part of the network stored by "+
253 getClass().getSimpleName() +
": the validity of the results cannot be guaranteed. Aborting!");
280 if (this.heap == null) {
282 for (
Node node : this.network.
getNodes().values()) this.heap.
add(node, 0.);
300 boolean stillSearching =
true;
302 while (stillSearching) {
305 if (outNode == null) {
306 log.warn(
"No route was found from node " + fromNode.
getId() +
" to node " + toNode.
getId() +
". " + createInfoMessage( person, vehicle ) +
"Some possible reasons:" );
307 log.warn(
" * Network is not connected. Run NetworkCleaner().") ;
308 log.warn(
" * Network for considered mode does not even exist. Modes need to be entered for each link in network.xml.");
309 log.warn(
" * Network for considered mode is not connected to starting or ending point of route. Setting insertingAccessEgressWalk to true may help.");
310 log.warn(
"This will now return null, but it may fail later with a null pointer exception.");
314 if (outNode == toNode) {
315 stillSearching =
false;
317 relaxNode(outNode, toNode, pendingNodes);
322 static StringBuilder createInfoMessage(
Person person,
Vehicle vehicle ){
323 StringBuilder strb =
new StringBuilder();
324 boolean flag = false ;
325 if ( person != null ) {
326 strb.append( person.getId() );
329 if ( vehicle !=null ) {
330 strb.append( vehicle.
getId() );
350 List<Node> nodes =
new ArrayList<>();
351 List<Link> links =
new ArrayList<>();
353 nodes.add(0, toNode);
355 if (tmpLink != null) {
357 links.add(0, tmpLink);
361 links.add(0, tmpLink);
367 Path path =
new Path(nodes, links, arrivalTime - startTime, toNodeData.
getCost());
383 void initFromNode(
final Node fromNode,
final Node toNode,
final double startTime,
386 visitNode(fromNode, data, pendingNodes, startTime, 0, null);
403 double currTime = outData.
getTime();
404 double currCost = outData.
getCost();
405 if (this.pruneDeadEnds) {
409 relaxNodeLogic(l, pendingNodes, currTime, currCost, toNode, ddOutData);
413 relaxNodeLogic(l, pendingNodes, currTime, currCost, toNode, null);
424 if (this.pruneDeadEnds) {
433 if ((ddData.getDeadEndEntryNode() == null)
434 || (ddOutData.getDeadEndEntryNode() != null)
435 || ((this.deadEndEntryNode != null)
436 && (this.deadEndEntryNode.
getId() == ddData.getDeadEndEntryNode().getId()))) {
469 final double currCost,
final Node toNode) {
471 final double travelTime = this.timeFunction.
getLinkTravelTime(l, currTime, this.person, this.vehicle);
475 visitNode(n, data, pendingNodes, currTime + travelTime, currCost + travelCost, l);
479 final double nCost = data.
getCost();
480 final double totalCost = currCost + travelCost;
481 if (totalCost < nCost) {
482 revisitNode(n, data, pendingNodes, currTime + travelTime, totalCost, l);
484 }
else if (totalCost == nCost) {
488 if (prevLink != null && prevLink.
getId().compareTo(l.
getId()) > 0) {
489 revisitNode(n, data, pendingNodes, currTime + travelTime, totalCost, l);
502 if (this.modeRestriction == null) {
505 for (String mode : this.modeRestriction) {
531 final double time,
final double cost,
final Link outLink) {
554 final double time,
final double cost,
final Link outLink) {
565 this.iterationID = Integer.MIN_VALUE + 1;
610 this.nodeData.put(n.
getId(), r);
void resetNetworkVisited()
void visitNode(final Node n, final DijkstraNodeData data, final RouterPriorityQueue< Node > pendingNodes, final double time, final double cost, final Link outLink)
Map< Id< Node >, ? extends Node > getNodes()
DijkstraNodeData getData(final Node n)
double getPriority(final DijkstraNodeData data)
boolean canPassLink(final Link link)
void augmentIterationId()
boolean addToPendingNodes(final Link l, final Node n, final RouterPriorityQueue< Node > pendingNodes, final double currTime, final double currCost, final Node toNode)
RouterPriorityQueue< Node > heap
Path constructPath(Node fromNode, Node toNode, double startTime, double arrivalTime)
double getLinkTravelTime(Link link, double time, Person person, Vehicle vehicle)
void setModeRestriction(final Set< String > modeRestriction)
DeadEndData getNodeData(final Node n)
void revisitNode(final Node n, final DijkstraNodeData data, final RouterPriorityQueue< Node > pendingNodes, final double time, final double cost, final Link outLink)
double getLinkTravelDisutility(final Link link, final double time, final Person person, final Vehicle vehicle)
boolean decreaseKey(E value, double priority)
PreProcessDijkstra.DeadEndData getPreProcessData(final Node n)
void visit(final Link comingFrom, final double cost, final double time, final int iterID)
Dijkstra(final Network network, final TravelDisutility costFunction, final TravelTime timeFunction, final PreProcessDijkstra preProcessData)
final PreProcessDijkstra preProcessData
final TravelDisutility costFunction
final TravelTime timeFunction
final Vehicle getVehicle()
Path calcLeastCostPath(final Node fromNode, final Node toNode, final double startTime, final Person person2, final Vehicle vehicle2)
String [] modeRestriction
Dijkstra(final Network network, final TravelDisutility costFunction, final TravelTime timeFunction)
Map< Id< Link >, ? extends Link > getOutLinks()
boolean isVisited(final int iterID)
void relaxNode(final Node outNode, final Node toNode, final RouterPriorityQueue< Node > pendingNodes)
boolean add(final E o, final double priority)
DijkstraNodeData createNodeData()
Set< String > getAllowedModes()