Skip to content

Commit

Permalink
Update DRT estimate and teleport module (#3333)
Browse files Browse the repository at this point in the history
Re-organizing the DRT estimation scripts. For more details, please see detailed description above.
  • Loading branch information
luchengqi7 authored Aug 9, 2024
1 parent 90c72f3 commit a455df3
Show file tree
Hide file tree
Showing 17 changed files with 441 additions and 121 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import org.junit.jupiter.api.extension.RegisterExtension;
import org.matsim.application.MATSimApplication;
import org.matsim.contrib.drt.estimator.DrtEstimatorModule;
import org.matsim.contrib.drt.estimator.impl.ConstantDrtEstimator;
import org.matsim.contrib.drt.estimator.impl.ExampleDrtEstimator;
import org.matsim.contrib.drt.extension.DrtTestScenario;
import org.matsim.contrib.drt.extension.modechoice.MultiModalDrtLegEstimator;
import org.matsim.contrib.drt.run.DrtConfigGroup;
Expand Down Expand Up @@ -51,7 +51,7 @@ public void install() {

for (DrtConfigGroup el : drtConfig.getModalElements()) {
install(new DrtEstimatorModule(el.mode, el, el.getDrtEstimatorParams().get()));
DrtEstimatorModule.bindEstimator(binder(), el.mode).toInstance(new ConstantDrtEstimator(1.05, 300));
DrtEstimatorModule.bindEstimator(binder(), el.mode).toInstance(new ExampleDrtEstimator(1.05, 300));
}
}
});
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package org.matsim.contrib.drt.estimator.impl;

import org.checkerframework.checker.units.qual.C;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.network.Link;
import org.matsim.contrib.drt.estimator.DrtEstimator;
import org.matsim.contrib.drt.estimator.impl.distribution.DistributionGenerator;
import org.matsim.contrib.drt.estimator.impl.distribution.LogNormalDistributionGenerator;
import org.matsim.contrib.drt.estimator.impl.distribution.NoDistribution;
import org.matsim.contrib.drt.estimator.impl.distribution.NormalDistributionGenerator;
import org.matsim.contrib.drt.estimator.impl.trip_estimation.ConstantRideDurationEstimator;
import org.matsim.contrib.drt.estimator.impl.trip_estimation.RideDurationEstimator;
import org.matsim.contrib.drt.estimator.impl.waiting_time_estimation.ConstantWaitingTimeEstimator;
import org.matsim.contrib.drt.estimator.impl.waiting_time_estimation.WaitingTimeEstimator;
import org.matsim.contrib.drt.routing.DrtRoute;
import org.matsim.core.utils.misc.OptionalTime;

