1 package org.matsim.core.router.speedy;
3 import com.google.common.base.Preconditions;
12 import java.util.Arrays;
13 import java.util.Iterator;
14 import java.util.NoSuchElementException;
33 private final double[]
data;
39 private final NodeMinHeap
pq;
45 this.data =
new double[graph.nodeCount * 3];
46 this.comingFrom =
new int[graph.nodeCount];
47 this.fromLink =
new int[graph.nodeCount];
48 this.comingFromLink =
new int[graph.linkCount];
49 this.pq =
new NodeMinHeap(graph.nodeCount, this::getCost, this::setCost);
55 this.
calculate(startNode, startTime, person, vehicle, (node, arrTime, cost, distance, depTime) ->
false);
59 Arrays.fill(this.data, Double.POSITIVE_INFINITY);
60 Arrays.fill(this.comingFrom, -1);
61 Arrays.fill(this.fromLink, -1);
63 setData(startNode, 0, startTime, 0);
66 this.pq.insert(startNode);
68 while (!this.pq.isEmpty()) {
69 final int nodeIdx = this.pq.poll();
71 Preconditions.checkState(currTime != Double.POSITIVE_INFINITY,
"Undefined Time");
72 double currCost =
getCost(nodeIdx);
75 if (stopCriterion.
stop(nodeIdx, currTime, currCost, currDistance, startTime)) {
79 this.
outLI.reset(nodeIdx);
80 while (this.
outLI.next()) {
81 int linkIdx = this.
outLI.getLinkIndex();
82 Link link = this.graph.getLink(linkIdx);
83 int toNode = this.
outLI.getToNodeIndex();
86 double newTime = currTime + travelTime;
89 double oldCost =
getCost(toNode);
90 if (Double.isFinite(oldCost)) {
91 if (newCost < oldCost) {
92 this.pq.decreaseKey(toNode, newCost);
94 this.comingFrom[toNode] = nodeIdx;
95 this.fromLink[toNode] = linkIdx;
99 this.pq.insert(toNode);
100 this.comingFrom[toNode] = nodeIdx;
101 this.fromLink[toNode] = linkIdx;
110 Arrays.fill(this.comingFromLink, -1);
111 for (
int i = 0; i < graph.nodeCount; i++) {
112 Node node = graph.getNode(i);
115 while (this.
outLI.next()) {
116 int previousLinkIdx = fromLink[i];
117 this.comingFromLink[
outLI.getLinkIndex()] = previousLinkIdx;
124 this.
calculate(arrivalNode, arrivalTime, person, vehicle, (node, arrTime, cost, distance, depTime) ->
false);
128 Arrays.fill(this.data, Double.POSITIVE_INFINITY);
129 Arrays.fill(this.comingFrom, -1);
130 Arrays.fill(this.fromLink, -1);
132 setData(arrivalNode, 0, arrivalTime, 0);
135 this.pq.insert(arrivalNode);
137 while (!this.pq.isEmpty()) {
138 final int nodeIdx = this.pq.poll();
140 Preconditions.checkState(currTime != Double.POSITIVE_INFINITY,
"Undefined Time");
141 double currCost =
getCost(nodeIdx);
144 if (stopCriterion.
stop(nodeIdx, arrivalTime, currCost, currDistance, currTime)) {
148 this.
inLI.reset(nodeIdx);
149 while (this.
inLI.next()) {
150 int linkIdx = this.
inLI.getLinkIndex();
151 Link link = this.graph.getLink(linkIdx);
152 int fromNode = this.
inLI.getFromNodeIndex();
155 double newTime = currTime - travelTime;
158 double oldCost =
getCost(fromNode);
159 if (Double.isFinite(oldCost)) {
160 if (newCost < oldCost) {
161 this.pq.decreaseKey(fromNode, newCost);
163 this.comingFrom[fromNode] = nodeIdx;
164 this.fromLink[fromNode] = linkIdx;
168 this.pq.insert(fromNode);
169 this.comingFrom[fromNode] = nodeIdx;
170 this.fromLink[fromNode] = linkIdx;
179 Arrays.fill(this.comingFromLink, -1);
180 for (
int i = 0; i < graph.nodeCount; i++) {
181 Node node = graph.getNode(i);
184 while (this.
inLI.next()) {
185 int previousLinkIdx = fromLink[i];
186 this.comingFromLink[
inLI.getLinkIndex()] = previousLinkIdx;
194 for (
int i = 0; i < data.length / 3; i++) {
195 Node uncoloredNode = graph.getNode(i);
196 if (uncoloredNode != null) {
199 if (uncoloredNode.
getId().index() != i) {
200 int uncoloredIndex = uncoloredNode.
getId().index();
201 double uncoloredCost =
getCost(uncoloredIndex);
202 double coloredCost =
getCost(i);
204 if (coloredCost < uncoloredCost) {
206 this.comingFrom[uncoloredIndex] = this.comingFrom[i];
207 this.fromLink[uncoloredIndex] = this.fromLink[i];
215 return this.data[nodeIndex * 3];
219 return this.data[nodeIndex * 3 + 1];
224 if (Double.isInfinite(time)) {
231 return this.data[nodeIndex * 3 + 2];
234 private void setCost(
int nodeIndex,
double cost) {
235 this.data[nodeIndex * 3] = cost;
238 private void setData(
int nodeIndex,
double cost,
double time,
double distance) {
239 int index = nodeIndex * 3;
240 this.data[index] = cost;
241 this.data[index + 1] = time;
242 this.data[index + 2] = distance;
255 boolean stop(
int nodeIndex,
double arrivalTime,
double travelCost,
double distance,
double departureTime);
267 public boolean stop(
int nodeIndex,
double arrivalTime,
double travelCost,
double distance,
double departureTime) {
268 return Math.abs(arrivalTime - departureTime) >= this.limit;
281 public boolean stop(
int nodeIndex,
double arrivalTime,
double travelCost,
double distance,
double departureTime) {
282 return distance >= this.limit;
292 current = startNode.
getId().index();
297 current = comingFrom[current];
299 throw new NoSuchElementException();
301 return graph.getNode(current);
306 return comingFrom[current] >= 0;
313 private boolean firstStep =
true;
318 current = fromLink[startNode.
getId().index()];
325 return graph.getLink(current);
327 current = comingFromLink[current];
329 throw new NoSuchElementException();
331 return graph.getLink(current);
336 return current >= 0 && (comingFromLink[current] >= 0 || firstStep);
final boolean hasTurnRestrictions
LeastCostPathTree(SpeedyGraph graph, TravelTime tt, TravelDisutility td)
LinkPathIterator getLinkPathIterator(Node node)
final SpeedyGraph.LinkIterator outLI
TravelDistanceStopCriterion(double limit)
PathIterator(Node startNode)
final TravelDisutility td
boolean stop(int nodeIndex, double arrivalTime, double travelCost, double distance, double departureTime)
double getLinkTravelTime(Link link, double time, Person person, Vehicle vehicle)
PathIterator getNodePathIterator(Node node)
boolean stop(int nodeIndex, double arrivalTime, double travelCost, double distance, double departureTime)
double getLinkTravelDisutility(final Link link, final double time, final Person person, final Vehicle vehicle)
void calculateBackwards(int arrivalNode, double arrivalTime, Person person, Vehicle vehicle)
OptionalTime getTime(int nodeIndex)
void calculate(int startNode, double startTime, Person person, Vehicle vehicle)
double getTimeRaw(int nodeIndex)
void setData(int nodeIndex, double cost, double time, double distance)
static OptionalTime defined(double seconds)
LinkPathIterator(Node startNode)
final int [] comingFromLink
double getCost(int nodeIndex)
LinkIterator getInLinkIterator()
double getDistance(int nodeIndex)
void calculateBackwards(int arrivalNode, double arrivalTime, Person person, Vehicle vehicle, StopCriterion stopCriterion)
final SpeedyGraph.LinkIterator inLI
TravelTimeStopCriterion(double limit)
static OptionalTime undefined()
void consolidateColoredNodes()
void calculate(int startNode, double startTime, Person person, Vehicle vehicle, StopCriterion stopCriterion)
LinkIterator getOutLinkIterator()
void setCost(int nodeIndex, double cost)
boolean stop(int nodeIndex, double arrivalTime, double travelCost, double distance, double departureTime)