Skip to content

Commit

Permalink
Merge branch 'master' into feat/withinday-interaction-activities
Browse files Browse the repository at this point in the history
  • Loading branch information
sebhoerl authored Dec 1, 2023
2 parents cb80d42 + e998c8a commit 5a39980
Show file tree
Hide file tree
Showing 31 changed files with 597 additions and 102 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/code-coverage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
uses: actions/checkout@v4

- name: Setup Java
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'zulu'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
uses: actions/checkout@v4

- name: Setup Java
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'zulu'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-on-pr-merge.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
uses: actions/checkout@v4

- name: Setup Java
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'zulu'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-on-release-created.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
uses: actions/checkout@v4

- name: Setup Java
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'zulu'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-weekly.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
uses: actions/checkout@v4

- name: Setup Java
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'zulu'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/full-integration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
uses: actions/checkout@v4

- name: Setup Java
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'zulu'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/verify-push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ jobs:
- name: Setup Java
if: ${{matrix.module != 'matsim' || steps.detect-changes.outputs.outside-contribs == 'true'}}
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'zulu'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,23 @@ public VehicleEntry create(DvrpVehicle vehicle, double currentTime) {
Battery battery = ((EvDvrpVehicle)vehicle).getElectricVehicle().getBattery();
int nextTaskIdx;
double chargeBeforeNextTask;
if (schedule.getStatus() == ScheduleStatus.PLANNED) {
nextTaskIdx = 0;
chargeBeforeNextTask = battery.getCharge();
} else { // STARTED
Task currentTask = schedule.getCurrentTask();
ETaskTracker eTracker = (ETaskTracker)currentTask.getTaskTracker();
chargeBeforeNextTask = eTracker.predictChargeAtEnd();
nextTaskIdx = currentTask.getTaskIdx() + 1;

switch (schedule.getStatus()) {
case PLANNED:
nextTaskIdx = 0;
chargeBeforeNextTask = battery.getCharge();
break;
case STARTED:
Task currentTask = schedule.getCurrentTask();
ETaskTracker eTracker = (ETaskTracker) currentTask.getTaskTracker();
chargeBeforeNextTask = eTracker.predictChargeAtEnd();
nextTaskIdx = currentTask.getTaskIdx() + 1;
break;
default:
return null;
}


List<? extends Task> tasks = schedule.getTasks();
for (int i = nextTaskIdx; i < tasks.size() - 1; i++) {
chargeBeforeNextTask -= ((ETask)tasks.get(i)).getTotalEnergy();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.matsim.contrib.drt.extension.estimator;

/**
* This interface is used to provide an initial estimate for the drt service.
* Supposed to be used when no data is available from the simulation yet.
* The interface is exactly the same as {@link DrtEstimator}, but this class won't be called with update events.
*/
public interface DrtInitialEstimator extends DrtEstimator {
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.matsim.contrib.drt.extension.estimator;
package org.matsim.contrib.drt.extension.estimator.impl;

import org.apache.commons.math3.stat.descriptive.SummaryStatistics;
import org.apache.commons.math3.stat.regression.RegressionResults;
Expand All @@ -9,8 +9,9 @@
import org.matsim.api.core.v01.events.PersonMoneyEvent;
import org.matsim.api.core.v01.population.Person;
import org.matsim.contrib.drt.analysis.DrtEventSequenceCollector;
import org.matsim.contrib.drt.extension.estimator.DrtEstimator;
import org.matsim.contrib.drt.extension.estimator.DrtInitialEstimator;
import org.matsim.contrib.drt.extension.estimator.run.DrtEstimatorConfigGroup;
import org.matsim.contrib.drt.fare.DrtFareParams;
import org.matsim.contrib.drt.routing.DrtRoute;
import org.matsim.contrib.drt.run.DrtConfigGroup;
import org.matsim.contrib.drt.speedup.DrtSpeedUp;
Expand All @@ -32,6 +33,7 @@ public class BasicDrtEstimator implements DrtEstimator, IterationEndsListener {
private final DrtEventSequenceCollector collector;
private final DrtEstimatorConfigGroup config;
private final DrtConfigGroup drtConfig;
private final DrtInitialEstimator initial;

private final SplittableRandom rnd = new SplittableRandom();
/**
Expand All @@ -40,10 +42,11 @@ public class BasicDrtEstimator implements DrtEstimator, IterationEndsListener {
private GlobalEstimate currentEst;
private RegressionResults fare;

public BasicDrtEstimator(DrtEventSequenceCollector collector, DrtEstimatorConfigGroup config,
DrtConfigGroup drtConfig) {
public BasicDrtEstimator(DrtEventSequenceCollector collector, DrtInitialEstimator initial,
DrtEstimatorConfigGroup config, DrtConfigGroup drtConfig) {
//zones = injector.getModal(DrtZonalSystem.class);
this.collector = collector;
this.initial = initial;
this.config = config;
this.drtConfig = drtConfig;
}
Expand Down Expand Up @@ -115,23 +118,8 @@ public void notifyIterationEnds(IterationEndsEvent event) {
public Estimate estimate(DrtRoute route, OptionalTime departureTime) {

if (currentEst == null) {
// If not estimates are present, use travel time alpha as detour
// beta is not used, because estimates are supposed to be minimums and not worst cases
double travelTime = Math.min(route.getDirectRideTime() + drtConfig.maxAbsoluteDetour,
route.getDirectRideTime() * drtConfig.maxTravelTimeAlpha);

double fare = 0;
if (drtConfig.getDrtFareParams().isPresent()) {
DrtFareParams fareParams = drtConfig.getDrtFareParams().get();
fare = fareParams.distanceFare_m * route.getDistance()
+ fareParams.timeFare_h * route.getDirectRideTime() / 3600.0
+ fareParams.baseFare;

fare = Math.max(fare, fareParams.minFarePerTrip);
}

// for distance, also use the max travel time alpha
return new Estimate(route.getDistance() * drtConfig.maxTravelTimeAlpha, travelTime, drtConfig.maxWaitTime, fare, 0);
// Same interface, just different binding
return initial.estimate(route, departureTime);
}

double fare = 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.matsim.contrib.drt.extension.estimator.impl;

import org.matsim.contrib.drt.extension.estimator.DrtInitialEstimator;
import org.matsim.contrib.drt.fare.DrtFareParams;
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 DrtInitialEstimator {

private final DrtConfigGroup drtConfig;

/**
* Detour factor for the estimate. 1.0 means no detour, 2.0 means twice the distance.
*/
private final double detourFactor;

/**
* Constant waiting time estimate in seconds.
*/
private final double waitingTime;

public ConstantDrtEstimator(DrtConfigGroup drtConfig, double detourFactor, double waitingTime) {
this.drtConfig = drtConfig;
this.detourFactor = detourFactor;
this.waitingTime = waitingTime;
}

@Override
public Estimate estimate(DrtRoute route, OptionalTime departureTime) {

double distance = route.getDistance() * detourFactor;
double travelTime = route.getDirectRideTime() * detourFactor;

double fare = 0;
if (drtConfig.getDrtFareParams().isPresent()) {
DrtFareParams fareParams = drtConfig.getDrtFareParams().get();
fare = fareParams.distanceFare_m * distance
+ fareParams.timeFare_h * travelTime / 3600.0
+ fareParams.baseFare;

fare = Math.max(fare, fareParams.minFarePerTrip);
}

return new Estimate(distance, travelTime, waitingTime, fare, 0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.matsim.contrib.drt.extension.estimator.impl;

import org.matsim.contrib.drt.extension.estimator.DrtInitialEstimator;
import org.matsim.contrib.drt.fare.DrtFareParams;
import org.matsim.contrib.drt.routing.DrtRoute;
import org.matsim.contrib.drt.run.DrtConfigGroup;
import org.matsim.core.utils.misc.OptionalTime;

/**
* Uses the upper bounds from config for the initial estimate.
*/
public class PessimisticDrtEstimator implements DrtInitialEstimator {
private final DrtConfigGroup drtConfig;

public PessimisticDrtEstimator(DrtConfigGroup drtConfig) {
this.drtConfig = drtConfig;
}

@Override
public Estimate estimate(DrtRoute route, OptionalTime departureTime) {
// If not estimates are present, use travel time alpha as detour
// beta is not used, because estimates are supposed to be minimums and not worst cases
double travelTime = Math.min(route.getDirectRideTime() + drtConfig.maxAbsoluteDetour,
route.getDirectRideTime() * drtConfig.maxTravelTimeAlpha);

double fare = 0;
if (drtConfig.getDrtFareParams().isPresent()) {
DrtFareParams fareParams = drtConfig.getDrtFareParams().get();
fare = fareParams.distanceFare_m * route.getDistance()
+ fareParams.timeFare_h * route.getDirectRideTime() / 3600.0
+ fareParams.baseFare;

fare = Math.max(fare, fareParams.minFarePerTrip);
}

// for distance, also use the max travel time alpha
return new Estimate(route.getDistance() * drtConfig.maxTravelTimeAlpha, travelTime, drtConfig.maxWaitTime, fare, 0);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ public class DrtEstimatorConfigGroup extends ReflectiveConfigGroupWithConfigurab
public enum EstimatorType {
BASIC,

/**
* Will use the bound initial estimator, without any updates.
*/
INITIAL,

/**
* Custom estimator, that needs to provided via binding.
*/
Expand Down Expand Up @@ -58,4 +63,12 @@ public String getMode() {
return mode;
}

/**
* Set estimator type and return same instance.
*/
public DrtEstimatorConfigGroup withEstimator(EstimatorType estimator) {
this.estimator = estimator;
return this;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import com.google.inject.Singleton;
import com.google.inject.multibindings.MapBinder;
import org.matsim.contrib.drt.analysis.DrtEventSequenceCollector;
import org.matsim.contrib.drt.extension.estimator.BasicDrtEstimator;
import org.matsim.contrib.drt.extension.estimator.DrtEstimateAnalyzer;
import org.matsim.contrib.drt.extension.estimator.DrtEstimator;
import org.matsim.contrib.drt.extension.estimator.DrtInitialEstimator;
import org.matsim.contrib.drt.extension.estimator.impl.BasicDrtEstimator;
import org.matsim.contrib.drt.extension.estimator.impl.PessimisticDrtEstimator;
import org.matsim.contrib.drt.run.DrtConfigGroup;
import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup;
import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule;
Expand All @@ -14,13 +16,22 @@
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.controler.AbstractModule;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;

/**
* Main module that needs to be installed if any estimator is to be used.
*/
public class DrtEstimatorModule extends AbstractModule {


/**
* Map of initial providers.
*/
private final Map<String, Function<DrtConfigGroup, DrtInitialEstimator>> initial = new HashMap<>();

@Override
public void install() {

Expand All @@ -35,7 +46,24 @@ public void install() {
}
}

static final class ModeModule extends AbstractDvrpModeModule {
/**
* Configure initial estimators for the given modes.
*
* @param getter modal getter, which can be used to use other modal components via guice
*/
public DrtEstimatorModule withInitialEstimator(Function<DrtConfigGroup, DrtInitialEstimator> getter, String... modes) {

if (modes.length == 0)
throw new IllegalArgumentException("At least one mode needs to be provided.");

for (String mode : modes) {
initial.put(mode, getter);
}

return this;
}

final class ModeModule extends AbstractDvrpModeModule {

private final DrtConfigGroup cfg;
private final DrtEstimatorConfigGroup group;
Expand All @@ -52,10 +80,21 @@ public void install() {
// try with default injections and overwrite
if (group.estimator == DrtEstimatorConfigGroup.EstimatorType.BASIC) {
bindModal(DrtEstimator.class).toProvider(modalProvider(
getter -> new BasicDrtEstimator(getter.getModal(DrtEventSequenceCollector.class), group, cfg)
getter -> new BasicDrtEstimator(
getter.getModal(DrtEventSequenceCollector.class),
getter.getModal(DrtInitialEstimator.class),
group, cfg
)
)).in(Singleton.class);
} else if (group.estimator == DrtEstimatorConfigGroup.EstimatorType.INITIAL) {
bindModal(DrtEstimator.class).to(modalKey(DrtInitialEstimator.class));
}

if (initial.containsKey(group.mode)) {
bindModal(DrtInitialEstimator.class).toProvider(() -> initial.get(group.mode).apply(cfg)).in(Singleton.class);
} else
bindModal(DrtInitialEstimator.class).toInstance(new PessimisticDrtEstimator(cfg));

// DRT Estimators will be available as Map<DvrpMode, DrtEstimator>
MapBinder.newMapBinder(this.binder(), DvrpMode.class, DrtEstimator.class)
.addBinding(DvrpModes.mode(getMode()))
Expand Down
Loading

0 comments on commit 5a39980

Please sign in to comment.