use of org.opentripplanner.routing.core.State in project OpenTripPlanner by opentripplanner.
the class RoundBasedProfileRouter method findInitialStops.
/**
* find the boarding stops
*/
private Collection<ProfileState> findInitialStops(boolean dest) {
double lat = dest ? request.toLat : request.fromLat;
double lon = dest ? request.toLon : request.fromLon;
QualifiedModeSet modes = dest ? request.accessModes : request.egressModes;
List<ProfileState> stops = Lists.newArrayList();
RoutingRequest rr = new RoutingRequest(TraverseMode.WALK);
rr.dominanceFunction = new DominanceFunction.EarliestArrival();
rr.batch = true;
rr.from = new GenericLocation(lat, lon);
rr.walkSpeed = request.walkSpeed;
rr.to = rr.from;
rr.setRoutingContext(graph);
// RoutingRequest dateTime defaults to currentTime.
// If elapsed time is not capped, searches are very slow.
rr.worstTime = (rr.dateTime + request.maxWalkTime * 60);
AStar astar = new AStar();
rr.longDistance = true;
rr.setNumItineraries(1);
// timeout in seconds
ShortestPathTree spt = astar.getShortestPathTree(rr, 5);
for (TransitStop tstop : graph.index.stopVertexForStop.values()) {
State s = spt.getState(tstop);
if (s != null) {
ProfileState ps = new ProfileState();
ps.lowerBound = ps.upperBound = (int) s.getElapsedTimeSeconds();
ps.stop = tstop;
ps.accessType = Type.STREET;
stops.add(ps);
}
}
Map<TripPattern, ProfileState> optimalBoardingLocation = Maps.newHashMap();
TObjectIntMap<TripPattern> minBoardTime = new TObjectIntHashMap<TripPattern>(100, 0.75f, Integer.MAX_VALUE);
// Only board patterns at the closest possible stop
for (ProfileState ps : stops) {
for (TripPattern pattern : graph.index.patternsForStop.get(ps.stop.getStop())) {
if (ps.lowerBound < minBoardTime.get(pattern)) {
optimalBoardingLocation.put(pattern, ps);
minBoardTime.put(pattern, ps.lowerBound);
}
}
ps.targetPatterns = Sets.newHashSet();
}
LOG.info("Found {} reachable stops, filtering to only board at closest stops", stops.size());
for (Entry<TripPattern, ProfileState> e : optimalBoardingLocation.entrySet()) {
e.getValue().targetPatterns.add(e.getKey());
}
for (Iterator<ProfileState> it = stops.iterator(); it.hasNext(); ) {
if (it.next().targetPatterns.isEmpty())
it.remove();
}
rr.cleanup();
return stops;
}
use of org.opentripplanner.routing.core.State in project OpenTripPlanner by opentripplanner.
the class AStar method iterate.
boolean iterate() {
// print debug info
if (verbose) {
double w = runState.pq.peek_min_key();
System.out.println("pq min key = " + w);
}
// interleave some heuristic-improving work (single threaded)
runState.heuristic.doSomeWork();
// get the lowest-weight state in the queue
runState.u = runState.pq.extract_min();
// and mark vertex as visited
if (!runState.spt.visit(runState.u)) {
// not in any optimal path. drop it on the floor and try the next one.
return false;
}
if (traverseVisitor != null) {
traverseVisitor.visitVertex(runState.u);
}
runState.u_vertex = runState.u.getVertex();
if (verbose)
System.out.println(" vertex " + runState.u_vertex);
runState.nVisited += 1;
Collection<Edge> edges = runState.options.arriveBy ? runState.u_vertex.getIncoming() : runState.u_vertex.getOutgoing();
for (Edge edge : edges) {
// returning NULL), the iteration is over. TODO Use this to board multiple trips.
for (State v = edge.traverse(runState.u); v != null; v = v.getNextResult()) {
if (traverseVisitor != null) {
traverseVisitor.visitEdge(edge, v);
}
double remaining_w = runState.heuristic.estimateRemainingWeight(v);
if (remaining_w < 0 || Double.isInfinite(remaining_w)) {
continue;
}
double estimate = v.getWeight() + remaining_w;
if (verbose) {
System.out.println(" edge " + edge);
System.out.println(" " + runState.u.getWeight() + " -> " + v.getWeight() + "(w) + " + remaining_w + "(heur) = " + estimate + " vert = " + v.getVertex());
}
// avoid enqueuing useless branches
if (estimate > runState.options.maxWeight) {
// too expensive to get here
if (verbose)
System.out.println(" too expensive to reach, not enqueued. estimated weight = " + estimate);
continue;
}
if (isWorstTimeExceeded(v, runState.options)) {
// too much time to get here
if (verbose)
System.out.println(" too much time to reach, not enqueued. time = " + v.getTimeSeconds());
continue;
}
// spt.add returns true if the state is hopeful; enqueue state if it's hopeful
if (runState.spt.add(v)) {
// report to the visitor if there is one
if (traverseVisitor != null)
traverseVisitor.visitEnqueue(v);
// LOG.info("u.w={} v.w={} h={}", runState.u.weight, v.weight, remaining_w);
runState.pq.insert(v, estimate);
}
}
}
return true;
}
use of org.opentripplanner.routing.core.State in project OpenTripPlanner by opentripplanner.
the class AStar method startSearch.
/**
* set up the search, optionally not adding the initial state to the queue (for multi-state Dijkstra)
*/
private void startSearch(RoutingRequest options, SearchTerminationStrategy terminationStrategy, long abortTime, boolean addToQueue) {
runState = new RunState(options, terminationStrategy);
runState.rctx = options.getRoutingContext();
runState.spt = options.getNewShortestPathTree();
// We want to reuse the heuristic instance in a series of requests for the same target to avoid repeated work.
// "Batch" means one-to-many mode, where there is no goal to reach so we use a trivial heuristic.
runState.heuristic = options.batch ? new TrivialRemainingWeightHeuristic() : runState.rctx.remainingWeightHeuristic;
// Since initial states can be multiple, heuristic cannot depend on the initial state.
// Initializing the bidirectional heuristic is a pretty complicated operation that involves searching through
// the streets around the origin and destination.
runState.heuristic.initialize(runState.options, abortTime);
if (abortTime < Long.MAX_VALUE && System.currentTimeMillis() > abortTime) {
LOG.warn("Timeout during initialization of goal direction heuristic.");
options.rctx.debugOutput.timedOut = true;
// Search timed out
runState = null;
return;
}
// Priority Queue.
// The queue is self-resizing, so we initialize it to have size = O(sqrt(|V|)) << |V|.
// For reference, a random, undirected search on a uniform 2d grid will examine roughly sqrt(|V|) vertices
// before reaching its target.
int initialSize = runState.rctx.graph.getVertices().size();
initialSize = (int) Math.ceil(2 * (Math.sqrt((double) initialSize + 1)));
runState.pq = new BinHeap<>(initialSize);
runState.nVisited = 0;
runState.targetAcceptedStates = Lists.newArrayList();
if (addToQueue) {
State initialState = new State(options);
runState.spt.add(initialState);
runState.pq.insert(initialState, 0);
}
}
use of org.opentripplanner.routing.core.State in project OpenTripPlanner by opentripplanner.
the class GenericDijkstra method getShortestPathTree.
public ShortestPathTree getShortestPathTree(State initialState) {
Vertex target = null;
if (options.rctx != null) {
target = initialState.getOptions().rctx.target;
}
ShortestPathTree spt = new DominanceFunction.MinimumWeight().getNewShortestPathTree(options);
BinHeap<State> queue = new BinHeap<State>(1000);
spt.add(initialState);
queue.insert(initialState, initialState.getWeight());
while (!queue.empty()) {
// Until the priority queue is empty:
State u = queue.extract_min();
Vertex u_vertex = u.getVertex();
if (traverseVisitor != null) {
traverseVisitor.visitVertex(u);
}
if (!spt.getStates(u_vertex).contains(u)) {
continue;
}
if (verbose) {
System.out.println("min," + u.getWeight());
System.out.println(u_vertex);
}
if (searchTerminationStrategy != null && searchTerminationStrategy.shouldSearchTerminate(initialState.getVertex(), null, u, spt, options)) {
break;
}
for (Edge edge : options.arriveBy ? u_vertex.getIncoming() : u_vertex.getOutgoing()) {
if (skipEdgeStrategy != null && skipEdgeStrategy.shouldSkipEdge(initialState.getVertex(), null, u, edge, spt, options)) {
continue;
}
// returning NULL), the iteration is over.
for (State v = edge.traverse(u); v != null; v = v.getNextResult()) {
if (skipTraverseResultStrategy != null && skipTraverseResultStrategy.shouldSkipTraversalResult(initialState.getVertex(), null, u, v, spt, options)) {
continue;
}
if (traverseVisitor != null) {
traverseVisitor.visitEdge(edge, v);
}
if (verbose) {
System.out.printf(" w = %f + %f = %f %s", u.getWeight(), v.getWeightDelta(), v.getWeight(), v.getVertex());
}
if (v.exceedsWeightLimit(options.maxWeight))
continue;
if (spt.add(v)) {
double estimate = heuristic.estimateRemainingWeight(v);
queue.insert(v, v.getWeight() + estimate);
if (traverseVisitor != null)
traverseVisitor.visitEnqueue(v);
}
}
}
}
return spt;
}
use of org.opentripplanner.routing.core.State in project OpenTripPlanner by opentripplanner.
the class EuclideanRemainingWeightHeuristic method determineRequiredWalkDistance.
/**
* Figure out the minimum amount of walking to reach the destination from transit.
* This is done by doing a Dijkstra search for the first reachable transit stop.
*/
private double determineRequiredWalkDistance(final RoutingRequest req) {
// required walk distance will be unused.
if (!transit)
return 0;
RoutingRequest options = req.clone();
options.setArriveBy(!req.arriveBy);
options.setRoutingContext(req.rctx.graph, req.rctx.fromVertex, req.rctx.toVertex);
GenericDijkstra gd = new GenericDijkstra(options);
State s = new State(options);
gd.setHeuristic(new TrivialRemainingWeightHeuristic());
final ClosestStopTraverseVisitor visitor = new ClosestStopTraverseVisitor();
gd.traverseVisitor = visitor;
gd.searchTerminationStrategy = new SearchTerminationStrategy() {
@Override
public boolean shouldSearchTerminate(Vertex origin, Vertex target, State current, ShortestPathTree spt, RoutingRequest traverseOptions) {
return visitor.distanceToClosestStop != Double.POSITIVE_INFINITY;
}
};
gd.getShortestPathTree(s);
return visitor.distanceToClosestStop;
}
Aggregations