/**
* DRT estimator that uses available data (e.g., real-world operational data, simulation-based data) to provide estimated data for DRT trips.
*/
public final class DirectTripBasedDrtEstimator implements DrtEstimator {
private final RideDurationEstimator rideDurationEstimator;
private final WaitingTimeEstimator waitingTimeEstimator;
private final DistributionGenerator waitingTimeDistributionGenerator;
private final DistributionGenerator rideTimeDistributionGenerator;

public static class Builder {
// Initialize with default estimation
private RideDurationEstimator rideDurationEstimator = new ConstantRideDurationEstimator(1.25, 300);
private WaitingTimeEstimator waitingTimeEstimator = new ConstantWaitingTimeEstimator(300);
private DistributionGenerator waitingTimeDistributionGenerator = new NoDistribution();
private DistributionGenerator rideTimeDistributionGenerator = new NoDistribution();

public Builder setRideDurationEstimator(RideDurationEstimator rideDurationEstimator) {
this.rideDurationEstimator = rideDurationEstimator;
return this;
}

public Builder setWaitingTimeEstimator(WaitingTimeEstimator waitingTimeEstimator) {
this.waitingTimeEstimator = waitingTimeEstimator;
return this;
}

public Builder setRideDurationDistributionGenerator(DistributionGenerator rideTimeDistributionGenerator) {
this.rideTimeDistributionGenerator = rideTimeDistributionGenerator;
return this;
}

public Builder setWaitingTimeDistributionGenerator(DistributionGenerator waitingTimeDistributionGenerator) {
this.waitingTimeDistributionGenerator = waitingTimeDistributionGenerator;
return this;
}

public DirectTripBasedDrtEstimator build() {
return new DirectTripBasedDrtEstimator(rideDurationEstimator, waitingTimeEstimator, rideTimeDistributionGenerator, waitingTimeDistributionGenerator);
}

}

public DirectTripBasedDrtEstimator(RideDurationEstimator rideDurationEstimator, WaitingTimeEstimator waitingTimeEstimator,
DistributionGenerator rideTimeDistribution, DistributionGenerator waitTimeDistribution) {
this.rideDurationEstimator = rideDurationEstimator;
this.waitingTimeEstimator = waitingTimeEstimator;
this.rideTimeDistributionGenerator = rideTimeDistribution;
this.waitingTimeDistributionGenerator = waitTimeDistribution;
}

/**
* Example DRT estimator based on the normal distributed ride time and waiting time
* @param estRideTimeAlpha typical ride duration = alpha * direct ride time + beta, alpha is specified here
* @param estRideTimeBeta typical ride duration = alpha * direct ride time + beta, beta is specified here
* @param rideTimeStd standard deviation of ride duration (normalized to 1)
* @param estMeanWaitTime estimated waiting time (i.e., mean wait time)
* @param waitTimeStd standard deviation of waiting time (normalized to 1)
* @return NetworkBasedDrtEstimator
*/
public static DirectTripBasedDrtEstimator normalDistributedNetworkBasedDrtEstimator(double estRideTimeAlpha, double estRideTimeBeta,
double rideTimeStd, double estMeanWaitTime,
double waitTimeStd) {
return new Builder()
.setWaitingTimeEstimator(new ConstantWaitingTimeEstimator(estMeanWaitTime))
.setRideDurationEstimator(new ConstantRideDurationEstimator(estRideTimeAlpha, estRideTimeBeta))
.setWaitingTimeDistributionGenerator(new NormalDistributionGenerator(1, waitTimeStd))
.setRideDurationDistributionGenerator(new NormalDistributionGenerator(2, rideTimeStd))
.build();
}

/**
* Example DRT estimator based on the log-normal distributed ride time and normal distributed waiting time
* @param estRideTimeAlpha typical ride duration = alpha * direct ride time + beta, alpha is specified here
* @param estRideTimeBeta typical ride duration = alpha * direct ride time + beta, beta is specified here
* @param mu log-normal distribution parameter for ride duration (normalized to typical ride duration)
* @param sigma log-normal distribution parameter for ride duration (normalized to typical ride duration)
* @param estMeanWaitTime estimated waiting time (i.e., mean wait time)
* @param waitTimeStd standard deviation of waiting time (normalized to 1)
* @return NetworkBasedDrtEstimator
*/
public static DirectTripBasedDrtEstimator mixDistributedNetworkBasedDrtEstimator(double estRideTimeAlpha, double estRideTimeBeta,
double mu, double sigma, double estMeanWaitTime,
double waitTimeStd) {
return new Builder()
.setWaitingTimeEstimator(new ConstantWaitingTimeEstimator(estMeanWaitTime))
.setRideDurationEstimator(new ConstantRideDurationEstimator(estRideTimeAlpha, estRideTimeBeta))
.setWaitingTimeDistributionGenerator(new NormalDistributionGenerator(1, waitTimeStd))
.setRideDurationDistributionGenerator(new LogNormalDistributionGenerator(2, mu, sigma))
.build();
}

@Override
public Estimate estimate(DrtRoute route, OptionalTime departureTime) {
double directRideTIme = route.getDirectRideTime();
double directDistance = route.getDistance();
Id<Link> fromLinkId = route.getStartLinkId();
Id<Link> toLinkId = route.getEndLinkId();
double typicalRideDuration = rideDurationEstimator.getEstimatedRideDuration(fromLinkId, toLinkId, departureTime, directRideTIme);
double typicalRideDistance = (typicalRideDuration / directRideTIme) * directDistance;
double typicalWaitingTime = waitingTimeEstimator.estimateWaitTime(fromLinkId, toLinkId, departureTime);

double estimatedWaitingTime = typicalWaitingTime * waitingTimeDistributionGenerator.generateRandomValue();

double detourRandomFactor = rideTimeDistributionGenerator.generateRandomValue();
double estimatedRideDuration = detourRandomFactor * typicalRideDuration;
double estimatedRideDistance = detourRandomFactor * typicalRideDistance;

double acceptanceRate = 1.0;

return new Estimate(estimatedRideDistance, estimatedRideDuration, estimatedWaitingTime, acceptanceRate);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,35 @@
import org.matsim.api.core.v01.Coord;
import org.matsim.api.core.v01.network.Network;
import org.matsim.contrib.drt.estimator.DrtEstimator;
import org.matsim.contrib.drt.estimator.impl.distribution.DistributionGenerator;
import org.matsim.contrib.drt.estimator.impl.distribution.LogNormalDistributionGenerator;
import org.matsim.contrib.drt.estimator.impl.distribution.NormalDistributionGenerator;
import org.matsim.contrib.drt.estimator.impl.trip_estimation.ConstantRideDurationEstimator;
import org.matsim.contrib.drt.estimator.impl.trip_estimation.RideDurationEstimator;
import org.matsim.contrib.drt.estimator.impl.waiting_time_estimation.ConstantWaitingTimeEstimator;
import org.matsim.contrib.drt.estimator.impl.waiting_time_estimation.WaitingTimeEstimator;
import org.matsim.contrib.drt.routing.DrtRoute;
import org.matsim.core.utils.collections.Tuple;
import org.matsim.core.utils.geometry.CoordUtils;
import org.matsim.core.utils.misc.OptionalTime;

import java.util.Random;

public class EuclideanDistanceBasedDrtEstimator implements DrtEstimator {
private final Network network;
/**
* For travel distance related scoring (e.g., marginal utility distance), we need estimated network distance:
* Estimated network distance = Euclidean distance * network distance factor
*/
private final double networkDistanceFactor;
/**
* Slope of the linear regression
*/
private final double slope;
/**
* Intercept of the linear regression
*/
private final double intercept;

private final double estimatedMeanWaitTime;

private final double waitTimeStd;
private final RideDurationEstimator rideDurationEstimator;
private final WaitingTimeEstimator waitingTimeEstimator;
private final DistributionGenerator rideDurationDistributionGenerator;
private final DistributionGenerator waitingTimeDistributionGenerator;

private final double mu;
private final double sigma;
private final Random random = new Random(1234);

/**
* We use log normal distribution to estimate the ride duration of each individual trip. The distribution
* is based on the linear regression.
*
* @params networkDistanceFactor: Estimated network distance = Euclidean distance * network distance factor
* @params slope: slope for the linear regression
* @params intercept: intercept for linear regression
Expand All @@ -47,32 +43,37 @@ public EuclideanDistanceBasedDrtEstimator(Network network, double networkDistanc
double mu, double sigma) {
this.network = network;
this.networkDistanceFactor = networkDistanceFactor;
this.slope = slope;
this.intercept = intercept;
this.estimatedMeanWaitTime = estimatedMeanWaitTime;
this.waitTimeStd = waitTimeStd;
this.mu = mu;
this.sigma = sigma;
this.rideDurationEstimator = new ConstantRideDurationEstimator(slope, intercept);
this.waitingTimeEstimator = new ConstantWaitingTimeEstimator(estimatedMeanWaitTime);
this.rideDurationDistributionGenerator = new LogNormalDistributionGenerator(1, mu, sigma);
this.waitingTimeDistributionGenerator = new NormalDistributionGenerator(2, waitTimeStd);
}

public EuclideanDistanceBasedDrtEstimator(Network network, double networkDistanceFactor, RideDurationEstimator rideDurationEstimator,
WaitingTimeEstimator waitingTimeEstimator, DistributionGenerator rideDurationDistributionGenerator,
DistributionGenerator waitingTimeDistributionGenerator) {
this.network = network;
this.networkDistanceFactor = networkDistanceFactor;
this.rideDurationEstimator = rideDurationEstimator;
this.waitingTimeEstimator = waitingTimeEstimator;
this.rideDurationDistributionGenerator = rideDurationDistributionGenerator;
this.waitingTimeDistributionGenerator = waitingTimeDistributionGenerator;
}

@Override
public Estimate estimate(DrtRoute route, OptionalTime departureTime) {
Coord fromCoord = network.getLinks().get(route.getStartLinkId()).getToNode().getCoord();
Coord toCoord = network.getLinks().get(route.getEndLinkId()).getToNode().getCoord();
double euclideanDistance = CoordUtils.calcEuclideanDistance(fromCoord, toCoord);
double typicalRideDuration = euclideanDistance * slope + intercept;

double typicalRideDuration = rideDurationEstimator.getEstimatedRideDuration(route.getStartLinkId(), route.getEndLinkId(), departureTime, euclideanDistance);
double typicalRideDistance = networkDistanceFactor * euclideanDistance;
double randomFactor = nextLogNormal(mu, sigma);
double waitTime = Math.max(estimatedMeanWaitTime * (1 + random.nextGaussian() * waitTimeStd), 0);
double typicalWaitingTime = waitingTimeEstimator.estimateWaitTime(route.getStartLinkId(), route.getEndLinkId(), departureTime);
double randomFactor = rideDurationDistributionGenerator.generateRandomValue();
double waitTime = Math.max(typicalWaitingTime * waitingTimeDistributionGenerator.generateRandomValue(), 0);

return new Estimate(typicalRideDistance * randomFactor, typicalRideDuration * randomFactor,
waitTime, 0);
}

public double nextLogNormal(double mu, double sigma) {
if (sigma == 0)
return Math.exp(mu);

return Math.exp(sigma * random.nextGaussian() + mu);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

import org.matsim.contrib.drt.estimator.DrtEstimator;
import org.matsim.contrib.drt.routing.DrtRoute;
import org.matsim.contrib.drt.run.DrtConfigGroup;
import org.matsim.core.utils.misc.OptionalTime;

/**
* Estimates using a constant detour factor and waiting time.
*/
public class ConstantDrtEstimator implements DrtEstimator {
@Deprecated
public class ExampleDrtEstimator implements DrtEstimator {

/**
* Detour factor for the estimate. 1.0 means no detour, 2.0 means twice the distance.
Expand All @@ -20,7 +20,7 @@ public class ConstantDrtEstimator implements DrtEstimator {
*/
private final double waitingTime;

public ConstantDrtEstimator(double detourFactor, double waitingTime) {
public ExampleDrtEstimator(double detourFactor, double waitingTime) {
this.detourFactor = detourFactor;
this.waitingTime = waitingTime;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.matsim.contrib.drt.estimator.impl;

import org.apache.commons.math3.stat.descriptive.SummaryStatistics;
import org.apache.commons.math3.stat.regression.RegressionResults;
import org.apache.commons.math3.stat.regression.SimpleRegression;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
Expand All @@ -23,12 +22,14 @@
import java.util.SplittableRandom;

/**
* When this estimator is used, explicit simulations of DRT will be carried out intermittently. During the iterations where no
* DRT is simulated, estimated DRT will be used. This estimator will replace the original DRT speed-up module
* Estimates drt trips based only daily averages. No spatial or temporal differentiation is taken into account for the estimate.
* This estimator is suited for small scenarios with few vehicles and trips and consequently few data points.
*/
public class BasicDrtEstimator implements DrtOnlineEstimator, IterationEndsListener {
public class OnlineSimulationBasedDrtEstimator implements DrtOnlineEstimator, IterationEndsListener {

private static final Logger log = LogManager.getLogger(BasicDrtEstimator.class);
private static final Logger log = LogManager.getLogger(OnlineSimulationBasedDrtEstimator.class);

private final DrtEventSequenceCollector collector;
private final DrtEstimatorParams config;
Expand All @@ -41,8 +42,8 @@ public class BasicDrtEstimator implements DrtOnlineEstimator, IterationEndsListe
*/
private GlobalEstimate currentEst;

public BasicDrtEstimator(DrtEventSequenceCollector collector, DrtEstimator initial,
DrtEstimatorParams config, DrtConfigGroup drtConfig) {
public OnlineSimulationBasedDrtEstimator(DrtEventSequenceCollector collector, DrtEstimator initial,
DrtEstimatorParams config, DrtConfigGroup drtConfig) {
//zones = injector.getModal(DrtZonalSystem.class);
this.collector = collector;
this.initial = initial;
Expand Down
Loading

0 comments on commit a455df3

Please sign in to comment.