use of org.opentripplanner.routing.graph.Vertex in project OpenTripPlanner by opentripplanner.
the class TestAStar method testMaxTime.
public void testMaxTime() {
Graph graph = ConstantsForTests.getInstance().getPortlandGraph();
String feedId = graph.getFeedIds().iterator().next();
Vertex start = graph.getVertex(feedId + ":8371");
Vertex end = graph.getVertex(feedId + ":8374");
RoutingRequest options = new RoutingRequest();
long startTime = TestUtils.dateInSeconds("America/Los_Angeles", 2009, 11, 1, 12, 34, 25);
options.dateTime = startTime;
// one hour is more than enough time
options.worstTime = startTime + 60 * 60;
options.setRoutingContext(graph, start, end);
ShortestPathTree spt = aStar.getShortestPathTree(options);
GraphPath path = spt.getPath(end, true);
assertNotNull(path);
// but one minute is not enough
options.worstTime = startTime + 60;
spt = aStar.getShortestPathTree(options);
path = spt.getPath(end, true);
assertNull(path);
}
use of org.opentripplanner.routing.graph.Vertex in project OpenTripPlanner by opentripplanner.
the class WalkableAreaBuilder method pruneAreaEdges.
/**
* Do an all-pairs shortest path search from a list of vertices over a specified set of edges,
* and retain only those edges which are actually used in some shortest path.
*
* @param startingVertices
* @param edges
*/
private void pruneAreaEdges(Collection<Vertex> startingVertices, Set<Edge> edges) {
if (edges.size() == 0)
return;
TraverseMode mode;
StreetEdge firstEdge = (StreetEdge) edges.iterator().next();
if (firstEdge.getPermission().allows(StreetTraversalPermission.PEDESTRIAN)) {
mode = TraverseMode.WALK;
} else if (firstEdge.getPermission().allows(StreetTraversalPermission.BICYCLE)) {
mode = TraverseMode.BICYCLE;
} else {
mode = TraverseMode.CAR;
}
RoutingRequest options = new RoutingRequest(mode);
options.setDummyRoutingContext(graph);
options.dominanceFunction = new DominanceFunction.EarliestArrival();
GenericDijkstra search = new GenericDijkstra(options);
search.setSkipEdgeStrategy(new ListedEdgesOnly(edges));
Set<Edge> usedEdges = new HashSet<Edge>();
for (Vertex vertex : startingVertices) {
State state = new State(vertex, options);
ShortestPathTree spt = search.getShortestPathTree(state);
for (Vertex endVertex : startingVertices) {
GraphPath path = spt.getPath(endVertex, false);
if (path != null) {
for (Edge edge : path.edges) {
usedEdges.add(edge);
}
}
}
}
for (Edge edge : edges) {
if (!usedEdges.contains(edge)) {
graph.removeEdge(edge);
}
}
}
use of org.opentripplanner.routing.graph.Vertex in project OpenTripPlanner by opentripplanner.
the class EarliestArrivalSearch method getShortestPathTree.
public ShortestPathTree getShortestPathTree(RoutingRequest options, double relTimeout, SearchTerminationStrategy terminationStrategy) {
// clone options before modifying, otherwise disabling resource limiting will cause
// SPT cache misses for subsequent requests.
options = options.clone();
// disable any resource limiting, which is algorithmically invalid here
options.maxTransfers = Integer.MAX_VALUE;
options.setMaxWalkDistance(Double.MAX_VALUE);
if (options.clampInitialWait < 0)
options.clampInitialWait = (60 * 30);
// impose search cutoff
final long maxt = maxDuration + options.clampInitialWait;
options.worstTime = options.dateTime + (options.arriveBy ? -maxt : maxt);
// SPT cache does not look at routing request in SPT to perform lookup,
// so it's OK to construct with the local cloned one
ShortestPathTree spt = new DominanceFunction.EarliestArrival().getNewShortestPathTree(options);
State initialState = new State(options);
spt.add(initialState);
BinHeap<State> pq = new BinHeap<State>();
pq.insert(initialState, 0);
while (!pq.empty()) {
State u = pq.extract_min();
Vertex u_vertex = u.getVertex();
if (!spt.visit(u))
continue;
Collection<Edge> edges = options.arriveBy ? u_vertex.getIncoming() : u_vertex.getOutgoing();
for (Edge edge : edges) {
for (State v = edge.traverse(u); v != null; v = v.getNextResult()) {
if (isWorstTimeExceeded(v, options)) {
continue;
}
if (spt.add(v)) {
// activeTime?
pq.insert(v, v.getActiveTime());
}
}
}
}
return spt;
}
use of org.opentripplanner.routing.graph.Vertex in project OpenTripPlanner by opentripplanner.
the class InterleavedBidirectionalHeuristic method initialize.
/**
* Before the main search begins, the heuristic must search on the streets around the origin and destination.
* This also sets up the initial states for the reverse search through the transit network, which progressively
* improves lower bounds on travel time to the target to guide the main search.
*/
@Override
public void initialize(RoutingRequest request, long abortTime) {
Vertex target = request.rctx.target;
if (target == this.target) {
LOG.debug("Reusing existing heuristic, the target vertex has not changed.");
return;
}
LOG.debug("Initializing heuristic computation.");
this.graph = request.rctx.graph;
long start = System.currentTimeMillis();
this.target = target;
this.routingRequest = request;
request.softWalkLimiting = false;
request.softPreTransitLimiting = false;
transitQueue = new BinHeap<>();
// Forward street search first, mark street vertices around the origin so H evaluates to 0
TObjectDoubleMap<Vertex> forwardStreetSearchResults = streetSearch(request, false, abortTime);
if (forwardStreetSearchResults == null) {
// Search timed out
return;
}
preTransitVertices = forwardStreetSearchResults.keySet();
LOG.debug("end forward street search {} ms", System.currentTimeMillis() - start);
postBoardingWeights = streetSearch(request, true, abortTime);
if (postBoardingWeights == null) {
// Search timed out
return;
}
LOG.debug("end backward street search {} ms", System.currentTimeMillis() - start);
// once street searches are done, raise the limits to max
// because hard walk limiting is incorrect and is observed to cause problems
// for trips near the cutoff
request.setMaxWalkDistance(Double.POSITIVE_INFINITY);
request.setMaxPreTransitTime(Integer.MAX_VALUE);
LOG.debug("initialized SSSP");
request.rctx.debugOutput.finishedPrecalculating();
}
use of org.opentripplanner.routing.graph.Vertex in project OpenTripPlanner by opentripplanner.
the class InterleavedBidirectionalHeuristic method streetSearch.
/**
* Explore the streets around the origin or target, recording the minimum weight of a path to each street vertex.
* When searching around the target, also retain the states that reach transit stops since we'll want to
* explore the transit network backward, in order to guide the main forward search.
*
* The main search always proceeds from the "origin" to the "target" (names remain unchanged in arriveBy mode).
* The reverse heuristic search always proceeds outward from the target (name remains unchanged in arriveBy).
*
* When the main search is departAfter:
* it gets outgoing edges and traverses them with arriveBy=false,
* the heuristic search gets incoming edges and traverses them with arriveBy=true,
* the heuristic destination street search also gets incoming edges and traverses them with arriveBy=true,
* the heuristic origin street search gets outgoing edges and traverses them with arriveBy=false.
*
* When main search is arriveBy:
* it gets incoming edges and traverses them with arriveBy=true,
* the heuristic search gets outgoing edges and traverses them with arriveBy=false,
* the heuristic destination street search also gets outgoing edges and traverses them with arriveBy=false,
* the heuristic origin street search gets incoming edges and traverses them with arriveBy=true.
* The streetSearch method traverses using the real traverse method rather than the lower bound traverse method
* because this allows us to keep track of the distance walked.
* Perhaps rather than tracking walk distance, we should just check the straight-line radius and
* only walk within that distance. This would avoid needing to call the main traversal functions.
*
* TODO what if the egress segment is by bicycle or car mode? This is no longer admissible.
*/
private TObjectDoubleMap<Vertex> streetSearch(RoutingRequest rr, boolean fromTarget, long abortTime) {
LOG.debug("Heuristic street search around the {}.", fromTarget ? "target" : "origin");
rr = rr.clone();
if (fromTarget) {
rr.setArriveBy(!rr.arriveBy);
}
// Create a map that returns Infinity when it does not contain a vertex.
TObjectDoubleMap<Vertex> vertices = new TObjectDoubleHashMap<>(100, 0.5f, Double.POSITIVE_INFINITY);
ShortestPathTree spt = new DominanceFunction.MinimumWeight().getNewShortestPathTree(rr);
// TODO use normal OTP search for this.
BinHeap<State> pq = new BinHeap<State>();
Vertex initVertex = fromTarget ? rr.rctx.target : rr.rctx.origin;
State initState = new State(initVertex, rr);
pq.insert(initState, 0);
while (!pq.empty()) {
if (abortTime < Long.MAX_VALUE && System.currentTimeMillis() > abortTime) {
return null;
}
State s = pq.extract_min();
Vertex v = s.getVertex();
// This is the lowest cost we will ever see for this vertex. We can record the cost to reach it.
if (v instanceof TransitStop) {
// place vertices on the transit queue so we can explore the transit network backward later.
if (fromTarget) {
double weight = s.getWeight();
transitQueue.insert(v, weight);
if (weight > maxWeightSeen) {
maxWeightSeen = weight;
}
}
continue;
}
// Record the cost to reach this vertex.
if (!vertices.containsKey(v)) {
// FIXME time or weight? is RR using right mode?
vertices.put(v, (int) s.getWeight());
}
for (Edge e : rr.arriveBy ? v.getIncoming() : v.getOutgoing()) {
// arriveBy has been set to match actual directional behavior in this subsearch.
// Walk cutoff will happen in the street edge traversal method.
State s1 = e.traverse(s);
if (s1 == null) {
continue;
}
if (spt.add(s1)) {
pq.insert(s1, s1.getWeight());
}
}
}
LOG.debug("Heuristric street search hit {} vertices.", vertices.size());
LOG.debug("Heuristric street search hit {} transit stops.", transitQueue.size());
return vertices;
}
Aggregations