MATSIM
AStarLandmarks.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * AStarLandmarks.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2007 by the members listed in the COPYING, *
8  * LICENSE and WARRANTY file. *
9  * email : info at matsim dot org *
10  * *
11  * *********************************************************************** *
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * See also COPYING, LICENSE and WARRANTY file *
18  * *
19  * *********************************************************************** */
20 
21 package org.matsim.core.router;
22 
23 import java.util.ArrayList;
24 import java.util.Iterator;
25 import java.util.List;
26 
35 import org.matsim.vehicles.Vehicle;
36 
66 public class AStarLandmarks extends AStarEuclidean {
67 
68  protected int[] activeLandmarkIndexes;
69 
70  protected final Node[] landmarks;
71 
72  /*package*/ static final int controlInterval = 40;
73  /*package*/ int controlCounter = 0;
74 
85  }
86 
94  this(network, preProcessData, preProcessData.getCostFunction(), timeFunction, 1);
95  }
96 
108  AStarLandmarks(final Network network, final PreProcessLandmarks preProcessData,
109  final TravelDisutility costFunction, final TravelTime timeFunction, final double overdoFactor) {
110  super(network, preProcessData, costFunction, timeFunction, overdoFactor);
111 
112  this.landmarks = preProcessData.getLandmarks();
113  }
114 
115  @Override
116  public Path calcLeastCostPath(final Node fromNode, final Node toNode, final double startTime, final Person person, final Vehicle vehicle) {
117  this.controlCounter = 0; // reset counter for each calculated path!
118 
119  if (this.landmarks.length >= 2) {
120  initializeActiveLandmarks(fromNode, toNode, 2);
121  } else {
122  initializeActiveLandmarks(fromNode, toNode, this.landmarks.length);
123  }
124  return super.calcLeastCostPath(fromNode, toNode, startTime, person, vehicle);
125  }
126 
127  @Override
128  protected void relaxNode(final Node outNode, final Node toNode, final RouterPriorityQueue<Node> pendingNodes) {
129  this.controlCounter++;
130  if (this.controlCounter == controlInterval) {
131  int newLandmarkIndex = checkToAddLandmark(outNode, toNode);
132  if (newLandmarkIndex > 0) {
133  updatePendingNodes(newLandmarkIndex, toNode, pendingNodes);
134  }
135  this.controlCounter = 0;
136  }
137  super.relaxNode(outNode, toNode, pendingNodes);
138  }
139 
147  /*package*/ void initializeActiveLandmarks(final Node fromNode, final Node toNode, final int actLandmarkCount) {
148  final PreProcessLandmarks.LandmarksData fromData = getPreProcessData(fromNode);
149  final PreProcessLandmarks.LandmarksData toData = getPreProcessData(toNode);
150 
151  // Sort the landmarks according to the accuracy of their distance estimation they yield.
152  double[] estTravelTimes = new double[actLandmarkCount];
153  this.activeLandmarkIndexes = new int[actLandmarkCount];
154  for (int i = 0; i < estTravelTimes.length; i++) {
155  estTravelTimes[i] = Double.NEGATIVE_INFINITY;
156  }
157  double tmpTravTime;
158  for (int i = 0; i < this.landmarks.length; i++) {
159  tmpTravTime = estimateRemainingTravelCost(fromData, toData, i);
160  for (int j = 0; j < estTravelTimes.length; j++) {
161  if (tmpTravTime > estTravelTimes[j]) {
162  for (int k = estTravelTimes.length - 1; k > j; k--) {
163  estTravelTimes[k] = estTravelTimes[k - 1];
164  this.activeLandmarkIndexes[k] = this.activeLandmarkIndexes[k - 1];
165  }
166  estTravelTimes[j] = tmpTravTime;
167  this.activeLandmarkIndexes[j] = i;
168  break;
169  }
170  }
171  }
172  }
173 
174  @Override
176  return (PreProcessLandmarks.LandmarksData) super.getPreProcessData(n);
177  }
178 
186  @Override
187  protected double estimateRemainingTravelCost(final Node fromNode, final Node toNode) {
188 
191  double tmpTravCost;
192  double travCost = 0;
193  for (int i = 0, n = this.activeLandmarkIndexes.length; i < n; i++) {
194  tmpTravCost = estimateRemainingTravelCost(fromRole, toRole, this.activeLandmarkIndexes[i]);
195  if (tmpTravCost > travCost) {
196  travCost = tmpTravCost;
197  }
198  }
199  tmpTravCost = super.estimateRemainingTravelCost(fromNode, toNode);
200  if (travCost > tmpTravCost) {
201  return travCost;
202  }
203  /* else */
204  return tmpTravCost;
205  }
206 
216  /*package*/ void updatePendingNodes(final int newLandmarkIndex, final Node toNode, final RouterPriorityQueue<Node> pendingNodes) {
217  Iterator<Node> it = pendingNodes.iterator();
219  List<Double> newEstRemTravCosts = new ArrayList<>();
220  List<Node> nodesToBeUpdated = new ArrayList<>();
221  while (it.hasNext()) {
222  Node node = it.next();
223  AStarNodeData data = getData(node);
225  double estRemTravCost = data.getExpectedRemainingCost();
226  double newEstRemTravCost = estimateRemainingTravelCost(ppRole, toRole, newLandmarkIndex);
227  if (newEstRemTravCost > estRemTravCost) {
228  nodesToBeUpdated.add(node);
229  newEstRemTravCosts.add(newEstRemTravCost);
230  }
231  }
232  for (Node node : nodesToBeUpdated) {
233  pendingNodes.remove(node);
234  }
235  for (int i = 0; i < nodesToBeUpdated.size(); i++) {
236  Node node = nodesToBeUpdated.get(i);
237  AStarNodeData data = getData(node);
238  data.setExpectedRemainingCost(newEstRemTravCosts.get(i));
239  pendingNodes.add(node, getPriority(data));
240  }
241  }
242 
251  /*package*/ int checkToAddLandmark(final Node fromNode, final Node toNode) {
252  double bestTravCostEst = estimateRemainingTravelCost(fromNode, toNode);
255  int bestIndex = -1;
256  for (int i = 0; i < this.landmarks.length; i++) {
257  double tmpTravTime = estimateRemainingTravelCost(fromRole, toRole, i);
258  if (tmpTravTime > bestTravCostEst) {
259  bestIndex = i;
260  bestTravCostEst = tmpTravTime;
261  }
262  }
263  if (bestIndex != -1) {
264  int[] newActiveLandmarks = new int[this.activeLandmarkIndexes.length + 1];
265  System.arraycopy(this.activeLandmarkIndexes, 0, newActiveLandmarks, 0, this.activeLandmarkIndexes.length);
266  newActiveLandmarks[this.activeLandmarkIndexes.length] = bestIndex;
267  this.activeLandmarkIndexes = newActiveLandmarks;
268  }
269  return bestIndex;
270  }
271 
282  final PreProcessLandmarks.LandmarksData toRole, final int index) {
283  double tmpTravTime;
284  final double fromMinLandmarkTravelTime = fromRole.getMinLandmarkTravelTime(index);
285  final double toMaxLandmarkTravelTime = toRole.getMaxLandmarkTravelTime(index);
286  tmpTravTime = fromMinLandmarkTravelTime - toMaxLandmarkTravelTime;
287  if (tmpTravTime < 0) {
288  tmpTravTime = toRole.getMinLandmarkTravelTime(index) - fromRole.getMaxLandmarkTravelTime(index);
289  if (tmpTravTime <= 0) {
290  return 0;
291  }
292  }
293  return tmpTravTime * this.overdoFactor;
294  }
295 }
double estimateRemainingTravelCost(final Node fromNode, final Node toNode)
PreProcessLandmarks.LandmarksData getPreProcessData(final Node n)
void setExpectedRemainingCost(final double expectedCost)
Path calcLeastCostPath(final Node fromNode, final Node toNode, final double startTime, final Person person, final Vehicle vehicle)
final PreProcessDijkstra preProcessData
Definition: Dijkstra.java:127
final TravelDisutility costFunction
Definition: Dijkstra.java:98
final TravelTime timeFunction
Definition: Dijkstra.java:103
void relaxNode(final Node outNode, final Node toNode, final RouterPriorityQueue< Node > pendingNodes)
double getPriority(final DijkstraNodeData data)
AStarNodeData getData(final Node n)
boolean add(final E o, final double priority)
double estimateRemainingTravelCost(final PreProcessLandmarks.LandmarksData fromRole, final PreProcessLandmarks.LandmarksData toRole, final int index)