Skip to content

Commit

Permalink
mark stops to find transfers. use dynamic programming to compute repe…
Browse files Browse the repository at this point in the history
…ated RAPTOR searches.
  • Loading branch information
mattwigway committed Apr 13, 2015
1 parent 361fd0c commit 1217058
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 19 deletions.
Expand Up @@ -92,11 +92,18 @@ public void route () {
// loop backwards with intention of eventually implementing dynamic programming/rRAPTOR based approach // loop backwards with intention of eventually implementing dynamic programming/rRAPTOR based approach
int i = 1; int i = 1;


// + 2 is because we have one additional round because there is one more ride than transfer
// (fencepost problem) and one additional round for the initial walk.
PathDiscardingRaptorStateStore rss = new PathDiscardingRaptorStateStore(rr.maxTransfers + 3);

// We assume the times are aligned to minutes, and we don't do a depart-after search starting // We assume the times are aligned to minutes, and we don't do a depart-after search starting
// at the end of the window. // at the end of the window.
for (int startTime = request.toTime - 60; startTime >= request.fromTime; startTime -= 60) { for (int startTime = request.toTime - 60; startTime >= request.fromTime; startTime -= 60) {
RaptorStateStore rss = new PathDiscardingRaptorStateStore(); // note that we do not have to change any times (except the times at the access stops)
// because this stores clock times not elapsed times.
rss.restart();


// add the initial stops, or move back the times at them if not on the first search
for (State state : states) { for (State state : states) {
rss.put((TransitStop) state.getVertex(), (int) (state.getElapsedTimeSeconds() + startTime)); rss.put((TransitStop) state.getVertex(), (int) (state.getElapsedTimeSeconds() + startTime));
} }
Expand Down
Expand Up @@ -11,44 +11,62 @@
import org.opentripplanner.routing.graph.Vertex; import org.opentripplanner.routing.graph.Vertex;
import org.opentripplanner.routing.vertextype.TransitStop; import org.opentripplanner.routing.vertextype.TransitStop;


@SuppressWarnings("unchecked")
public class PathDiscardingRaptorStateStore implements RaptorStateStore { public class PathDiscardingRaptorStateStore implements RaptorStateStore {
/** stores what is reachable in the current round. This stores clock time in seconds since midnight. */ // suppressing warnings because generic arrays don't work in Java . . .
private TObjectIntMap<TransitStop> current = new TObjectIntHashMap<TransitStop>(1000, 0.75f, Integer.MAX_VALUE); @SuppressWarnings("rawtypes")
private TObjectIntMap[] matrix;


/** stores what was reachable in the previous round */ int current = 0;
private TObjectIntMap<TransitStop> prev;


@Override @Override
public boolean put(TransitStop t, int time) { public boolean put(TransitStop t, int time) {
if (time < current.get(t)) { if (time < matrix[current].get(t)) {
current.put(t, time); matrix[current].put(t, time);
return true; return true;
} }
return false; return false;
} }


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


@Override @Override
public int getCurrent(TransitStop t) { public int getCurrent(TransitStop t) {
return current.get(t); return matrix[current].get(t);
} }


@Override @Override
public int getPrev(TransitStop t) { public int getPrev(TransitStop t) {
return prev.get(t); return matrix[current - 1].get(t);
} }


public TObjectIntIterator<TransitStop> currentIterator() { public TObjectIntIterator<TransitStop> currentIterator() {
return current.iterator(); return matrix[current].iterator();
} }


public TObjectIntIterator<TransitStop> prevIterator() { public TObjectIntIterator<TransitStop> prevIterator() {
return prev.iterator(); return matrix[current - 1].iterator();
}

/** Restart the search from the first round. Used when running repeated RAPTOR searches using the dynamic programming
* algorithm.
*
* TODO write up the dynamic programming algorithm.
*/
public void restart () {
current = 0;
}

/** Create a new store with the given number of rounds. Remember to include the initial walk as a "round" */
public PathDiscardingRaptorStateStore(int rounds) {
matrix = new TObjectIntMap[rounds];

for (int i = 0; i < rounds; i++) {
matrix[i] = new TObjectIntHashMap<TransitStop>(1000, 0.75f, Integer.MAX_VALUE);
}
} }

} }
12 changes: 7 additions & 5 deletions src/main/java/org/opentripplanner/routing/algorithm/Raptor.java
Expand Up @@ -40,6 +40,7 @@ public class Raptor {
private static final Logger LOG = LoggerFactory.getLogger(Raptor.class); private static final Logger LOG = LoggerFactory.getLogger(Raptor.class);


private HashSet<TripPattern> markedPatterns = Sets.newHashSet(); private HashSet<TripPattern> markedPatterns = Sets.newHashSet();
private HashSet<TransitStop> markedStops;


private Map<TripPattern, TripTimeSubset> times; private Map<TripPattern, TripTimeSubset> times;


Expand Down Expand Up @@ -111,6 +112,7 @@ private boolean doRound () {
// TODO: implement the rest of the optimizations in the paper, in particular not going past the destination // TODO: implement the rest of the optimizations in the paper, in particular not going past the destination
Set<TripPattern> oldMarkedPatterns = markedPatterns; Set<TripPattern> oldMarkedPatterns = markedPatterns;
markedPatterns = Sets.newHashSet(); markedPatterns = Sets.newHashSet();
markedStops = Sets.newHashSet();


//LOG.info("Exploring {} patterns", oldMarkedPatterns.size()); //LOG.info("Exploring {} patterns", oldMarkedPatterns.size());


Expand All @@ -135,14 +137,12 @@ private boolean doRound () {
/** Find all the transfers from the last round to this round */ /** Find all the transfers from the last round to this round */
public void findTransfers () { public void findTransfers () {
// TODO: don't transfer from things that were not updated this round // TODO: don't transfer from things that were not updated this round
for (TObjectIntIterator<TransitStop> stateIt = store.prevIterator(); stateIt.hasNext();) { for (TransitStop tstop : markedStops) {
stateIt.advance(); for (Edge e : tstop.getOutgoing()) {

for (Edge e : stateIt.key().getOutgoing()) {
if (e instanceof SimpleTransfer) { if (e instanceof SimpleTransfer) {
TransitStop to = (TransitStop) e.getToVertex(); TransitStop to = (TransitStop) e.getToVertex();


if (store.put(to, (int) (stateIt.value() + e.getDistance() / options.walkSpeed))) { if (store.put(to, (int) (store.getPrev(tstop) + e.getDistance() / options.walkSpeed))) {
markedPatterns.addAll(options.rctx.graph.index.patternsForStop.get(to.getStop())); markedPatterns.addAll(options.rctx.graph.index.patternsForStop.get(to.getStop()));
} }
} }
Expand Down Expand Up @@ -174,6 +174,8 @@ public void propagate (int time, TripPattern tripPattern, int stopIndex) {
if (tp != tripPattern) if (tp != tripPattern)
markedPatterns.add(tp); markedPatterns.add(tp);
} }

markedStops.add(v);
} }
} }
} }
Expand Down

0 comments on commit 1217058

Please sign in to comment.