Skip to content

Commit 751684e

Browse files
authored
Merge branch 'develop' into matsim-15
2 parents 8a409f8 + ffadf34 commit 751684e

File tree

47 files changed

+1061
-455
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1061
-455
lines changed

core/src/main/java/org/eqasim/core/analysis/run/RunTripAnalysis.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import org.eqasim.core.analysis.trips.TripReaderFromEvents;
1717
import org.eqasim.core.analysis.trips.TripReaderFromPopulation;
1818
import org.eqasim.core.analysis.trips.TripWriter;
19-
import org.eqasim.core.components.EqasimMainModeIdentifier;
2019
import org.matsim.api.core.v01.Scenario;
2120
import org.matsim.api.core.v01.network.Network;
2221
import org.matsim.core.config.CommandLine;
@@ -26,6 +25,7 @@
2625
import org.matsim.core.network.NetworkUtils;
2726
import org.matsim.core.network.io.MatsimNetworkReader;
2827
import org.matsim.core.router.MainModeIdentifier;
28+
import org.matsim.core.router.RoutingModeMainModeIdentifier;
2929
import org.matsim.core.scenario.ScenarioUtils;
3030
import org.matsim.facilities.ActivityFacilities;
3131
import org.matsim.facilities.MatsimFacilitiesReader;
@@ -66,7 +66,7 @@ public static void run(CommandLine cmd, PersonAnalysisFilter personAnalysisFilte
6666

6767
String outputPath = cmd.getOptionStrict("output-path");
6868

69-
MainModeIdentifier mainModeIdentifier = new EqasimMainModeIdentifier();
69+
MainModeIdentifier mainModeIdentifier = new RoutingModeMainModeIdentifier();
7070

7171
Collection<String> vehicleModes = Arrays.asList(cmd.getOption("vehicle-modes").orElse("car,pt").split(","))
7272
.stream().map(s -> s.trim()).collect(Collectors.toSet());

core/src/main/java/org/eqasim/core/analysis/trips/TripListener.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.matsim.api.core.v01.events.handler.PersonEntersVehicleEventHandler;
2525
import org.matsim.api.core.v01.events.handler.PersonLeavesVehicleEventHandler;
2626
import org.matsim.api.core.v01.network.Network;
27+
import org.matsim.api.core.v01.population.Leg;
2728
import org.matsim.api.core.v01.population.Person;
2829
import org.matsim.api.core.v01.population.PopulationFactory;
2930
import org.matsim.core.api.experimental.events.TeleportationArrivalEvent;
@@ -92,7 +93,9 @@ public void handleEvent(ActivityEndEvent event) {
9293
@Override
9394
public void handleEvent(PersonDepartureEvent event) {
9495
if (personFilter.analyzePerson(event.getPersonId())) {
95-
ongoing.get(event.getPersonId()).elements.add(factory.createLeg(event.getLegMode()));
96+
Leg leg = factory.createLeg(event.getLegMode());
97+
leg.getAttributes().putAttribute("routingMode", event.getRoutingMode());
98+
ongoing.get(event.getPersonId()).elements.add(leg);
9699
}
97100
}
98101

core/src/main/java/org/eqasim/core/components/EqasimComponentsModule.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
import org.matsim.core.controler.AbstractModule;
44
import org.matsim.core.router.MainModeIdentifier;
5+
import org.matsim.core.router.RoutingModeMainModeIdentifier;
56

67
public class EqasimComponentsModule extends AbstractModule {
78
@Override
89
public void install() {
9-
bind(MainModeIdentifier.class).to(EqasimMainModeIdentifier.class);
10+
bind(MainModeIdentifier.class).to(RoutingModeMainModeIdentifier.class);
1011
}
1112
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.eqasim.core.misc;
2+
3+
import java.lang.reflect.InvocationTargetException;
4+
5+
public class ClassUtils {
6+
public static <T> T getInstanceOfClassExtendingOtherClass(String className, Class<T> otherClass) {
7+
try {
8+
Class<?> classDescription = Class.forName(className);
9+
Object instance = null;
10+
try {
11+
instance = classDescription.getConstructor().newInstance();
12+
} catch (InstantiationException e) {
13+
throw new RuntimeException(e);
14+
} catch (IllegalAccessException e) {
15+
throw new RuntimeException(e);
16+
} catch (InvocationTargetException e) {
17+
throw new RuntimeException(e);
18+
} catch (NoSuchMethodException e) {
19+
throw new RuntimeException(String.format("The class %s does not have a constructor that does not require arguments", classDescription.getCanonicalName()), e);
20+
}
21+
22+
if (otherClass.isInstance(instance)) {
23+
return (T) instance;
24+
} else {
25+
throw new IllegalStateException(String.format("Class %s does not extend %s", classDescription.getCanonicalName(), otherClass.getCanonicalName()));
26+
}
27+
} catch (ClassNotFoundException e) {
28+
throw new RuntimeException(e);
29+
}
30+
}
31+
}

core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,18 @@
99
import org.eqasim.core.components.transit.EqasimTransitModule;
1010
import org.eqasim.core.components.transit.EqasimTransitQSimModule;
1111
import org.eqasim.core.simulation.calibration.CalibrationConfigGroup;
12+
import org.eqasim.core.simulation.mode_choice.epsilon.EpsilonModule;
1213
import org.matsim.api.core.v01.Id;
1314
import org.matsim.api.core.v01.Scenario;
1415
import org.matsim.api.core.v01.population.Person;
16+
import org.matsim.contrib.drt.routing.DrtRoute;
17+
import org.matsim.contrib.drt.routing.DrtRouteFactory;
18+
import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup;
19+
import org.matsim.contrib.drt.run.MultiModeDrtModule;
20+
import org.matsim.contrib.dvrp.run.DvrpConfigGroup;
21+
import org.matsim.contrib.dvrp.run.DvrpModule;
22+
import org.matsim.contrib.dvrp.run.DvrpQSimComponents;
23+
import org.matsim.contrib.dvrp.run.MultiModal;
1524
import org.matsim.contribs.discrete_mode_choice.modules.DiscreteModeChoiceModule;
1625
import org.matsim.contribs.discrete_mode_choice.modules.config.DiscreteModeChoiceConfigGroup;
1726
import org.matsim.core.config.Config;
@@ -46,13 +55,22 @@ public EqasimConfigurator() {
4655
new SwissRailRaptorModule(), //
4756
new EqasimTransitModule(), //
4857
new DiscreteModeChoiceModule(), //
49-
new EqasimComponentsModule() //
58+
new EqasimComponentsModule(),
59+
new EpsilonModule()//
5060
));
5161

5262
qsimModules.addAll(Arrays.asList( //
5363
new EqasimTransitQSimModule(), //
5464
new EqasimTrafficQSimModule() //
5565
));
66+
67+
this.registerOptionalConfigGroup(new MultiModeDrtConfigGroup(),
68+
Collections.singleton(new MultiModeDrtModule()),
69+
Collections.emptyList(),
70+
Collections.singletonList((controller, components) ->
71+
DvrpQSimComponents.activateAllModes((MultiModal<?>) controller.getConfig().getModules().get(MultiModeDrtConfigGroup.GROUP_NAME)).configure(components)));
72+
73+
this.registerOptionalConfigGroup(new DvrpConfigGroup(), Collections.singleton(new DvrpModule()));
5674
}
5775

5876
public ConfigGroup[] getConfigGroups() {
@@ -132,6 +150,7 @@ public void addOptionalConfigGroups(Config config) {
132150
}
133151

134152
public void configureScenario(Scenario scenario) {
153+
scenario.getPopulation().getFactory().getRouteFactories().setRouteFactory(DrtRoute.class, new DrtRouteFactory());
135154
}
136155

137156
public void adjustScenario(Scenario scenario) {

core/src/main/java/org/eqasim/core/simulation/analysis/EqasimAnalysisModule.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,29 @@
55
import org.eqasim.core.analysis.legs.LegListener;
66
import org.eqasim.core.analysis.pt.PublicTransportLegListener;
77
import org.eqasim.core.analysis.trips.TripListener;
8+
import org.eqasim.core.simulation.modes.drt.analysis.DrtAnalysisModule;
89
import org.matsim.api.core.v01.network.Network;
10+
import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup;
911
import org.matsim.core.controler.AbstractModule;
1012
import org.matsim.core.router.MainModeIdentifier;
1113
import org.matsim.pt.transitSchedule.api.TransitSchedule;
1214

1315
import com.google.inject.Provides;
1416
import com.google.inject.Singleton;
1517

18+
1619
public class EqasimAnalysisModule extends AbstractModule {
1720
@Override
1821
public void install() {
1922
addControlerListenerBinding().to(AnalysisOutputListener.class);
20-
bind(DefaultPersonAnalysisFilter.class);
21-
bind(PersonAnalysisFilter.class).to(DefaultPersonAnalysisFilter.class);
23+
if(getConfig().getModules().containsKey(MultiModeDrtConfigGroup.GROUP_NAME)) {
24+
install(new DrtAnalysisModule());
25+
} else {
26+
// Would be better if there was a way to add the module above as an overriding module from this method.
27+
// That way we could simply bind the two classes below before the if clause
28+
bind(DefaultPersonAnalysisFilter.class);
29+
bind(PersonAnalysisFilter.class).to(DefaultPersonAnalysisFilter.class);
30+
}
2231
}
2332

2433
@Provides

core/src/main/java/org/eqasim/core/simulation/mode_choice/EqasimModeChoiceModule.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.util.Collections;
44
import java.util.HashMap;
55
import java.util.Map;
6+
import java.util.stream.Collectors;
67

78
import org.eqasim.core.components.config.EqasimConfigGroup;
89
import org.eqasim.core.simulation.mode_choice.constraints.EqasimVehicleTourConstraint;
@@ -24,9 +25,15 @@
2425
import org.eqasim.core.simulation.mode_choice.utilities.predictors.PersonPredictor;
2526
import org.eqasim.core.simulation.mode_choice.utilities.predictors.PtPredictor;
2627
import org.eqasim.core.simulation.mode_choice.utilities.predictors.WalkPredictor;
28+
import org.eqasim.core.simulation.modes.drt.mode_choice.constraints.DrtWalkConstraint;
29+
import org.eqasim.core.simulation.modes.drt.mode_choice.predictors.DefaultDrtPredictor;
30+
import org.eqasim.core.simulation.modes.drt.mode_choice.predictors.DrtPredictor;
31+
import org.eqasim.core.simulation.modes.drt.mode_choice.utilities.estimators.DrtUtilityEstimator;
32+
import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup;
2733
import org.matsim.contribs.discrete_mode_choice.components.utils.home_finder.HomeFinder;
2834
import org.matsim.contribs.discrete_mode_choice.modules.config.DiscreteModeChoiceConfigGroup;
2935
import org.matsim.contribs.discrete_mode_choice.modules.config.VehicleTourConstraintConfigGroup;
36+
import org.matsim.core.config.Config;
3037
import org.matsim.core.router.TripRouter;
3138
import org.matsim.core.utils.timing.TimeInterpretation;
3239
import org.matsim.facilities.ActivityFacilities;
@@ -39,7 +46,7 @@
3946
public class EqasimModeChoiceModule extends AbstractEqasimExtension {
4047
public static final String PASSENGER_CONSTRAINT_NAME = "PassengerConstraint";
4148
public static final String OUTSIDE_CONSTRAINT_NAME = "OutsideConstraint";
42-
49+
public static final String DRT_WALK_CONSTRAINT = "DrtWalkConstraint";
4350
public static final String TOUR_LENGTH_FILTER_NAME = "TourLengthFilter";
4451
public static final String OUTSIDE_FILTER_NAME = "OutsideFilter";
4552

@@ -50,6 +57,7 @@ public class EqasimModeChoiceModule extends AbstractEqasimExtension {
5057
public static final String BIKE_ESTIMATOR_NAME = "BikeUtilityEstimator";
5158
public static final String WALK_ESTIMATOR_NAME = "WalkUtilityEstimator";
5259
public static final String ZERO_ESTIMATOR_NAME = "ZeroUtilityEstimator";
60+
public static final String DRT_ESTIMATOR_NAME = "DrtUtilityEstimator";
5361

5462
public static final String ZERO_COST_MODEL_NAME = "ZeroCostModel";
5563

@@ -60,6 +68,7 @@ public class EqasimModeChoiceModule extends AbstractEqasimExtension {
6068
protected void installEqasimExtension() {
6169
bindTripConstraintFactory(PASSENGER_CONSTRAINT_NAME).to(PassengerConstraint.Factory.class);
6270
bindTripConstraintFactory(OUTSIDE_CONSTRAINT_NAME).to(OutsideConstraint.Factory.class);
71+
bindTripConstraintFactory(DRT_WALK_CONSTRAINT).to(DrtWalkConstraint.Factory.class);
6372

6473
bindTourFilter(TOUR_LENGTH_FILTER_NAME).to(TourLengthFilter.class);
6574
bindTourFilter(OUTSIDE_FILTER_NAME).to(OutsideFilter.class);
@@ -71,12 +80,14 @@ protected void installEqasimExtension() {
7180
bind(BikePredictor.class);
7281
bind(WalkPredictor.class);
7382
bind(PersonPredictor.class);
83+
bind(DrtPredictor.class).to(DefaultDrtPredictor.class);
7484

7585
bindUtilityEstimator(ZERO_ESTIMATOR_NAME).to(ZeroUtilityEstimator.class);
7686
bindUtilityEstimator(CAR_ESTIMATOR_NAME).to(CarUtilityEstimator.class);
7787
bindUtilityEstimator(PT_ESTIMATOR_NAME).to(PtUtilityEstimator.class);
7888
bindUtilityEstimator(BIKE_ESTIMATOR_NAME).to(BikeUtilityEstimator.class);
7989
bindUtilityEstimator(WALK_ESTIMATOR_NAME).to(WalkUtilityEstimator.class);
90+
bindUtilityEstimator(DRT_ESTIMATOR_NAME).to(DrtUtilityEstimator.class);
8091

8192
bindCostModel(ZERO_COST_MODEL_NAME).to(ZeroCostModel.class);
8293

@@ -124,4 +135,14 @@ public EqasimVehicleTourConstraint.Factory provideEqasimVehicleTourConstraintFac
124135
VehicleTourConstraintConfigGroup config = dmcConfig.getVehicleTourConstraintConfig();
125136
return new EqasimVehicleTourConstraint.Factory(config.getRestrictedModes(), homeFinder);
126137
}
138+
139+
@Provides
140+
public DefaultDrtPredictor provideDefaultDrtPredictor(Config config, Map<String, Provider<CostModel>> factory) {
141+
if(!config.getModules().containsKey(MultiModeDrtConfigGroup.GROUP_NAME)) {
142+
throw new IllegalStateException(String.format("%s module not found", MultiModeDrtConfigGroup.GROUP_NAME));
143+
}
144+
EqasimConfigGroup eqasimConfigGroup = (EqasimConfigGroup) config.getModules().get(EqasimConfigGroup.GROUP_NAME);
145+
MultiModeDrtConfigGroup multiModeDrtConfigGroup = (MultiModeDrtConfigGroup) config.getModules().get(MultiModeDrtConfigGroup.GROUP_NAME);
146+
return new DefaultDrtPredictor(multiModeDrtConfigGroup.modes().collect(Collectors.toMap(mode -> mode, mode -> getCostModel(factory, eqasimConfigGroup, mode))));
147+
}
127148
}

core/src/main/java/org/eqasim/core/simulation/mode_choice/epsilon/AbstractEpsilonProvider.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,23 @@
99
import org.matsim.api.core.v01.population.Person;
1010

1111
public abstract class AbstractEpsilonProvider implements EpsilonProvider {
12-
private final MessageDigest digest;
13-
private final double maximumValue;
1412
private final long randomSeed;
1513

1614
public AbstractEpsilonProvider(long randomSeed) {
15+
this.randomSeed = randomSeed;
16+
}
17+
18+
protected double getUniformEpsilon(Id<Person> personId, int tripIndex, String mode) {
19+
20+
MessageDigest digest;
21+
double maximumValue;
1722
try {
18-
this.digest = MessageDigest.getInstance("SHA-512");
19-
this.maximumValue = BigInteger.valueOf(2).pow(digest.getDigestLength() * 8).doubleValue();
20-
this.randomSeed = randomSeed;
23+
digest = MessageDigest.getInstance("SHA-512");
24+
maximumValue = BigInteger.valueOf(2).pow(digest.getDigestLength() * 8).doubleValue();
2125
} catch (NoSuchAlgorithmException e) {
2226
throw new RuntimeException("Cannot find SHA-512 algorithm. Providing epsilons is not possible.");
2327
}
24-
}
2528

26-
protected double getUniformEpsilon(Id<Person> personId, int tripIndex, String mode) {
2729
digest.reset();
2830

2931
digest.update(ByteBuffer //
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package org.eqasim.core.simulation.mode_choice.epsilon;
2+
3+
import org.eqasim.core.components.config.EqasimConfigGroup;
4+
import org.matsim.contribs.discrete_mode_choice.modules.SelectorModule;
5+
import org.matsim.contribs.discrete_mode_choice.modules.config.DiscreteModeChoiceConfigGroup;
6+
import org.matsim.core.config.CommandLine;
7+
import org.matsim.core.config.Config;
8+
import org.matsim.core.config.ConfigUtils;
9+
10+
import java.util.Map;
11+
12+
public class AdaptConfigForEpsilon {
13+
14+
public static void main(String[] args) throws CommandLine.ConfigurationException {
15+
CommandLine commandLine = new CommandLine.Builder(args).requireOptions("input-config-path", "output-config-path").build();
16+
17+
Config config = ConfigUtils.loadConfig(commandLine.getOptionStrict("input-config-path"), new EqasimConfigGroup(), new DiscreteModeChoiceConfigGroup());
18+
commandLine.applyConfiguration(config);
19+
20+
DiscreteModeChoiceConfigGroup discreteModeChoiceConfigGroup = (DiscreteModeChoiceConfigGroup) config.getModules().get(DiscreteModeChoiceConfigGroup.GROUP_NAME);
21+
discreteModeChoiceConfigGroup.setSelector(SelectorModule.MAXIMUM);
22+
23+
EqasimConfigGroup eqasimConfigGroup = (EqasimConfigGroup) config.getModules().get(EqasimConfigGroup.GROUP_NAME);
24+
25+
26+
for(Map.Entry<String, String> entry: eqasimConfigGroup.getEstimators().entrySet()) {
27+
if(entry.getValue().startsWith(EpsilonModule.EPSILON_UTILITY_PREFIX)) {
28+
continue;
29+
}
30+
eqasimConfigGroup.setEstimator(entry.getKey(), EpsilonModule.EPSILON_UTILITY_PREFIX + entry.getValue());
31+
}
32+
33+
ConfigUtils.writeConfig(config, commandLine.getOptionStrict("output-config-path"));
34+
}
35+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package org.eqasim.core.simulation.mode_choice.epsilon;
2+
3+
import com.google.inject.Inject;
4+
import com.google.inject.Provider;
5+
import com.google.inject.Provides;
6+
import org.apache.log4j.Logger;
7+
import org.eqasim.core.components.config.EqasimConfigGroup;
8+
import org.eqasim.core.simulation.mode_choice.AbstractEqasimExtension;
9+
import org.eqasim.core.simulation.mode_choice.utilities.UtilityEstimator;
10+
import org.matsim.core.config.groups.GlobalConfigGroup;
11+
12+
import java.util.HashSet;
13+
import java.util.Map;
14+
import java.util.Set;
15+
16+
public class EpsilonModule extends AbstractEqasimExtension {
17+
18+
public static final Logger logger = Logger.getLogger(EpsilonModule.class);
19+
20+
public static final String EPSILON_UTILITY_PREFIX = "epsilon_";
21+
@Provides
22+
public GumbelEpsilonProvider provideGumbelEpsilonProvider(GlobalConfigGroup config) {
23+
return new GumbelEpsilonProvider(config.getRandomSeed(), 1.0);
24+
}
25+
26+
@Override
27+
protected void installEqasimExtension() {
28+
bind(EpsilonProvider.class).to(GumbelEpsilonProvider.class);
29+
30+
31+
EqasimConfigGroup eqasimConfigGroup = (EqasimConfigGroup) getConfig().getModules().get(EqasimConfigGroup.GROUP_NAME);
32+
Set<String> processed = new HashSet<>();
33+
for(Map.Entry<String, String > entry: eqasimConfigGroup.getEstimators().entrySet()) {
34+
String mode = entry.getKey();
35+
String utilityEstimator = entry.getValue();
36+
if(utilityEstimator.startsWith(EPSILON_UTILITY_PREFIX)) {
37+
if(processed.contains(utilityEstimator)) {
38+
logger.warn(String.format("The epsilon utility estimator '%s' is used for more than one mode. The seed of the epsilon generator will rely on the first mode", utilityEstimator));
39+
continue;
40+
}
41+
processed.add(utilityEstimator);
42+
String baseEstimator = utilityEstimator.substring(EPSILON_UTILITY_PREFIX.length());
43+
bindUtilityEstimator(utilityEstimator).toProvider(new Provider<>() {
44+
@Inject
45+
private Map<String, Provider<UtilityEstimator>> factory;
46+
47+
@Inject
48+
private EpsilonProvider epsilonProvider;
49+
50+
@Override
51+
public UtilityEstimator get() {
52+
UtilityEstimator delegate = factory.get(baseEstimator).get();
53+
return new EpsilonAdapter(mode, delegate, epsilonProvider);
54+
}
55+
});
56+
}
57+
}
58+
}
59+
}

core/src/main/java/org/eqasim/core/simulation/mode_choice/parameters/ModeParameters.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ public class WalkParameters {
3030
public double betaTravelTime_u_min = 0.0;
3131
}
3232

33+
public class DrtParameters {
34+
public double alpha_u = 0.0;
35+
public double betaTravelTime_u_min = 0.0;
36+
public double betaWaitingTime_u_min = 0.0;
37+
public double betaAccessEgressTime_u_min = 0.0;
38+
}
39+
40+
3341
public double lambdaCostEuclideanDistance = 0.0;
3442
public double referenceEuclideanDistance_km = 0.0;
3543

@@ -39,4 +47,5 @@ public class WalkParameters {
3947
public final PtParameters pt = new PtParameters();
4048
public final BikeParameters bike = new BikeParameters();
4149
public final WalkParameters walk = new WalkParameters();
50+
public final DrtParameters drt = new DrtParameters();
4251
}

0 commit comments

Comments
 (0)