Skip to content

Commit

Permalink
Store trip times efficiently. don't use states.
Browse files Browse the repository at this point in the history
  • Loading branch information
mattwigway committed Apr 13, 2015
1 parent 2e8041f commit 361fd0c
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 230 deletions.
@@ -1,5 +1,6 @@
package org.opentripplanner.profile;

import gnu.trove.iterator.TObjectIntIterator;
import gnu.trove.map.TObjectIntMap;
import gnu.trove.map.TObjectLongMap;
import gnu.trove.map.hash.TObjectIntHashMap;
Expand All @@ -8,21 +9,26 @@
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.joda.time.DateTimeZone;
import org.opentripplanner.analyst.TimeSurface;
import org.opentripplanner.api.parameter.QualifiedModeSet;
import org.opentripplanner.common.model.GenericLocation;
import org.opentripplanner.routing.algorithm.AStar;
import org.opentripplanner.routing.algorithm.PathDiscardingRaptorStateStore;
import org.opentripplanner.routing.algorithm.Raptor;
import org.opentripplanner.routing.algorithm.RaptorStateStore;
import org.opentripplanner.routing.core.RoutingRequest;
import org.opentripplanner.routing.core.State;
import org.opentripplanner.routing.core.TraverseMode;
import org.opentripplanner.routing.core.TraverseModeSet;
import org.opentripplanner.routing.edgetype.TripPattern;
import org.opentripplanner.routing.graph.Graph;
import org.opentripplanner.routing.graph.Vertex;
import org.opentripplanner.routing.spt.DominanceFunction;
import org.opentripplanner.routing.spt.ShortestPathTree;
import org.opentripplanner.routing.trippattern.TripTimeSubset;
import org.opentripplanner.routing.vertextype.TransitStop;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -64,6 +70,7 @@ public void route () {
long computationStartTime = System.currentTimeMillis();
LOG.info("Begin profile request");
LOG.info("Finding initial stops");

Collection<State> states = findInitialStops(false);

LOG.info("Found {} initial stops", states.size());
Expand All @@ -79,33 +86,27 @@ public void route () {
rr.dateTime = request.date.toDateMidnight(DateTimeZone.forTimeZone(graph.getTimeZone())).getMillis() / 1000 + request.fromTime;
rr.setRoutingContext(graph);

Map<TripPattern, TripTimeSubset> timetables =
TripTimeSubset.indexGraph(graph, request.date, request.fromTime, request.toTime + 120 * 60);

// loop backwards with intention of eventually implementing dynamic programming/rRAPTOR based approach
int i = 1;

// We assume the times are aligned to minutes, and we don't do a depart-after search starting
// at the end of the window.
for (int startTime = request.toTime - 60; startTime >= request.fromTime; startTime -= 60) {
RaptorStateStore rss = new PathDiscardingRaptorStateStore();

for (State state : states) {
rss.put((TransitStop) state.getVertex(), (int) (state.getElapsedTimeSeconds() + startTime));
}

if (++i % 30 == 0)
LOG.info("Completed {} RAPTOR searches", i);

//LOG.info("Filtering RAPTOR states");

final long startTimeEpoch = request.date.toDateMidnight(DateTimeZone.forTimeZone(graph.getTimeZone())).getMillis() / 1000 + startTime;
rr.dateTime = startTimeEpoch;

// clooge: create new states offset in time.
// for Modeify we won't be able to do this as we need to be able to reconstruct paths
Collection<State> raptorStates = Collections2.transform(states, new Function<State, State> () {

@Override
public State apply(State input) {
return new State(input.getVertex(), null, input.getElapsedTimeSeconds() + startTimeEpoch, startTimeEpoch, rr);
}

});

Raptor raptor = new Raptor(raptorStates, rr);
Raptor raptor = new Raptor(rss, rr, timetables);

//LOG.info("Performing RAPTOR search for minute {}", i++);

Expand All @@ -114,11 +115,11 @@ public State apply(State input) {
//LOG.info("Finished RAPTOR search in {} milliseconds", System.currentTimeMillis() - roundStartTime);

// loop over all states, accumulating mins, maxes, etc.
for (Iterator<State> it = raptor.iterator(); it.hasNext();) {
State state = it.next();
for (TObjectIntIterator<TransitStop> it = raptor.iterator(); it.hasNext();) {
it.advance();

int et = (int) state.getElapsedTimeSeconds();
Vertex v = state.getVertex();
int et = it.value() - startTime;
Vertex v = it.key();
if (et < mins.get(v))
mins.put(v, et);

Expand Down
Expand Up @@ -12,92 +12,43 @@
import org.opentripplanner.routing.vertextype.TransitStop;

public class PathDiscardingRaptorStateStore implements RaptorStateStore {
/** stores what is reachable in the current round. This stores elapsed time not clock time, but elapsed time is just clock time minus constant start time. */
private TObjectIntMap<Vertex> current = new TObjectIntHashMap<Vertex>(1000, 0.75f, Integer.MAX_VALUE);
/** stores what is reachable in the current round. This stores clock time in seconds since midnight. */
private TObjectIntMap<TransitStop> current = new TObjectIntHashMap<TransitStop>(1000, 0.75f, Integer.MAX_VALUE);

/** stores what was reachable in the previous round */
private TObjectIntMap<Vertex> prev;

private RoutingRequest options;
private TObjectIntMap<TransitStop> prev;

@Override
public boolean put(State s) {
Vertex v = s.getVertex();

if (!(v instanceof TransitStop))
throw new UnsupportedOperationException("Vertex is not a transit stop!");

TransitStop t = (TransitStop) v;

int elapsedTime = (int) s.getElapsedTimeSeconds();
if (elapsedTime < current.get(t)) {
current.put(t, elapsedTime);
public boolean put(TransitStop t, int time) {
if (time < current.get(t)) {
current.put(t, time);
return true;
}
return false;
}

private State get(TransitStop t, TObjectIntMap which) {
if (!which.containsKey(t))
return null;

int elapsedTimeSecs = which.get(t);
long startTime = options.dateTime;
return new State(t, null, elapsedTimeSecs + startTime, startTime, options);
}


}

@Override
public void proceed() {
prev = new TObjectIntHashMap<Vertex>();
prev = new TObjectIntHashMap<TransitStop>(1000, 0.75f, Integer.MAX_VALUE);
prev.putAll(current);
}

@Override
public State getCurrent(TransitStop t) {
return get(t, current);
public int getCurrent(TransitStop t) {
return current.get(t);
}

@Override
public State getPrev(TransitStop t) {
return get(t, prev);
}

public PathDiscardingRaptorStateStore(RoutingRequest options) {
this.options = options;
}

private Iterator<State> iterator (final TObjectIntMap<Vertex> map) {
return new Iterator<State> () {
private TObjectIntIterator<Vertex> baseIterator = map.iterator();

@Override
public boolean hasNext() {
return baseIterator.hasNext();
}

@Override
public State next() {
baseIterator.advance();
long startTime = options.dateTime;
return new State(baseIterator.key(), null, baseIterator.value() + startTime, startTime, options);
}

@Override
public void remove() {
baseIterator.remove();
}

};
public int getPrev(TransitStop t) {
return prev.get(t);
}

public Iterator<State> currentIterator() {
return iterator(current);
public TObjectIntIterator<TransitStop> currentIterator() {
return current.iterator();
}

public Iterator<State> prevIterator() {
return iterator(prev);
public TObjectIntIterator<TransitStop> prevIterator() {
return prev.iterator();
}

}

0 comments on commit 361fd0c

Please sign in to comment.