Skip to content

Commit

Permalink
work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
luchengqi7 committed May 17, 2024
1 parent e9e8ce0 commit 9376ecf
Show file tree
Hide file tree
Showing 11 changed files with 280 additions and 109 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@
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.ConstantTripEstimator;
import org.matsim.contrib.drt.estimator.impl.trip_estimation.TripEstimator;
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;

Expand All @@ -16,26 +24,16 @@ public class EuclideanDistanceBasedDrtEstimator implements DrtEstimator {
* 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 TripEstimator tripEstimator;
private final WaitingTimeEstimator waitingTimeEstimator;
private final DistributionGenerator rideDurationDistributionGenerator;
private final DistributionGenerator waitingTimeDistributionGenerator;

private final double estimatedMeanWaitTime;

private final double waitTimeStd;

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 +45,38 @@ 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.tripEstimator = new ConstantTripEstimator(slope, intercept);
this.waitingTimeEstimator = new ConstantWaitingTimeEstimator(estimatedMeanWaitTime);
this.rideDurationDistributionGenerator = new LogNormalDistributionGenerator(new Random(4711), mu, sigma);
this.waitingTimeDistributionGenerator = new NormalDistributionGenerator(4711, waitTimeStd);
}

public EuclideanDistanceBasedDrtEstimator(Network network, double networkDistanceFactor, TripEstimator tripEstimator,
WaitingTimeEstimator waitingTimeEstimator, DistributionGenerator rideDurationDistributionGenerator,
DistributionGenerator waitingTimeDistributionGenerator) {
this.network = network;
this.networkDistanceFactor = networkDistanceFactor;
this.tripEstimator = tripEstimator;
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;

Tuple<Double, Double> alphaBeta = tripEstimator.getAlphaBetaValues(route.getStartLinkId(), route.getEndLinkId(), departureTime);
double typicalRideDuration = euclideanDistance * alphaBeta.getFirst() + alphaBeta.getSecond();
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
@@ -0,0 +1,108 @@
package org.matsim.contrib.drt.estimator.impl;

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.NormalDistributionGenerator;
import org.matsim.contrib.drt.estimator.impl.trip_estimation.ConstantTripEstimator;
import org.matsim.contrib.drt.estimator.impl.trip_estimation.TripEstimator;
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.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 NetworkBasedDrtEstimator implements DrtEstimator {
private final TripEstimator rideDurationEstimator;
private final WaitingTimeEstimator waitingTimeEstimator;
private final DistributionGenerator waitingTimeDistributionGenerator;
private final DistributionGenerator rideTimeDistributionGenerator;

static class Builder {
private TripEstimator rideDurationEstimator;
private WaitingTimeEstimator waitingTimeEstimator;
private DistributionGenerator waitingTimeDistributionGenerator;
private DistributionGenerator rideTimeDistributionGenerator;

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

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

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

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

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

}

public NetworkBasedDrtEstimator(TripEstimator 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 NetworkBasedDrtEstimator normalDistributed(double estRideTimeAlpha, double estRideTimeBeta, double rideTimeStd, double estMeanWaitTime,
double waitTimeStd) {
return new Builder()
.setWaitingTimeEstimator(new ConstantWaitingTimeEstimator(estMeanWaitTime))
.setRideDurationEstimator(new ConstantTripEstimator(estRideTimeAlpha, estRideTimeBeta))
.setWaitingTimeDistributionGenerator(new NormalDistributionGenerator(4711, waitTimeStd))
.setRideDurationDistributionGenerator(new NormalDistributionGenerator(4711, rideTimeStd))
.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();
Tuple<Double, Double> alphaBetaTuple = rideDurationEstimator.getAlphaBetaValues(fromLinkId, toLinkId, departureTime);
double alpha = alphaBetaTuple.getFirst();
double beta = alphaBetaTuple.getSecond();
double typicalRideDuration = directRideTIme * alpha + beta;
double typicalRideDistance = directDistance * alpha + beta;
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
@@ -0,0 +1,10 @@
package org.matsim.contrib.drt.estimator.impl.distribution;

public interface DistributionGenerator {
/**
* @return relative value to the typical ride duration
*/
double generateRandomValue();

enum DistributionType {NORMAL, LOG_NORMAL, POISSON, CUSTOM}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.matsim.contrib.drt.estimator.impl.distribution;

import java.util.Random;

public class LogNormalDistributionGenerator implements DistributionGenerator {
private final Random random;
private final double mu;
private final double sigma;
private final double minValue;

private final double maxValue;

public LogNormalDistributionGenerator(Random random, double mu, double sigma) {
this.random = new Random();
this.mu = mu;
this.sigma = sigma;
this.minValue = 0.5;
this.maxValue = 3;
}

public LogNormalDistributionGenerator(Random random, double mu, double sigma, double minValue, double maxValue) {
this.random = random;
this.mu = mu;
this.sigma = sigma;
this.minValue = minValue;
this.maxValue = maxValue;
}

@Override
public double generateRandomValue() {
if (sigma == 0)
return Math.exp(mu);
return Math.max(Math.min(Math.exp(sigma * random.nextGaussian() + mu), maxValue), minValue);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.matsim.contrib.drt.estimator.impl.distribution;

import java.util.Random;

public class NormalDistributionGenerator implements DistributionGenerator{
private final Random random;
private final double std;

private final double minValue;

private final double maxValue;

public NormalDistributionGenerator(long seed, double std) {
this.random = new Random(seed);
this.std = std;
this.minValue = 0.5;
this.maxValue = 3.0;
}

public NormalDistributionGenerator(long seed, double std, double minValue, double maxValue) {
this.random = new Random(seed);
this.std = std;
this.minValue = minValue;
this.maxValue = maxValue;
}

@Override
public double generateRandomValue() {
double randomValue = random.nextGaussian() * std;
randomValue = Math.min(maxValue, randomValue);
randomValue = Math.max(minValue, randomValue);
return randomValue;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.matsim.contrib.drt.estimator.impl.trip_estimation;

import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.network.Link;
import org.matsim.core.utils.collections.Tuple;
import org.matsim.core.utils.misc.OptionalTime;

public class ConstantTripEstimator implements TripEstimator {
private final double alpha;
private final double beta;

public ConstantTripEstimator(double alpha, double beta) {
this.alpha = alpha;
this.beta = beta;
}

@Override
public Tuple<Double, Double> getAlphaBetaValues(Id<Link> fromLinkId, Id<Link> toLinkId, OptionalTime departureTime) {
return new Tuple<>(alpha, beta);
}
}
Loading

0 comments on commit 9376ecf

Please sign in to comment.