From eb692d80daf9510ea8d2b166ad3ee414d179a2e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Mon, 30 Sep 2024 13:50:07 +0200 Subject: [PATCH 01/37] activate epsilon by default --- .../mode_choice/epsilon/AdaptConfigForEpsilon.java | 10 +++++++--- .../eqasim/ile_de_france/scenario/RunAdaptConfig.java | 4 ++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/eqasim/core/simulation/mode_choice/epsilon/AdaptConfigForEpsilon.java b/core/src/main/java/org/eqasim/core/simulation/mode_choice/epsilon/AdaptConfigForEpsilon.java index d379e3fb2..313d46cff 100644 --- a/core/src/main/java/org/eqasim/core/simulation/mode_choice/epsilon/AdaptConfigForEpsilon.java +++ b/core/src/main/java/org/eqasim/core/simulation/mode_choice/epsilon/AdaptConfigForEpsilon.java @@ -17,7 +17,13 @@ public static void main(String[] args) throws CommandLine.ConfigurationException Config config = ConfigUtils.loadConfig(commandLine.getOptionStrict("input-config-path"), new EqasimConfigGroup(), new DiscreteModeChoiceConfigGroup()); commandLine.applyConfiguration(config); - DiscreteModeChoiceConfigGroup discreteModeChoiceConfigGroup = (DiscreteModeChoiceConfigGroup) config.getModules().get(DiscreteModeChoiceConfigGroup.GROUP_NAME); + run(config); + + ConfigUtils.writeConfig(config, commandLine.getOptionStrict("output-config-path")); + } + + static public void run(Config config) { + DiscreteModeChoiceConfigGroup discreteModeChoiceConfigGroup = (DiscreteModeChoiceConfigGroup) config.getModules().get(DiscreteModeChoiceConfigGroup.GROUP_NAME); discreteModeChoiceConfigGroup.setSelector(SelectorModule.MAXIMUM); EqasimConfigGroup eqasimConfigGroup = (EqasimConfigGroup) config.getModules().get(EqasimConfigGroup.GROUP_NAME); @@ -29,7 +35,5 @@ public static void main(String[] args) throws CommandLine.ConfigurationException } eqasimConfigGroup.setEstimator(entry.getKey(), EpsilonModule.EPSILON_UTILITY_PREFIX + entry.getValue()); } - - ConfigUtils.writeConfig(config, commandLine.getOptionStrict("output-config-path")); } } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java index a171cbef6..0c36105be 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java @@ -2,6 +2,7 @@ import org.eqasim.core.components.config.ConfigAdapter; import org.eqasim.core.components.config.EqasimConfigGroup; +import org.eqasim.core.simulation.mode_choice.epsilon.AdaptConfigForEpsilon; import org.eqasim.ile_de_france.IDFConfigurator; import org.eqasim.ile_de_france.mode_choice.IDFModeChoiceModule; import org.matsim.api.core.v01.TransportMode; @@ -32,6 +33,9 @@ static public void adaptConfiguration(Config config, String prefix) { .get(DiscreteModeChoiceConfigGroup.GROUP_NAME); dmcConfig.setModeAvailability(IDFModeChoiceModule.MODE_AVAILABILITY_NAME); + + // Epsilon + AdaptConfigForEpsilon.run(config); // Calibration results for 5% From 6649152ba5fa224aad34de0e46e8ab1ec217d153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Mon, 30 Sep 2024 13:57:34 +0200 Subject: [PATCH 02/37] integrate transit routing parameters --- .../raptor/EqasimRaptorConfigGroup.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/org/eqasim/core/components/raptor/EqasimRaptorConfigGroup.java b/core/src/main/java/org/eqasim/core/components/raptor/EqasimRaptorConfigGroup.java index d0ee550f9..c496a6007 100644 --- a/core/src/main/java/org/eqasim/core/components/raptor/EqasimRaptorConfigGroup.java +++ b/core/src/main/java/org/eqasim/core/components/raptor/EqasimRaptorConfigGroup.java @@ -10,26 +10,26 @@ public EqasimRaptorConfigGroup() { } @Parameter - public double travelTimeRail_u_h = -7.0; + public double travelTimeRail_u_h = -1.4278139352278472; @Parameter - public double travelTimeSubway_u_h = -7.0; + public double travelTimeSubway_u_h = -1.0; @Parameter - public double travelTimeBus_u_h = -7.0; + public double travelTimeBus_u_h = -2.835025304050246; @Parameter - public double travelTimeTram_u_h = -7.0; + public double travelTimeTram_u_h = -3.199594607188756; @Parameter - public double travelTimeOther_u_h = -7.0; + public double travelTimeOther_u_h = -2.835025304050246; @Parameter - public double perTransfer_u = -1.0; + public double perTransfer_u = -0.5441109013512305; @Parameter - public double waitTime_u_h = -6.0; + public double waitTime_u_h = -0.497984826174775; @Parameter - public double walkTime_u_h = -7.0; + public double walkTime_u_h = -3.8494071051697385; } From d4a55d9e412fd9131bfa9ac583649aac41c07807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Mon, 30 Sep 2024 16:31:56 +0200 Subject: [PATCH 03/37] update crossing penalty --- .../components/traffic/CrossingPenalty.java | 7 +++ .../traffic/DefaultCrossingPenalty.java | 54 +++++++++++++++++++ .../traffic/EqasimLinkSpeedCalculator.java | 23 ++------ .../traffic/EqasimTrafficModule.java | 21 ++++++++ .../traffic/EqasimTrafficQSimModule.java | 5 +- .../scenario/preparation/AdjustFreespeed.java | 40 ++++++++++++++ .../core/simulation/EqasimConfigurator.java | 4 +- .../eqasim/core/simulation/vdf/VDFModule.java | 5 +- .../vdf/travel_time/VDFTravelTime.java | 40 +++++--------- .../test/java/org/eqasim/TestEmissions.java | 18 ++++--- .../scenario/RunAdaptConfig.java | 11 ++-- 11 files changed, 162 insertions(+), 66 deletions(-) create mode 100644 core/src/main/java/org/eqasim/core/components/traffic/CrossingPenalty.java create mode 100644 core/src/main/java/org/eqasim/core/components/traffic/DefaultCrossingPenalty.java create mode 100644 core/src/main/java/org/eqasim/core/components/traffic/EqasimTrafficModule.java create mode 100644 core/src/main/java/org/eqasim/core/scenario/preparation/AdjustFreespeed.java diff --git a/core/src/main/java/org/eqasim/core/components/traffic/CrossingPenalty.java b/core/src/main/java/org/eqasim/core/components/traffic/CrossingPenalty.java new file mode 100644 index 000000000..875716a91 --- /dev/null +++ b/core/src/main/java/org/eqasim/core/components/traffic/CrossingPenalty.java @@ -0,0 +1,7 @@ +package org.eqasim.core.components.traffic; + +import org.matsim.api.core.v01.network.Link; + +public interface CrossingPenalty { + double calculateCrossingPenalty(Link link); +} diff --git a/core/src/main/java/org/eqasim/core/components/traffic/DefaultCrossingPenalty.java b/core/src/main/java/org/eqasim/core/components/traffic/DefaultCrossingPenalty.java new file mode 100644 index 000000000..412a143a6 --- /dev/null +++ b/core/src/main/java/org/eqasim/core/components/traffic/DefaultCrossingPenalty.java @@ -0,0 +1,54 @@ +package org.eqasim.core.components.traffic; + +import org.matsim.api.core.v01.IdSet; +import org.matsim.api.core.v01.TransportMode; +import org.matsim.api.core.v01.network.Link; +import org.matsim.api.core.v01.network.Network; + +public class DefaultCrossingPenalty implements CrossingPenalty { + static public final String MAJOR_CROSSING_ATTRIBUTE = "eqasim:majorCrossing"; + + private final IdSet penalizedLinkIds; + private final double crossingPenalty; + + DefaultCrossingPenalty(IdSet penalizedLinkIds, double crossingPenalty) { + this.penalizedLinkIds = penalizedLinkIds; + this.crossingPenalty = crossingPenalty; + } + + @Override + public double calculateCrossingPenalty(Link link) { + if (penalizedLinkIds.contains(link.getId())) { + return crossingPenalty; + } else { + return 0.0; + } + } + + static public DefaultCrossingPenalty build(Network network, double crossingPenalty) { + IdSet penalizedLinkIds = new IdSet<>(Link.class); + + for (Link link : network.getLinks().values()) { + if (link.getAllowedModes().contains(TransportMode.car)) { + if (link.getToNode().getInLinks().size() > 1) { // otherwise straight road or diverge + double maximumCapacity = Double.NEGATIVE_INFINITY; + boolean foundLower = false; + + for (Link inlink : link.getToNode().getInLinks().values()) { + if (inlink.getCapacity() > maximumCapacity) { + maximumCapacity = inlink.getCapacity(); + } + + foundLower |= inlink.getCapacity() < link.getCapacity(); + } + + if (link.getCapacity() == maximumCapacity && foundLower) { + penalizedLinkIds.add(link.getId()); + } + } + } + } + + return new DefaultCrossingPenalty(penalizedLinkIds, crossingPenalty); + } +} diff --git a/core/src/main/java/org/eqasim/core/components/traffic/EqasimLinkSpeedCalculator.java b/core/src/main/java/org/eqasim/core/components/traffic/EqasimLinkSpeedCalculator.java index 98345a6ae..98e56d789 100644 --- a/core/src/main/java/org/eqasim/core/components/traffic/EqasimLinkSpeedCalculator.java +++ b/core/src/main/java/org/eqasim/core/components/traffic/EqasimLinkSpeedCalculator.java @@ -5,30 +5,17 @@ import org.matsim.core.mobsim.qsim.qnetsimengine.linkspeedcalculator.LinkSpeedCalculator; public class EqasimLinkSpeedCalculator implements LinkSpeedCalculator { - final private double crossingPenalty; + private final CrossingPenalty crossingPenalty; - public EqasimLinkSpeedCalculator(double crossingPenalty) { + public EqasimLinkSpeedCalculator(CrossingPenalty crossingPenalty) { this.crossingPenalty = crossingPenalty; } @Override public double getMaximumVelocity(QVehicle vehicle, Link link, double time) { - boolean isMajor = true; - - for (Link other : link.getToNode().getInLinks().values()) { - if (other.getCapacity() >= link.getCapacity()) { - isMajor = false; - } - } - double maximumVelocity = Math.min(vehicle.getMaximumVelocity(), link.getFreespeed(time)); - - if (isMajor || link.getToNode().getInLinks().size() == 1) { - return maximumVelocity; - } else { - double travelTime = link.getLength() / maximumVelocity; - travelTime += crossingPenalty; - return link.getLength() / travelTime; - } + double travelTime = link.getLength() / maximumVelocity; + travelTime += crossingPenalty.calculateCrossingPenalty(link); + return link.getLength() / travelTime; } } diff --git a/core/src/main/java/org/eqasim/core/components/traffic/EqasimTrafficModule.java b/core/src/main/java/org/eqasim/core/components/traffic/EqasimTrafficModule.java new file mode 100644 index 000000000..8f8b2b98d --- /dev/null +++ b/core/src/main/java/org/eqasim/core/components/traffic/EqasimTrafficModule.java @@ -0,0 +1,21 @@ +package org.eqasim.core.components.traffic; + +import org.eqasim.core.components.config.EqasimConfigGroup; +import org.matsim.api.core.v01.network.Network; +import org.matsim.core.controler.AbstractModule; + +import com.google.inject.Provides; +import com.google.inject.Singleton; + +public class EqasimTrafficModule extends AbstractModule { + @Override + public void install() { + bind(CrossingPenalty.class).to(DefaultCrossingPenalty.class); + } + + @Provides + @Singleton + public DefaultCrossingPenalty provideDefaultCrossingPenalty(Network network, EqasimConfigGroup eqasimConfig) { + return DefaultCrossingPenalty.build(network, eqasimConfig.getCrossingPenalty()); + } +} diff --git a/core/src/main/java/org/eqasim/core/components/traffic/EqasimTrafficQSimModule.java b/core/src/main/java/org/eqasim/core/components/traffic/EqasimTrafficQSimModule.java index 752a75f6e..e102c8db6 100644 --- a/core/src/main/java/org/eqasim/core/components/traffic/EqasimTrafficQSimModule.java +++ b/core/src/main/java/org/eqasim/core/components/traffic/EqasimTrafficQSimModule.java @@ -1,6 +1,5 @@ package org.eqasim.core.components.traffic; -import org.eqasim.core.components.config.EqasimConfigGroup; import org.matsim.core.mobsim.qsim.AbstractQSimModule; import org.matsim.core.mobsim.qsim.qnetsimengine.linkspeedcalculator.LinkSpeedCalculator; @@ -15,7 +14,7 @@ protected void configureQSim() { @Provides @Singleton - public EqasimLinkSpeedCalculator provideBaselineLinkSpeedCalculator(EqasimConfigGroup eqasimConfig) { - return new EqasimLinkSpeedCalculator(eqasimConfig.getCrossingPenalty()); + public EqasimLinkSpeedCalculator provideBaselineLinkSpeedCalculator(CrossingPenalty crossigPenalty) { + return new EqasimLinkSpeedCalculator(crossigPenalty); } } diff --git a/core/src/main/java/org/eqasim/core/scenario/preparation/AdjustFreespeed.java b/core/src/main/java/org/eqasim/core/scenario/preparation/AdjustFreespeed.java new file mode 100644 index 000000000..e9a21bf6c --- /dev/null +++ b/core/src/main/java/org/eqasim/core/scenario/preparation/AdjustFreespeed.java @@ -0,0 +1,40 @@ +package org.eqasim.core.scenario.preparation; + +import org.matsim.api.core.v01.Scenario; +import org.matsim.api.core.v01.network.Link; +import org.matsim.api.core.v01.network.Network; +import org.matsim.core.config.CommandLine; +import org.matsim.core.config.CommandLine.ConfigurationException; + +public class AdjustFreespeed { + static public final String INITIAL_FREESPEED = "eqasim:initialFreespeed"; + + static public void main(String[] args) throws ConfigurationException { + CommandLine commandLine = new CommandLine.Builder(args) // + .requireOptions("input-path", "output-path") // + .allowPrefixes("freespeed") // + .build(); + + + + } + + static public void run(Network network) { + + } + + static public void validate(Scenario scenario) { + boolean valid = false; + + for (Link link : scenario.getNetwork().getLinks().values()) { + if (link.getAttributes().getAttribute(INITIAL_FREESPEED) != null) { + valid = true; + break; + } + } + + if (!valid) { + throw new IllegalStateException("Did not find initial freespeed. Did you call AdjustFreespeed?"); + } + } +} diff --git a/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java b/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java index 3f759caff..00c4d233e 100644 --- a/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java +++ b/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java @@ -7,6 +7,7 @@ import org.eqasim.core.components.config.EqasimConfigGroup; import org.eqasim.core.components.raptor.EqasimRaptorConfigGroup; import org.eqasim.core.components.raptor.EqasimRaptorModule; +import org.eqasim.core.components.traffic.EqasimTrafficModule; import org.eqasim.core.components.traffic.EqasimTrafficQSimModule; import org.eqasim.core.components.transit.EqasimTransitModule; import org.eqasim.core.components.transit.EqasimTransitQSimModule; @@ -79,7 +80,8 @@ public EqasimConfigurator() { new EqasimComponentsModule(), // new EpsilonModule(), // new EqasimRaptorModule(), - new EqasimModeChoiceModule()// + new EqasimModeChoiceModule(), // + new EqasimTrafficModule() // )); qsimModules.addAll(Arrays.asList( // diff --git a/core/src/main/java/org/eqasim/core/simulation/vdf/VDFModule.java b/core/src/main/java/org/eqasim/core/simulation/vdf/VDFModule.java index 53ba1918d..98bbf919b 100644 --- a/core/src/main/java/org/eqasim/core/simulation/vdf/VDFModule.java +++ b/core/src/main/java/org/eqasim/core/simulation/vdf/VDFModule.java @@ -6,6 +6,7 @@ import java.util.Optional; import org.eqasim.core.components.config.EqasimConfigGroup; +import org.eqasim.core.components.traffic.CrossingPenalty; import org.eqasim.core.scenario.cutter.extent.ScenarioExtent; import org.eqasim.core.scenario.cutter.extent.ShapeScenarioExtent; import org.eqasim.core.simulation.vdf.handlers.VDFHorizonHandler; @@ -69,10 +70,10 @@ public VDFScope provideVDFScope(VDFConfigGroup config) { @Provides @Singleton public VDFTravelTime provideVDFTravelTime(VDFConfigGroup config, VDFScope scope, Network network, - VolumeDelayFunction vdf, QSimConfigGroup qsimConfig, EqasimConfigGroup eqasimConfig) throws IOException { + VolumeDelayFunction vdf, QSimConfigGroup qsimConfig, EqasimConfigGroup eqasimConfig, CrossingPenalty crossingPenalty) throws IOException { ScenarioExtent updateExtent = config.getUpdateAreaShapefile() == null ? null : new ShapeScenarioExtent.Builder(new File(ConfigGroup.getInputFileURL(getConfig().getContext(), config.getUpdateAreaShapefile()).getPath()), Optional.empty(), Optional.empty()).build(); return new VDFTravelTime(scope, config.getMinimumSpeed(), config.getCapacityFactor(), - eqasimConfig.getSampleSize(), network, vdf, eqasimConfig.getCrossingPenalty(), updateExtent); + eqasimConfig.getSampleSize(), network, vdf, crossingPenalty, updateExtent); } @Provides diff --git a/core/src/main/java/org/eqasim/core/simulation/vdf/travel_time/VDFTravelTime.java b/core/src/main/java/org/eqasim/core/simulation/vdf/travel_time/VDFTravelTime.java index 994fe22ee..8df59c2a9 100644 --- a/core/src/main/java/org/eqasim/core/simulation/vdf/travel_time/VDFTravelTime.java +++ b/core/src/main/java/org/eqasim/core/simulation/vdf/travel_time/VDFTravelTime.java @@ -7,6 +7,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.eqasim.core.components.traffic.CrossingPenalty; import org.eqasim.core.scenario.cutter.extent.ScenarioExtent; import org.eqasim.core.simulation.vdf.VDFScope; import org.eqasim.core.simulation.vdf.travel_time.function.VolumeDelayFunction; @@ -24,23 +25,25 @@ public class VDFTravelTime implements TravelTime { private final double minimumSpeed; private final double capacityFactor; private final double samplingRate; - private final double crossingPenalty; private final Network network; private final VolumeDelayFunction vdf; private final ScenarioExtent updateAreaExtent; + private final CrossingPenalty crossingPenalty; + private final IdMap> travelTimes = new IdMap<>(Link.class); private final Logger logger = LogManager.getLogger(VDFTravelTime.class); public VDFTravelTime(VDFScope scope, double minimumSpeed, double capacityFactor, double samplingRate, - Network network, VolumeDelayFunction vdf, double crossingPenalty) { + Network network, VolumeDelayFunction vdf, CrossingPenalty crossingPenalty) { this(scope, minimumSpeed, capacityFactor, samplingRate, network, vdf, crossingPenalty, null); } public VDFTravelTime(VDFScope scope, double minimumSpeed, double capacityFactor, double samplingRate, - Network network, VolumeDelayFunction vdf, double crossingPenalty, ScenarioExtent updateAreaExtent) { + Network network, VolumeDelayFunction vdf, CrossingPenalty crossingPenalty, + ScenarioExtent updateAreaExtent) { this.scope = scope; this.network = network; this.vdf = vdf; @@ -53,8 +56,8 @@ public VDFTravelTime(VDFScope scope, double minimumSpeed, double capacityFactor, for (Link link : network.getLinks().values()) { double travelTime = Math.max(1.0, Math.min(link.getLength() / minimumSpeed, link.getLength() / link.getFreespeed())); - travelTimes.put(link.getId(), new ArrayList<>( - Collections.nCopies(scope.getIntervals(), considerCrossingPenalty(link, travelTime)))); + travelTimes.put(link.getId(), new ArrayList<>(Collections.nCopies(scope.getIntervals(), + travelTime + crossingPenalty.calculateCrossingPenalty(link)))); } } @@ -70,7 +73,7 @@ public void update(IdMap> counts) { public void update(IdMap> counts, boolean forceUpdateAllLinks) { String logMessage = "Updating VDFTravelTime "; - if(updateAreaExtent != null && !forceUpdateAllLinks) { + if (updateAreaExtent != null && !forceUpdateAllLinks) { logMessage += " using update extent ..."; } else { logMessage += " ..."; @@ -82,12 +85,13 @@ public void update(IdMap> counts, boolean forceUpdateAllLinks for (Map.Entry, List> entry : counts.entrySet()) { Link link = network.getLinks().get(entry.getKey()); - if(link == null) { + if (link == null) { continue; } - if(updateAreaExtent != null && !forceUpdateAllLinks) { - if(!updateAreaExtent.isInside(link.getFromNode().getCoord()) || !updateAreaExtent.isInside(link.getToNode().getCoord())) { + if (updateAreaExtent != null && !forceUpdateAllLinks) { + if (!updateAreaExtent.isInside(link.getFromNode().getCoord()) + || !updateAreaExtent.isInside(link.getToNode().getCoord())) { continue; } } @@ -105,7 +109,7 @@ public void update(IdMap> counts, boolean forceUpdateAllLinks double travelTime = Math.max(1.0, Math.min(link.getLength() / minimumSpeed, vdf.getTravelTime(time, flow, capacity, link))); - linkTravelTimes.set(i, considerCrossingPenalty(link, travelTime)); + linkTravelTimes.set(i, travelTime + crossingPenalty.calculateCrossingPenalty(link)); if (travelTime > link.getLength() / link.getFreespeed()) { nonFreespeedCount += 1; @@ -115,20 +119,4 @@ public void update(IdMap> counts, boolean forceUpdateAllLinks logger.info(String.format(" Done: %d/%d are slower than freespeed", nonFreespeedCount, totalCount)); } - - private double considerCrossingPenalty(Link link, double baseTravelTime) { - boolean isMajor = true; - - for (Link other : link.getToNode().getInLinks().values()) { - if (other.getCapacity() >= link.getCapacity()) { - isMajor = false; - } - } - - if (isMajor || link.getToNode().getInLinks().size() == 1) { - return baseTravelTime; - } else { - return baseTravelTime + crossingPenalty; - } - } } diff --git a/core/src/test/java/org/eqasim/TestEmissions.java b/core/src/test/java/org/eqasim/TestEmissions.java index bef761534..ab897f275 100644 --- a/core/src/test/java/org/eqasim/TestEmissions.java +++ b/core/src/test/java/org/eqasim/TestEmissions.java @@ -168,11 +168,11 @@ private void runModifyNetwork() { private void runMelunEmissions() throws CommandLine.ConfigurationException, IOException { Map counts = countLegs("melun_test/output/output_events.xml.gz"); - Assert.assertEquals(3297, (long) counts.get("car")); - Assert.assertEquals(1560, (long) counts.get("car_passenger")); - Assert.assertEquals(9348, (long) counts.get("walk")); - Assert.assertEquals(3412, (long) counts.getOrDefault("bike", 0L)); - Assert.assertEquals(2108, (long) counts.get("pt")); + Assert.assertEquals(2793, (long) counts.get("car")); + Assert.assertEquals(1559, (long) counts.get("car_passenger")); + Assert.assertEquals(11642, (long) counts.get("walk")); + Assert.assertEquals(2861, (long) counts.getOrDefault("bike", 0L)); + Assert.assertEquals(3347, (long) counts.get("pt")); RunComputeEmissionsEvents.main(new String[] { "--config-path", "melun_test/input/config.xml", "--hbefa-cold-avg", "sample_41_EFA_ColdStart_vehcat_2020average.csv", "--hbefa-hot-avg", @@ -180,7 +180,7 @@ private void runMelunEmissions() throws CommandLine.ConfigurationException, IOEx "sample_41_EFA_ColdStart_SubSegm_2020detailed.csv", "--hbefa-hot-detailed", "sample_41_EFA_HOT_SubSegm_2020detailed.csv", }); - assertEquals(355977, countLines(new File("melun_test/output/output_emissions_events.xml.gz"))); + assertEquals(334633, countLines(new File("melun_test/output/output_emissions_events.xml.gz"))); RunExportEmissionsNetwork.main(new String[] { "--config-path", "melun_test/input/config.xml", "--pollutants", "PM,CO,NOx,Unknown", "--time-bin-size", "3600" }); @@ -197,10 +197,12 @@ private void runMelunEmissions() throws CommandLine.ConfigurationException, IOEx & f.getAttribute("time").toString().equals("43200")).findFirst().orElse(null); assertNotNull(feature); - double expectedPm = 0.006847378350421; - double expectedCo = 0.456258730331835; + double expectedPm = 0.006288836075491; + double expectedCo = 0.263774681387141; double expectedNox = 0.477558671071797; double expectedUnknown = Double.NaN; + + assertEquals(expectedPm, feature.getAttribute("PM")); assertEquals(expectedCo, feature.getAttribute("CO")); diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java index 0c36105be..96bc9010f 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java @@ -34,16 +34,11 @@ static public void adaptConfiguration(Config config, String prefix) { dmcConfig.setModeAvailability(IDFModeChoiceModule.MODE_AVAILABILITY_NAME); + // Major crossing penalty from calibration + eqasimConfig.setCrossingPenalty(4.2); + // Epsilon AdaptConfigForEpsilon.run(config); - - // Calibration results for 5% - - if (eqasimConfig.getSampleSize() == 0.05) { - // Adjust flow and storage capacity - config.qsim().setFlowCapFactor(0.045); - config.qsim().setStorageCapFactor(0.045); - } // Vehicles QSimConfigGroup qsimConfig = config.qsim(); From 8ef52520c1a005e41c3d23c471a81bd1f1a97132 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Mon, 30 Sep 2024 22:36:27 +0200 Subject: [PATCH 04/37] update choice model --- .../mode_choice/IDFModeAvailability.java | 39 ++------ .../mode_choice/IDFModeChoiceModule.java | 32 +++++-- .../ile_de_france/mode_choice/SynpopTODO.java | 9 ++ .../costs/IDFMotorbikeCostModel.java | 27 ++++++ .../mode_choice/costs/IDFPtCostModel.java | 94 +++++++------------ .../parameters/IDFCostParameters.java | 4 +- .../parameters/IDFModeParameters.java | 80 ++++++++++------ .../estimators/IDFBikeUtilityEstimator.java | 51 ---------- .../estimators/IDFCarUtilityEstimator.java | 34 +++---- .../IDFMotorbikeUtilityEstimator.java | 56 +++++++++++ .../IDFPassengerUtilityEstimator.java | 49 ++++++++++ .../estimators/IDFPtUtilityEstimator.java | 54 +++++++++++ .../predictors/IDFMotorbikePredictor.java | 53 +++++++++++ .../predictors/IDFPassengerPredictor.java | 42 +++++++++ .../predictors/IDFPersonPredictor.java | 4 +- .../predictors/IDFPredictorUtils.java | 24 ++++- .../utilities/predictors/IDFPtPredictor.java | 53 +++++++++++ .../predictors/IDFSpatialPredictor.java | 23 ----- .../variables/IDFMotorbikeVariables.java | 18 ++++ .../variables/IDFPassengerVariables.java | 15 +++ .../variables/IDFPersonVariables.java | 4 +- .../utilities/variables/IDFPtVariables.java | 13 +++ .../variables/IDFSpatialVariables.java | 13 --- .../scenario/RunAdaptConfig.java | 4 +- 24 files changed, 553 insertions(+), 242 deletions(-) create mode 100644 ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/SynpopTODO.java create mode 100644 ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFMotorbikeCostModel.java delete mode 100644 ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFBikeUtilityEstimator.java create mode 100644 ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFMotorbikeUtilityEstimator.java create mode 100644 ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFPassengerUtilityEstimator.java create mode 100644 ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFPtUtilityEstimator.java create mode 100644 ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFMotorbikePredictor.java create mode 100644 ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPassengerPredictor.java create mode 100644 ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java delete mode 100644 ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFSpatialPredictor.java create mode 100644 ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFMotorbikeVariables.java create mode 100644 ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPassengerVariables.java create mode 100644 ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPtVariables.java delete mode 100644 ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFSpatialVariables.java diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeAvailability.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeAvailability.java index b193c2bb6..cf77d84a1 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeAvailability.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeAvailability.java @@ -4,11 +4,11 @@ import java.util.HashSet; import java.util.List; +import org.eqasim.ile_de_france.mode_choice.utilities.predictors.IDFPredictorUtils; import org.matsim.api.core.v01.TransportMode; import org.matsim.api.core.v01.population.Person; import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; import org.matsim.contribs.discrete_mode_choice.model.mode_availability.ModeAvailability; -import org.matsim.core.population.PersonUtils; public class IDFModeAvailability implements ModeAvailability { @Override @@ -18,47 +18,28 @@ public Collection getAvailableModes(Person person, List elements) { + return costParameters.motorbikeCost_EUR_km * getInVehicleDistance_km(elements); + } +} diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFPtCostModel.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFPtCostModel.java index 37ac35dce..4a5780809 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFPtCostModel.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFPtCostModel.java @@ -4,100 +4,70 @@ import org.eqasim.core.simulation.mode_choice.cost.CostModel; import org.eqasim.ile_de_france.mode_choice.utilities.predictors.IDFPersonPredictor; -import org.eqasim.ile_de_france.mode_choice.utilities.predictors.IDFSpatialPredictor; +import org.eqasim.ile_de_france.mode_choice.utilities.predictors.IDFPtPredictor; import org.eqasim.ile_de_france.mode_choice.utilities.variables.IDFPersonVariables; -import org.eqasim.ile_de_france.mode_choice.utilities.variables.IDFSpatialVariables; +import org.eqasim.ile_de_france.mode_choice.utilities.variables.IDFPtVariables; import org.matsim.api.core.v01.Coord; -import org.matsim.api.core.v01.TransportMode; -import org.matsim.api.core.v01.population.Leg; import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.PlanElement; import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; import org.matsim.core.utils.geometry.CoordUtils; -import org.matsim.pt.routes.TransitPassengerRoute; -import org.matsim.pt.transitSchedule.api.TransitSchedule; import com.google.inject.Inject; public class IDFPtCostModel implements CostModel { private final IDFPersonPredictor personPredictor; - private final IDFSpatialPredictor spatialPredictor; - - // TODO: This should be hidden by some custom predictor - private final TransitSchedule transitSchedule; + private final IDFPtPredictor ptPredictor; @Inject - public IDFPtCostModel(IDFPersonPredictor personPredictor, IDFSpatialPredictor spatialPredictor, - TransitSchedule transitSchedule) { + public IDFPtCostModel(IDFPersonPredictor personPredictor, IDFPtPredictor ptPredictor) { this.personPredictor = personPredictor; - this.spatialPredictor = spatialPredictor; - this.transitSchedule = transitSchedule; - } - - private boolean isOnlyMetroOrBus(List elements) { - for (PlanElement element : elements) { - if (element instanceof Leg) { - Leg leg = (Leg) element; - - if (leg.getMode().equals(TransportMode.pt)) { - TransitPassengerRoute route = (TransitPassengerRoute) leg.getRoute(); - - String transportMode = transitSchedule.getTransitLines().get(route.getLineId()).getRoutes() - .get(route.getRouteId()).getTransportMode(); - - if (!transportMode.equals("bus") && !transportMode.equals("subway")) { - return false; - } - } - } - } - - return true; + this.ptPredictor = ptPredictor; } private final static Coord CENTER = new Coord(651726, 6862287); - private double calculateBasisDistance_km(DiscreteModeChoiceTrip trip) { - return 1e-3 * (CoordUtils.calcEuclideanDistance(CENTER, trip.getOriginActivity().getCoord()) - + CoordUtils.calcEuclideanDistance(CENTER, trip.getDestinationActivity().getCoord())); - } + private final static double regressionA = 0.098; + private final static double regressionB = 0.006; + private final static double regressionC = 0.006; + private final static double regressionD = -0.77; @Override public double calculateCost_MU(Person person, DiscreteModeChoiceTrip trip, List elements) { // I) If the person has a subscription, the price is zero! - IDFPersonVariables personVariables = personPredictor.predictVariables(person, trip, elements); if (personVariables.hasSubscription) { return 0.0; } - // II) If the trip is entirely inside of Paris, or it only consists of metro and - // bus, the price is 1.80 EUR - - IDFSpatialVariables spatialVariables = spatialPredictor.predictVariables(person, trip, elements); - boolean isWithinParis = spatialVariables.hasUrbanOrigin && spatialVariables.hasUrbanDestination; + // II) Special case: Within Paris or only metro and bus + IDFPtVariables ptVariables = ptPredictor.predictVariables(person, trip, elements); + boolean isWithinParis = false; - boolean isOnlyMetroOrBus = isOnlyMetroOrBus(elements); + if (true) { + throw new IllegalStateException("find out if this is in paris"); + } - if (isOnlyMetroOrBus || isWithinParis) { + if (ptVariables.hasOnlySubwayAndBus || isWithinParis) { return 1.8; } - /*- - * III) Otherwise, we calculate as follows: - * - * 1) Determine the Euclidean distance from the origin station to the center of Paris. - * 2) Determine the Euclidean distance from the destination station to the center of Paris. - * 3) Add up the two distances to arrive at the distance D as the basis for price calculation. - * 4) Calculate 0.25 EUR/km * D to arrive at a rough price estimate. - * - * This assumes that trips in Île-de-France usually must cross through Paris (and otherwise - * they would usually be a bus). And some brief experimentation with the route planner of - * RATP showed that the prices are roghly constructed by the total ride distance with - * a price per distance. TODO: A more detailed analysis would be good to have! - */ - - return 0.25 * calculateBasisDistance_km(trip); + // III) Otherwise, use regression by Abdelkader DIB + double directDistance_km = 1e-3 * CoordUtils.calcEuclideanDistance(trip.getOriginActivity().getCoord(), + trip.getDestinationActivity().getCoord()); + + double originCenterDistance_km = 1e-3 + * CoordUtils.calcEuclideanDistance(CENTER, trip.getOriginActivity().getCoord()); + + double destinationCenterDistance_km = 1e-3 + * CoordUtils.calcEuclideanDistance(CENTER, trip.getDestinationActivity().getCoord()); + + return Math.max(1.9, sigmoid(regressionA * directDistance_km + regressionB * originCenterDistance_km + + regressionC * destinationCenterDistance_km + regressionD)); + } + + private double sigmoid(double x) { + return 1.0 / (1.0 + Math.exp(x)); } } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFCostParameters.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFCostParameters.java index 4e2563840..bdf6b5e1a 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFCostParameters.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFCostParameters.java @@ -4,11 +4,13 @@ public class IDFCostParameters implements ParameterDefinition { public double carCost_EUR_km = 0.0; + public double motorbikeCost_EUR_km = 0.0; public static IDFCostParameters buildDefault() { IDFCostParameters parameters = new IDFCostParameters(); - parameters.carCost_EUR_km = 0.15; + parameters.carCost_EUR_km = 0.2; + parameters.motorbikeCost_EUR_km = 0.1; return parameters; } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFModeParameters.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFModeParameters.java index e145acd47..fbab01232 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFModeParameters.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFModeParameters.java @@ -4,52 +4,78 @@ public class IDFModeParameters extends ModeParameters { public class IDFCarParameters { - public double betaInsideUrbanArea; - public double betaCrossingUrbanArea; + public double betaInVehicleTravelTime_u_min; } - public class IDFBikeParameters { - public double betaInsideUrbanArea; + public final IDFCarParameters idfCar = new IDFCarParameters(); + + public class IDFPassengerParameters { + public double alpha_u; + public double betaInVehicleTravelTime_u_min; + public double betaDrivingPermit_u; } - public final IDFCarParameters idfCar = new IDFCarParameters(); - public final IDFBikeParameters idfBike = new IDFBikeParameters(); + public final IDFPassengerParameters idfPassenger = new IDFPassengerParameters(); + + public class IDFMotorbikeParameters { + public double alpha_u; + public double betaInVehicleTravelTime_u_min; + } + + public final IDFMotorbikeParameters idfMotorbike = new IDFMotorbikeParameters(); + + public class IDFPtParameters { + public double betaDrivingPermit_u; + public double onlyBus_u; + } + + public final IDFPtParameters idfPt = new IDFPtParameters(); + + public double betaAccessTime_u_min; public static IDFModeParameters buildDefault() { IDFModeParameters parameters = new IDFModeParameters(); + // Access + parameters.betaAccessTime_u_min = -0.0313; + // Cost - parameters.betaCost_u_MU = -0.206; - parameters.lambdaCostEuclideanDistance = -0.4; - parameters.referenceEuclideanDistance_km = 40.0; + parameters.betaCost_u_MU = -0.474; + parameters.lambdaCostEuclideanDistance = -0.274; + parameters.referenceEuclideanDistance_km = 4.4; // Car - parameters.car.alpha_u = 1.35; - parameters.car.betaTravelTime_u_min = -0.06; + parameters.car.alpha_u = -0.662; + parameters.car.betaTravelTime_u_min = -0.0262; + + parameters.idfCar.betaInVehicleTravelTime_u_min = -0.0262; + + // Car passenger + parameters.idfPassenger.alpha_u = -2.08; + parameters.idfPassenger.betaDrivingPermit_u = -1.17; + parameters.idfPassenger.betaInVehicleTravelTime_u_min = -0.0608; - parameters.car.additionalAccessEgressWalkTime_min = 4.0; - parameters.car.constantParkingSearchPenalty_min = 4.0; - - parameters.idfCar.betaInsideUrbanArea = -0.5; - parameters.idfCar.betaCrossingUrbanArea = -1.0; + // Motorbike + parameters.idfMotorbike.alpha_u = -2.2; + parameters.idfMotorbike.betaInVehicleTravelTime_u_min = -0.0321; // PT parameters.pt.alpha_u = 0.0; - parameters.pt.betaLineSwitch_u = -0.17; - parameters.pt.betaInVehicleTime_u_min = -0.017; - parameters.pt.betaWaitingTime_u_min = -0.0484; - parameters.pt.betaAccessEgressTime_u_min = -0.0804; + parameters.pt.betaLineSwitch_u = -0.452; + parameters.pt.betaInVehicleTime_u_min = -0.0201; + parameters.pt.betaWaitingTime_u_min = -0.0191; + parameters.pt.betaAccessEgressTime_u_min = parameters.betaAccessTime_u_min; + parameters.idfPt.betaDrivingPermit_u = -0.712; + parameters.idfPt.onlyBus_u = -1.42; + // Bike - parameters.bike.alpha_u = -2.0; - parameters.bike.betaTravelTime_u_min = -0.05; - parameters.bike.betaAgeOver18_u_a = -0.0496; - - parameters.idfBike.betaInsideUrbanArea = 1.5; + parameters.bike.alpha_u = -3.42; + parameters.bike.betaTravelTime_u_min = -0.0824; // Walk - parameters.walk.alpha_u = 1.43; - parameters.walk.betaTravelTime_u_min = -0.15; + parameters.walk.alpha_u = 1.2; + parameters.walk.betaTravelTime_u_min = -0.158; return parameters; } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFBikeUtilityEstimator.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFBikeUtilityEstimator.java deleted file mode 100644 index 4c77d18bc..000000000 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFBikeUtilityEstimator.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.eqasim.ile_de_france.mode_choice.utilities.estimators; - -import java.util.List; - -import org.eqasim.core.simulation.mode_choice.utilities.estimators.BikeUtilityEstimator; -import org.eqasim.core.simulation.mode_choice.utilities.predictors.BikePredictor; -import org.eqasim.core.simulation.mode_choice.utilities.predictors.PersonPredictor; -import org.eqasim.ile_de_france.mode_choice.parameters.IDFModeParameters; -import org.eqasim.ile_de_france.mode_choice.utilities.predictors.IDFSpatialPredictor; -import org.eqasim.ile_de_france.mode_choice.utilities.variables.IDFSpatialVariables; -import org.matsim.api.core.v01.population.Person; -import org.matsim.api.core.v01.population.PlanElement; -import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; - -import com.google.inject.Inject; - -public class IDFBikeUtilityEstimator extends BikeUtilityEstimator { - private final IDFModeParameters parameters; - private final IDFSpatialPredictor spatialPredictor; - - @Inject - public IDFBikeUtilityEstimator(IDFModeParameters parameters, IDFSpatialPredictor spatialPredictor, - PersonPredictor personPredictor, BikePredictor bikePredictor) { - super(parameters, personPredictor, bikePredictor); - - this.parameters = parameters; - this.spatialPredictor = spatialPredictor; - } - - protected double estimateUrbanUtility(IDFSpatialVariables variables) { - double utility = 0.0; - - if (variables.hasUrbanOrigin && variables.hasUrbanDestination) { - utility += parameters.idfBike.betaInsideUrbanArea; - } - - return utility; - } - - @Override - public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List elements) { - IDFSpatialVariables variables = spatialPredictor.predictVariables(person, trip, elements); - - double utility = 0.0; - - utility += super.estimateUtility(person, trip, elements); - utility += estimateUrbanUtility(variables); - - return utility; - } -} diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFCarUtilityEstimator.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFCarUtilityEstimator.java index ca318a373..24e9f1b1f 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFCarUtilityEstimator.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFCarUtilityEstimator.java @@ -4,9 +4,8 @@ import org.eqasim.core.simulation.mode_choice.utilities.estimators.CarUtilityEstimator; import org.eqasim.core.simulation.mode_choice.utilities.predictors.CarPredictor; +import org.eqasim.core.simulation.mode_choice.utilities.variables.CarVariables; import org.eqasim.ile_de_france.mode_choice.parameters.IDFModeParameters; -import org.eqasim.ile_de_france.mode_choice.utilities.predictors.IDFSpatialPredictor; -import org.eqasim.ile_de_france.mode_choice.utilities.variables.IDFSpatialVariables; import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.PlanElement; import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; @@ -15,39 +14,30 @@ public class IDFCarUtilityEstimator extends CarUtilityEstimator { private final IDFModeParameters parameters; - private final IDFSpatialPredictor spatialPredictor; + private final CarPredictor predictor; @Inject - public IDFCarUtilityEstimator(IDFModeParameters parameters, IDFSpatialPredictor spatialPredictor, - CarPredictor carPredictor) { - super(parameters, carPredictor); + public IDFCarUtilityEstimator(IDFModeParameters parameters, CarPredictor predictor) { + super(parameters, predictor); this.parameters = parameters; - this.spatialPredictor = spatialPredictor; + this.predictor = predictor; } - protected double estimateUrbanUtility(IDFSpatialVariables variables) { - double utility = 0.0; - - if (variables.hasUrbanOrigin && variables.hasUrbanDestination) { - utility += parameters.idfCar.betaInsideUrbanArea; - } - - if (variables.hasUrbanOrigin || variables.hasUrbanDestination) { - utility += parameters.idfCar.betaCrossingUrbanArea; - } - - return utility; + protected double estimateAccessEgressTimeUtility(CarVariables variables) { + return parameters.betaAccessTime_u_min * variables.accessEgressTime_min; } @Override public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List elements) { - IDFSpatialVariables variables = spatialPredictor.predictVariables(person, trip, elements); + CarVariables variables = predictor.predictVariables(person, trip, elements); double utility = 0.0; - utility += super.estimateUtility(person, trip, elements); - utility += estimateUrbanUtility(variables); + utility += estimateConstantUtility(); + utility += estimateTravelTimeUtility(variables); + utility += estimateAccessEgressTimeUtility(variables); + utility += estimateMonetaryCostUtility(variables); return utility; } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFMotorbikeUtilityEstimator.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFMotorbikeUtilityEstimator.java new file mode 100644 index 000000000..38f1942c6 --- /dev/null +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFMotorbikeUtilityEstimator.java @@ -0,0 +1,56 @@ +package org.eqasim.ile_de_france.mode_choice.utilities.estimators; + +import java.util.List; + +import org.eqasim.core.simulation.mode_choice.utilities.UtilityEstimator; +import org.eqasim.core.simulation.mode_choice.utilities.estimators.EstimatorUtils; +import org.eqasim.ile_de_france.mode_choice.parameters.IDFModeParameters; +import org.eqasim.ile_de_france.mode_choice.utilities.predictors.IDFMotorbikePredictor; +import org.eqasim.ile_de_france.mode_choice.utilities.variables.IDFMotorbikeVariables; +import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.PlanElement; +import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; + +import com.google.inject.Inject; + +public class IDFMotorbikeUtilityEstimator implements UtilityEstimator { + private final IDFModeParameters parameters; + private final IDFMotorbikePredictor predictor; + + @Inject + public IDFMotorbikeUtilityEstimator(IDFModeParameters parameters, IDFMotorbikePredictor predictor) { + this.parameters = parameters; + this.predictor = predictor; + } + + protected double estimateConstantUtility() { + return parameters.idfMotorbike.alpha_u; + } + + protected double estimateTravelTimeUtility(IDFMotorbikeVariables variables) { + return parameters.idfMotorbike.betaInVehicleTravelTime_u_min * variables.travelTime_min; + } + + protected double estimateAccessEgressTimeUtility(IDFMotorbikeVariables variables) { + return parameters.betaAccessTime_u_min * variables.accessEgressTime_min; + } + + protected double estimateMonetaryCostUtility(IDFMotorbikeVariables variables) { + return parameters.betaCost_u_MU * EstimatorUtils.interaction(variables.euclideanDistance_km, + parameters.referenceEuclideanDistance_km, parameters.lambdaCostEuclideanDistance) * variables.cost_MU; + } + + @Override + public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List elements) { + IDFMotorbikeVariables variables = predictor.predictVariables(person, trip, elements); + + double utility = 0.0; + + utility += estimateConstantUtility(); + utility += estimateTravelTimeUtility(variables); + utility += estimateAccessEgressTimeUtility(variables); + utility += estimateMonetaryCostUtility(variables); + + return utility; + } +} \ No newline at end of file diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFPassengerUtilityEstimator.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFPassengerUtilityEstimator.java new file mode 100644 index 000000000..610829606 --- /dev/null +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFPassengerUtilityEstimator.java @@ -0,0 +1,49 @@ +package org.eqasim.ile_de_france.mode_choice.utilities.estimators; + +import java.util.List; + +import org.eqasim.core.simulation.mode_choice.utilities.UtilityEstimator; +import org.eqasim.ile_de_france.mode_choice.parameters.IDFModeParameters; +import org.eqasim.ile_de_france.mode_choice.utilities.predictors.IDFPassengerPredictor; +import org.eqasim.ile_de_france.mode_choice.utilities.variables.IDFPassengerVariables; +import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.PlanElement; +import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; + +import com.google.inject.Inject; + +public class IDFPassengerUtilityEstimator implements UtilityEstimator { + private final IDFModeParameters parameters; + private final IDFPassengerPredictor predictor; + + @Inject + public IDFPassengerUtilityEstimator(IDFModeParameters parameters, IDFPassengerPredictor predictor) { + this.parameters = parameters; + this.predictor = predictor; + } + + protected double estimateConstantUtility() { + return parameters.idfPassenger.alpha_u; + } + + protected double estimateTravelTimeUtility(IDFPassengerVariables variables) { + return parameters.idfPassenger.betaInVehicleTravelTime_u_min * variables.travelTime_min; + } + + protected double estimateAccessEgressTimeUtility(IDFPassengerVariables variables) { + return parameters.betaAccessTime_u_min * variables.accessEgressTime_min; + } + + @Override + public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List elements) { + IDFPassengerVariables variables = predictor.predictVariables(person, trip, elements); + + double utility = 0.0; + + utility += estimateConstantUtility(); + utility += estimateTravelTimeUtility(variables); + utility += estimateAccessEgressTimeUtility(variables); + + return utility; + } +} \ No newline at end of file diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFPtUtilityEstimator.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFPtUtilityEstimator.java new file mode 100644 index 000000000..e61ec0dcf --- /dev/null +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFPtUtilityEstimator.java @@ -0,0 +1,54 @@ +package org.eqasim.ile_de_france.mode_choice.utilities.estimators; + +import java.util.List; + +import org.eqasim.core.simulation.mode_choice.utilities.estimators.PtUtilityEstimator; +import org.eqasim.core.simulation.mode_choice.utilities.predictors.PtPredictor; +import org.eqasim.ile_de_france.mode_choice.parameters.IDFModeParameters; +import org.eqasim.ile_de_france.mode_choice.utilities.predictors.IDFPersonPredictor; +import org.eqasim.ile_de_france.mode_choice.utilities.predictors.IDFPtPredictor; +import org.eqasim.ile_de_france.mode_choice.utilities.variables.IDFPersonVariables; +import org.eqasim.ile_de_france.mode_choice.utilities.variables.IDFPtVariables; +import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.PlanElement; +import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; + +import com.google.inject.Inject; + +public class IDFPtUtilityEstimator extends PtUtilityEstimator { + private final IDFModeParameters parameters; + private final IDFPersonPredictor personPredictor; + private final IDFPtPredictor idfPtPredictor; + + @Inject + public IDFPtUtilityEstimator(IDFModeParameters parameters, IDFPtPredictor idfPtPredictor, + IDFPersonPredictor personPredictor, PtPredictor ptPredictor) { + super(parameters, ptPredictor); + + this.personPredictor = personPredictor; + this.idfPtPredictor = idfPtPredictor; + this.parameters = parameters; + } + + protected double estimateDrivingPermitUtility(IDFPersonVariables variables) { + return variables.hasDrivingPermit ? parameters.idfPt.betaDrivingPermit_u : 0.0; + } + + protected double estimateOnlyBus(IDFPtVariables variables) { + return variables.isOnlyBus ? parameters.idfPt.onlyBus_u : 0.0; + } + + @Override + public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List elements) { + IDFPersonVariables personVariables = personPredictor.predictVariables(person, trip, elements); + IDFPtVariables ptVariables = idfPtPredictor.predictVariables(person, trip, elements); + + double utility = 0.0; + + utility += super.estimateUtility(person, trip, elements); + utility += estimateDrivingPermitUtility(personVariables); + utility += estimateOnlyBus(ptVariables); + + return utility; + } +} diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFMotorbikePredictor.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFMotorbikePredictor.java new file mode 100644 index 000000000..43cf46fe8 --- /dev/null +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFMotorbikePredictor.java @@ -0,0 +1,53 @@ +package org.eqasim.ile_de_france.mode_choice.utilities.predictors; + +import java.util.List; + +import org.eqasim.core.simulation.mode_choice.cost.CostModel; +import org.eqasim.core.simulation.mode_choice.utilities.predictors.CachedVariablePredictor; +import org.eqasim.core.simulation.mode_choice.utilities.predictors.PredictorUtils; +import org.eqasim.ile_de_france.mode_choice.IDFModeChoiceModule; +import org.eqasim.ile_de_france.mode_choice.utilities.variables.IDFMotorbikeVariables; +import org.matsim.api.core.v01.TransportMode; +import org.matsim.api.core.v01.population.Leg; +import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.PlanElement; +import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; +import org.matsim.core.router.TripStructureUtils; + +import com.google.common.base.Verify; +import com.google.inject.Inject; +import com.google.inject.name.Named; + +public class IDFMotorbikePredictor extends CachedVariablePredictor { + private final CostModel costModel; + + @Inject + public IDFMotorbikePredictor(@Named(IDFModeChoiceModule.MOTORBIKE) CostModel costModel) { + this.costModel = costModel; + } + + @Override + public IDFMotorbikeVariables predict(Person person, DiscreteModeChoiceTrip trip, + List elements) { + double motorbikeTravelTime_min = 0.0; + double accessEgressTime_min = 0.0; + + boolean foundCar = false; + + for (Leg leg : TripStructureUtils.getLegs(elements)) { + if (leg.getMode().equals(IDFModeChoiceModule.MOTORBIKE)) { + Verify.verify(!foundCar); + motorbikeTravelTime_min += leg.getTravelTime().seconds() / 60.0; + } else if (leg.getMode().equals(TransportMode.walk)) { + accessEgressTime_min += leg.getTravelTime().seconds() / 60.0; + } else { + throw new IllegalStateException("Unexpected mode in motorbike chain: " + leg.getMode()); + } + } + + double cost_MU = costModel.calculateCost_MU(person, trip, elements); + double euclideanDistance_km = PredictorUtils.calculateEuclideanDistance_km(trip); + + return new IDFMotorbikeVariables(motorbikeTravelTime_min, cost_MU, euclideanDistance_km, accessEgressTime_min); + } +} \ No newline at end of file diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPassengerPredictor.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPassengerPredictor.java new file mode 100644 index 000000000..2fea60c66 --- /dev/null +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPassengerPredictor.java @@ -0,0 +1,42 @@ +package org.eqasim.ile_de_france.mode_choice.utilities.predictors; + +import java.util.List; + +import org.eqasim.core.simulation.mode_choice.utilities.predictors.CachedVariablePredictor; +import org.eqasim.core.simulation.mode_choice.utilities.predictors.PredictorUtils; +import org.eqasim.ile_de_france.mode_choice.IDFModeChoiceModule; +import org.eqasim.ile_de_france.mode_choice.utilities.variables.IDFPassengerVariables; +import org.matsim.api.core.v01.TransportMode; +import org.matsim.api.core.v01.population.Leg; +import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.PlanElement; +import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; +import org.matsim.core.router.TripStructureUtils; + +import com.google.common.base.Verify; + +public class IDFPassengerPredictor extends CachedVariablePredictor { + @Override + public IDFPassengerVariables predict(Person person, DiscreteModeChoiceTrip trip, + List elements) { + double passengerTravelTime_min = 0.0; + double accessEgressTime_min = 0.0; + + boolean foundCar = false; + + for (Leg leg : TripStructureUtils.getLegs(elements)) { + if (leg.getMode().equals(IDFModeChoiceModule.PASSENGER)) { + Verify.verify(!foundCar); + passengerTravelTime_min += leg.getTravelTime().seconds() / 60.0; + } else if (leg.getMode().equals(TransportMode.walk)) { + accessEgressTime_min += leg.getTravelTime().seconds() / 60.0; + } else { + throw new IllegalStateException("Unexpected mode in passenger chain: " + leg.getMode()); + } + } + + double euclideanDistance_km = PredictorUtils.calculateEuclideanDistance_km(trip); + + return new IDFPassengerVariables(passengerTravelTime_min, euclideanDistance_km, accessEgressTime_min); + } +} \ No newline at end of file diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPersonPredictor.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPersonPredictor.java index e4d5d5ca0..249b82371 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPersonPredictor.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPersonPredictor.java @@ -7,12 +7,14 @@ import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.PlanElement; import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; +import org.matsim.core.population.PersonUtils; public class IDFPersonPredictor extends CachedVariablePredictor { @Override protected IDFPersonVariables predict(Person person, DiscreteModeChoiceTrip trip, List elements) { boolean hasSubscription = IDFPredictorUtils.hasSubscription(person); - return new IDFPersonVariables(hasSubscription); + boolean hasDrivingPermit = !"no".equals(PersonUtils.getLicense(person)); + return new IDFPersonVariables(hasSubscription, hasDrivingPermit); } } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPredictorUtils.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPredictorUtils.java index 1672f3c16..b49d88e00 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPredictorUtils.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPredictorUtils.java @@ -1,7 +1,7 @@ package org.eqasim.ile_de_france.mode_choice.utilities.predictors; -import org.matsim.api.core.v01.population.Activity; import org.matsim.api.core.v01.population.Person; +import org.matsim.core.population.PersonUtils; public class IDFPredictorUtils { static public boolean hasSubscription(Person person) { @@ -9,8 +9,24 @@ static public boolean hasSubscription(Person person) { return hasSubscription != null && hasSubscription; } - static public boolean isUrbanArea(Activity activity) { - Boolean isUrban = (Boolean) activity.getAttributes().getAttribute("isUrban"); - return isUrban != null && isUrban; + static public boolean isOutside(Person person) { + Boolean isOutside = (Boolean) person.getAttributes().getAttribute("outside"); + return isOutside != null && isOutside; + } + + static public boolean hasDrivingLicense(Person person) { + return !"no".equals(PersonUtils.getLicense(person)); + } + + static public boolean hasCarAvailability(Person person) { + return !"none".equals((String) person.getAttributes().getAttribute("carAvailability")); + } + + static public boolean hasBicycleAvailability(Person person) { + return !"none".equals((String) person.getAttributes().getAttribute("bicycleAvailability")); + } + + static public boolean hasMotorbikeAvailability(Person person) { + return !"none".equals((String) person.getAttributes().getAttribute("motorbikeAvailability")); } } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java new file mode 100644 index 000000000..26014a3a0 --- /dev/null +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java @@ -0,0 +1,53 @@ +package org.eqasim.ile_de_france.mode_choice.utilities.predictors; + +import java.util.List; + +import org.eqasim.core.simulation.mode_choice.utilities.predictors.CachedVariablePredictor; +import org.eqasim.ile_de_france.mode_choice.utilities.variables.IDFPtVariables; +import org.matsim.api.core.v01.population.Leg; +import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.PlanElement; +import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; +import org.matsim.pt.routes.TransitPassengerRoute; +import org.matsim.pt.transitSchedule.api.TransitLine; +import org.matsim.pt.transitSchedule.api.TransitRoute; +import org.matsim.pt.transitSchedule.api.TransitSchedule; + +import com.google.inject.Inject; + +public class IDFPtPredictor extends CachedVariablePredictor { + private final TransitSchedule schedule; + + @Inject + public IDFPtPredictor(TransitSchedule schedule) { + this.schedule = schedule; + } + + @Override + public IDFPtVariables predict(Person person, DiscreteModeChoiceTrip trip, List elements) { + int busCount = 0; + int subwayCount = 0; + int otherCount = 0; + + for (PlanElement element : elements) { + if (element instanceof Leg leg) { + if (leg instanceof TransitPassengerRoute route) { + TransitLine transitLine = schedule.getTransitLines().get(route.getLineId()); + TransitRoute transitRoute = transitLine.getRoutes().get(route.getRouteId()); + String transportMode = transitRoute.getTransportMode(); + + if (transportMode.equals("bus")) { + busCount++; + } else if (transportMode.equals("subway")) { + subwayCount++; + } + } + } + } + + boolean isOnlyBus = busCount > 0 && subwayCount == 0 && otherCount == 0; + boolean hasOnlySubwayAndBus = (busCount > 0 || subwayCount > 0) && otherCount == 0; + + return new IDFPtVariables(isOnlyBus, hasOnlySubwayAndBus); + } +} \ No newline at end of file diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFSpatialPredictor.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFSpatialPredictor.java deleted file mode 100644 index dbafe6437..000000000 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFSpatialPredictor.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.eqasim.ile_de_france.mode_choice.utilities.predictors; - -import java.util.List; - -import org.eqasim.core.simulation.mode_choice.utilities.predictors.CachedVariablePredictor; -import org.eqasim.ile_de_france.mode_choice.utilities.variables.IDFSpatialVariables; -import org.matsim.api.core.v01.population.Person; -import org.matsim.api.core.v01.population.PlanElement; -import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; - -import com.google.inject.Singleton; - -@Singleton -public class IDFSpatialPredictor extends CachedVariablePredictor { - @Override - protected IDFSpatialVariables predict(Person person, DiscreteModeChoiceTrip trip, - List elements) { - boolean hasUrbanOrigin = IDFPredictorUtils.isUrbanArea(trip.getOriginActivity()); - boolean hasUrbanDestination = IDFPredictorUtils.isUrbanArea(trip.getDestinationActivity()); - - return new IDFSpatialVariables(hasUrbanOrigin, hasUrbanDestination); - } -} diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFMotorbikeVariables.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFMotorbikeVariables.java new file mode 100644 index 000000000..31065c9ad --- /dev/null +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFMotorbikeVariables.java @@ -0,0 +1,18 @@ +package org.eqasim.ile_de_france.mode_choice.utilities.variables; + +import org.eqasim.core.simulation.mode_choice.utilities.variables.BaseVariables; + +public class IDFMotorbikeVariables implements BaseVariables { + final public double travelTime_min; + final public double cost_MU; + final public double euclideanDistance_km; + final public double accessEgressTime_min; + + public IDFMotorbikeVariables(double travelTime_min, double cost_MU, double euclideanDistance_km, + double accessEgressTime_min) { + this.travelTime_min = travelTime_min; + this.cost_MU = cost_MU; + this.euclideanDistance_km = euclideanDistance_km; + this.accessEgressTime_min = accessEgressTime_min; + } +} diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPassengerVariables.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPassengerVariables.java new file mode 100644 index 000000000..6701629a9 --- /dev/null +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPassengerVariables.java @@ -0,0 +1,15 @@ +package org.eqasim.ile_de_france.mode_choice.utilities.variables; + +import org.eqasim.core.simulation.mode_choice.utilities.variables.BaseVariables; + +public class IDFPassengerVariables implements BaseVariables { + final public double travelTime_min; + final public double euclideanDistance_km; + final public double accessEgressTime_min; + + public IDFPassengerVariables(double travelTime_min, double euclideanDistance_km, double accessEgressTime_min) { + this.travelTime_min = travelTime_min; + this.euclideanDistance_km = euclideanDistance_km; + this.accessEgressTime_min = accessEgressTime_min; + } +} diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPersonVariables.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPersonVariables.java index f3d821c52..9d668747d 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPersonVariables.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPersonVariables.java @@ -4,8 +4,10 @@ public class IDFPersonVariables implements BaseVariables { public final boolean hasSubscription; + public final boolean hasDrivingPermit; - public IDFPersonVariables(boolean hasSubscription) { + public IDFPersonVariables(boolean hasSubscription, boolean hasDrivingPermit) { this.hasSubscription = hasSubscription; + this.hasDrivingPermit = hasDrivingPermit; } } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPtVariables.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPtVariables.java new file mode 100644 index 000000000..a8e8f705e --- /dev/null +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPtVariables.java @@ -0,0 +1,13 @@ +package org.eqasim.ile_de_france.mode_choice.utilities.variables; + +import org.eqasim.core.simulation.mode_choice.utilities.variables.BaseVariables; + +public class IDFPtVariables implements BaseVariables { + public final boolean isOnlyBus; + public final boolean hasOnlySubwayAndBus; + + public IDFPtVariables(boolean isOnlyBus, boolean hasOnlySubwayAndBus) { + this.isOnlyBus = isOnlyBus; + this.hasOnlySubwayAndBus = hasOnlySubwayAndBus; + } +} diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFSpatialVariables.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFSpatialVariables.java deleted file mode 100644 index 6edc67e88..000000000 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFSpatialVariables.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.eqasim.ile_de_france.mode_choice.utilities.variables; - -import org.eqasim.core.simulation.mode_choice.utilities.variables.BaseVariables; - -public class IDFSpatialVariables implements BaseVariables { - public final boolean hasUrbanOrigin; - public final boolean hasUrbanDestination; - - public IDFSpatialVariables(boolean hasUrbanOrigin, boolean hasUrbanDestination) { - this.hasUrbanOrigin = hasUrbanOrigin; - this.hasUrbanDestination = hasUrbanDestination; - } -} diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java index 96bc9010f..42d573b33 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java @@ -27,7 +27,9 @@ static public void adaptConfiguration(Config config, String prefix) { eqasimConfig.setCostModel(TransportMode.pt, IDFModeChoiceModule.PT_COST_MODEL_NAME); eqasimConfig.setEstimator(TransportMode.car, IDFModeChoiceModule.CAR_ESTIMATOR_NAME); - eqasimConfig.setEstimator(TransportMode.bike, IDFModeChoiceModule.BIKE_ESTIMATOR_NAME); + eqasimConfig.setEstimator(IDFModeChoiceModule.BICYCLE, IDFModeChoiceModule.BICYCLE_ESTIMATOR_NAME); + eqasimConfig.setEstimator(IDFModeChoiceModule.MOTORBIKE, IDFModeChoiceModule.MOTORBIKE_ESTIMATOR_NAME); + eqasimConfig.setEstimator(IDFModeChoiceModule.PASSENGER, IDFModeChoiceModule.PASSENGER_ESTIMATOR_NAME); DiscreteModeChoiceConfigGroup dmcConfig = (DiscreteModeChoiceConfigGroup) config.getModules() .get(DiscreteModeChoiceConfigGroup.GROUP_NAME); From 748bac629d051ab48de2a76f824959c1ecb36393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Tue, 1 Oct 2024 14:53:00 +0200 Subject: [PATCH 05/37] prepare for testing --- .../spatial/ImputeSpatialAttribute.java | 22 +++++- .../spatial/RunImputeSpatialAttribute.java | 17 ++++- .../eqasim/ile_de_france/RunSimulation.java | 76 +++++++++++++++++++ .../mode_choice/IDFModeChoiceModule.java | 16 ++++ .../mode_choice/costs/IDFPtCostModel.java | 7 +- .../utilities/predictors/IDFPtPredictor.java | 26 ++++++- .../utilities/variables/IDFPtVariables.java | 4 +- .../scenario/RunAdaptConfig.java | 42 +++++++++- 8 files changed, 199 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/org/eqasim/core/scenario/spatial/ImputeSpatialAttribute.java b/core/src/main/java/org/eqasim/core/scenario/spatial/ImputeSpatialAttribute.java index 3c948a4c9..d76d34b7f 100644 --- a/core/src/main/java/org/eqasim/core/scenario/spatial/ImputeSpatialAttribute.java +++ b/core/src/main/java/org/eqasim/core/scenario/spatial/ImputeSpatialAttribute.java @@ -13,6 +13,8 @@ import org.matsim.api.core.v01.population.Population; import org.matsim.core.router.TripStructureUtils; import org.matsim.core.router.TripStructureUtils.StageActivityHandling; +import org.matsim.pt.transitSchedule.api.TransitSchedule; +import org.matsim.pt.transitSchedule.api.TransitStopFacility; public class ImputeSpatialAttribute { private final Geometry geometry; @@ -30,7 +32,8 @@ public void run(Population population) throws InterruptedException { for (Person person : population.getPersons().values()) { for (Plan plan : person.getPlans()) { - for (Activity activity : TripStructureUtils.getActivities(plan, StageActivityHandling.ExcludeStageActivities)) { + for (Activity activity : TripStructureUtils.getActivities(plan, + StageActivityHandling.ExcludeStageActivities)) { Point point = factory .createPoint(new Coordinate(activity.getCoord().getX(), activity.getCoord().getY())); @@ -62,4 +65,21 @@ public void run(Network network) throws InterruptedException { progress.close(); } + + public void run(TransitSchedule schedule) throws InterruptedException { + ParallelProgress progress = new ParallelProgress("Imputing spatial schedule attributes ...", + schedule.getFacilities().size()); + + for (TransitStopFacility facility : schedule.getFacilities().values()) { + Point point = factory.createPoint(new Coordinate(facility.getCoord().getX(), facility.getCoord().getY())); + + if (geometry.covers(point)) { + facility.getAttributes().putAttribute(attribute, true); + } + + progress.update(); + } + + progress.close(); + } } diff --git a/core/src/main/java/org/eqasim/core/scenario/spatial/RunImputeSpatialAttribute.java b/core/src/main/java/org/eqasim/core/scenario/spatial/RunImputeSpatialAttribute.java index 08bce0d8e..b0fc697b4 100644 --- a/core/src/main/java/org/eqasim/core/scenario/spatial/RunImputeSpatialAttribute.java +++ b/core/src/main/java/org/eqasim/core/scenario/spatial/RunImputeSpatialAttribute.java @@ -18,13 +18,15 @@ import org.matsim.core.population.io.PopulationReader; import org.matsim.core.population.io.PopulationWriter; import org.matsim.core.scenario.ScenarioUtils; +import org.matsim.pt.transitSchedule.api.TransitScheduleReader; +import org.matsim.pt.transitSchedule.api.TransitScheduleWriter; public class RunImputeSpatialAttribute { static public void main(String[] args) throws ConfigurationException, MalformedURLException, IOException, InterruptedException { CommandLine cmd = new CommandLine.Builder(args) // .allowOptions("input-population-path", "input-network-path", "output-population-path", - "output-network-path") // + "output-network-path", "input-schedule-path", "output-schedule-path") // .requireOptions("shape-path", "shape-attribute", "shape-value", "attribute") // .build(); @@ -36,6 +38,10 @@ static public void main(String[] args) throw new IllegalStateException("Both input and output path must be given for the network."); } + if (cmd.hasOption("input-schedule-path") ^ cmd.hasOption("output-schedule-path")) { + throw new IllegalStateException("Both input and output path must be given for the schedule."); + } + // Load shape String shapeAttribute = cmd.getOptionStrict("shape-attribute"); String shapeValue = cmd.getOptionStrict("shape-value"); @@ -68,5 +74,14 @@ static public void main(String[] args) algorithm.run(scenario.getPopulation()); new PopulationWriter(scenario.getPopulation()).write(cmd.getOptionStrict("output-population-path")); } + + // Load schedule + if (cmd.hasOption("input-schedule-path")) { + File populationPath = new File(cmd.getOptionStrict("input-schedule-path")); + new TransitScheduleReader(scenario).readFile(populationPath.toString()); + algorithm.run(scenario.getTransitSchedule()); + new TransitScheduleWriter(scenario.getTransitSchedule()) + .writeFile(cmd.getOptionStrict("output-schedule-path")); + } } } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java index 4a5ce91bd..95c288a56 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java @@ -1,16 +1,39 @@ package org.eqasim.ile_de_france; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.eqasim.core.components.config.EqasimConfigGroup; import org.eqasim.core.scenario.validation.VehiclesValidator; import org.eqasim.core.simulation.analysis.EqasimAnalysisModule; import org.eqasim.core.simulation.mode_choice.EqasimModeChoiceModule; import org.eqasim.ile_de_france.mode_choice.IDFModeChoiceModule; +import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; +import org.matsim.api.core.v01.network.Link; +import org.matsim.api.core.v01.population.Leg; +import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.Plan; +import org.matsim.contribs.discrete_mode_choice.modules.config.DiscreteModeChoiceConfigGroup; +import org.matsim.contribs.discrete_mode_choice.modules.config.VehicleTourConstraintConfigGroup; import org.matsim.core.config.CommandLine; import org.matsim.core.config.CommandLine.ConfigurationException; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; +import org.matsim.core.config.groups.RoutingConfigGroup.AccessEgressType; +import org.matsim.core.config.groups.RoutingConfigGroup.TeleportedModeParams; +import org.matsim.core.config.groups.ScoringConfigGroup.ModeParams; import org.matsim.core.controler.Controler; +import org.matsim.core.router.TripStructureUtils; import org.matsim.core.scenario.ScenarioUtils; +import org.matsim.vehicles.Vehicle; +import org.matsim.vehicles.VehicleType; +import org.matsim.vehicles.VehicleUtils; +import org.matsim.vehicles.Vehicles; +import org.matsim.vehicles.VehiclesFactory; public class RunSimulation { static public void main(String[] args) throws ConfigurationException { @@ -30,6 +53,59 @@ static public void main(String[] args) throws ConfigurationException { ScenarioUtils.loadScenario(scenario); configurator.adjustScenario(scenario); + /*-{ + // TODO: Make this static! > OK looks like everything is covered in pipeline + Vehicles vehicles = scenario.getVehicles(); + VehiclesFactory factory = vehicles.getFactory(); + + VehicleType vehicleType = vehicles.getVehicleTypes() + .get(Id.create("defaultVehicleType", VehicleType.class)); + + // ok should be done in pipeline + for (Person person : scenario.getPopulation().getPersons().values()) { + Map> personVehicles = new HashMap<>(); + + for (String mode : Arrays.asList("motorbike", "passenger")) { + Vehicle vehicle = factory.createVehicle(Id.createVehicleId(person.getId().toString() + ":" + mode), + vehicleType); + vehicles.addVehicle(vehicle); + + personVehicles.put(mode, vehicle.getId()); + } + + VehicleUtils.insertVehicleIdsIntoPersonAttributes(person, personVehicles); + } + + for (Person person : scenario.getPopulation().getPersons().values()) { + person.getAttributes().putAttribute("bicycleAvailability", + person.getAttributes().getAttribute("bikeAvailability")); // ok done in pipeline + person.getAttributes().putAttribute("motorbikeAvailability", + person.getAttributes().getAttribute("bikeAvailability")); // ok done in pipeline + + // ok mode changes in pipeline + for (Plan plan : person.getPlans()) { + for (Leg leg : TripStructureUtils.getLegs(plan)) { + if (leg.getMode().equals("bike")) { + leg.setMode("bicycle"); + TripStructureUtils.setRoutingMode(leg, "bicycle"); + } + } + } + } + + // OK done with pt2matsim + for (Link link : scenario.getNetwork().getLinks().values()) { + Set allowedModes = new HashSet<>(link.getAllowedModes()); + + if (allowedModes.contains("car")) { + allowedModes.add("passenger"); + allowedModes.add("motorbike"); + } + + link.setAllowedModes(allowedModes); + } + }*/ + Controler controller = new Controler(scenario); configurator.configureController(controller); controller.addOverridingModule(new EqasimAnalysisModule()); diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeChoiceModule.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeChoiceModule.java index c8863f1b8..4cef140a4 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeChoiceModule.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeChoiceModule.java @@ -3,10 +3,12 @@ import java.io.File; import java.io.IOException; import java.util.List; +import java.util.Map; import org.eqasim.core.components.config.EqasimConfigGroup; import org.eqasim.core.simulation.mode_choice.AbstractEqasimExtension; import org.eqasim.core.simulation.mode_choice.ParameterDefinition; +import org.eqasim.core.simulation.mode_choice.cost.CostModel; import org.eqasim.core.simulation.mode_choice.parameters.ModeParameters; import org.eqasim.core.simulation.mode_choice.tour_finder.ActivityTourFinderWithExcludedActivities; import org.eqasim.core.simulation.mode_choice.utilities.estimators.BikeUtilityEstimator; @@ -19,15 +21,20 @@ import org.eqasim.ile_de_france.mode_choice.utilities.estimators.IDFMotorbikeUtilityEstimator; import org.eqasim.ile_de_france.mode_choice.utilities.estimators.IDFPassengerUtilityEstimator; import org.eqasim.ile_de_france.mode_choice.utilities.estimators.IDFPtUtilityEstimator; +import org.eqasim.ile_de_france.mode_choice.utilities.predictors.IDFMotorbikePredictor; +import org.eqasim.ile_de_france.mode_choice.utilities.predictors.IDFPassengerPredictor; import org.eqasim.ile_de_france.mode_choice.utilities.predictors.IDFPersonPredictor; +import org.eqasim.ile_de_france.mode_choice.utilities.predictors.IDFPtPredictor; import org.matsim.contribs.discrete_mode_choice.components.tour_finder.ActivityTourFinder; import org.matsim.contribs.discrete_mode_choice.modules.config.ActivityTourFinderConfigGroup; import org.matsim.contribs.discrete_mode_choice.modules.config.DiscreteModeChoiceConfigGroup; import org.matsim.core.config.CommandLine; import org.matsim.core.config.CommandLine.ConfigurationException; +import com.google.inject.Provider; import com.google.inject.Provides; import com.google.inject.Singleton; +import com.google.inject.name.Named; public class IDFModeChoiceModule extends AbstractEqasimExtension { private final CommandLine commandLine; @@ -61,6 +68,9 @@ protected void installEqasimExtension() { bindModeAvailability(MODE_AVAILABILITY_NAME).to(IDFModeAvailability.class); bind(IDFPersonPredictor.class); + bind(IDFMotorbikePredictor.class); + bind(IDFPassengerPredictor.class); + bind(IDFPtPredictor.class); bindCostModel(CAR_COST_MODEL_NAME).to(IDFCarCostModel.class); bindCostModel(MOTORBIKE_COST_MODEL_NAME).to(IDFMotorbikeCostModel.class); @@ -112,4 +122,10 @@ public ActivityTourFinderWithExcludedActivities provideActivityTourFinderWithExc return new ActivityTourFinderWithExcludedActivities(List.of("outside"), new ActivityTourFinder(config.getActivityTypes())); } + + @Provides + @Named("motorbike") + public CostModel providePtCostModel(Map> factory, EqasimConfigGroup config) { + return getCostModel(factory, config, "motorbike"); + } } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFPtCostModel.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFPtCostModel.java index 4a5780809..8c98f0510 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFPtCostModel.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFPtCostModel.java @@ -43,13 +43,8 @@ public double calculateCost_MU(Person person, DiscreteModeChoiceTrip trip, List< // II) Special case: Within Paris or only metro and bus IDFPtVariables ptVariables = ptPredictor.predictVariables(person, trip, elements); - boolean isWithinParis = false; - if (true) { - throw new IllegalStateException("find out if this is in paris"); - } - - if (ptVariables.hasOnlySubwayAndBus || isWithinParis) { + if (ptVariables.hasOnlySubwayAndBus || ptVariables.isWithinParis) { return 1.8; } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java index 26014a3a0..2f1508fed 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java @@ -12,10 +12,13 @@ import org.matsim.pt.transitSchedule.api.TransitLine; import org.matsim.pt.transitSchedule.api.TransitRoute; import org.matsim.pt.transitSchedule.api.TransitSchedule; +import org.matsim.pt.transitSchedule.api.TransitStopFacility; import com.google.inject.Inject; public class IDFPtPredictor extends CachedVariablePredictor { + static public final String PARIS_ATTRIBUTE = "isParis"; + private final TransitSchedule schedule; @Inject @@ -29,6 +32,9 @@ public IDFPtVariables predict(Person person, DiscreteModeChoiceTrip trip, List 0 && subwayCount == 0 && otherCount == 0; boolean hasOnlySubwayAndBus = (busCount > 0 || subwayCount > 0) && otherCount == 0; - return new IDFPtVariables(isOnlyBus, hasOnlySubwayAndBus); + boolean isWithinParis = false; + + if (firstRoute != null) { + TransitStopFacility startFacility = schedule.getFacilities().get(firstRoute.getAccessStopId()); + TransitStopFacility endFacility = schedule.getFacilities().get(lastRoute.getEgressStopId()); + + Boolean startParis = (Boolean) startFacility.getAttributes().getAttribute(PARIS_ATTRIBUTE); + Boolean endParis = (Boolean) endFacility.getAttributes().getAttribute(PARIS_ATTRIBUTE); + + isWithinParis = startParis != null && endParis != null && startParis && endParis; + } + + return new IDFPtVariables(isOnlyBus, hasOnlySubwayAndBus, isWithinParis); } } \ No newline at end of file diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPtVariables.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPtVariables.java index a8e8f705e..461f1de3e 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPtVariables.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPtVariables.java @@ -5,9 +5,11 @@ public class IDFPtVariables implements BaseVariables { public final boolean isOnlyBus; public final boolean hasOnlySubwayAndBus; + public final boolean isWithinParis; - public IDFPtVariables(boolean isOnlyBus, boolean hasOnlySubwayAndBus) { + public IDFPtVariables(boolean isOnlyBus, boolean hasOnlySubwayAndBus, boolean isWithinParis) { this.isOnlyBus = isOnlyBus; this.hasOnlySubwayAndBus = hasOnlySubwayAndBus; + this.isWithinParis = isWithinParis; } } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java index 42d573b33..a37e2c5f8 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java @@ -1,16 +1,25 @@ package org.eqasim.ile_de_france.scenario; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + import org.eqasim.core.components.config.ConfigAdapter; import org.eqasim.core.components.config.EqasimConfigGroup; +import org.eqasim.core.simulation.mode_choice.EqasimModeChoiceModule; import org.eqasim.core.simulation.mode_choice.epsilon.AdaptConfigForEpsilon; import org.eqasim.ile_de_france.IDFConfigurator; import org.eqasim.ile_de_france.mode_choice.IDFModeChoiceModule; import org.matsim.api.core.v01.TransportMode; import org.matsim.contribs.discrete_mode_choice.modules.config.DiscreteModeChoiceConfigGroup; +import org.matsim.contribs.discrete_mode_choice.modules.config.VehicleTourConstraintConfigGroup; import org.matsim.core.config.CommandLine.ConfigurationException; import org.matsim.core.config.Config; import org.matsim.core.config.groups.QSimConfigGroup; import org.matsim.core.config.groups.QSimConfigGroup.VehiclesSource; +import org.matsim.core.config.groups.RoutingConfigGroup.AccessEgressType; +import org.matsim.core.config.groups.RoutingConfigGroup.TeleportedModeParams; +import org.matsim.core.config.groups.ScoringConfigGroup.ModeParams; import org.matsim.core.config.groups.VehiclesConfigGroup; public class RunAdaptConfig { @@ -20,22 +29,53 @@ static public void main(String[] args) throws ConfigurationException { } static public void adaptConfiguration(Config config, String prefix) { + // MATSim: routing + config.routing().setAccessEgressType(AccessEgressType.accessEgressModeToLink); + + Set networkModes = new HashSet<>(config.routing().getNetworkModes()); + networkModes.add("passenger"); + networkModes.add("motorbike"); + config.routing().setNetworkModes(networkModes); + + // MATSim: scoring + TeleportedModeParams bicycleRouteParams = new TeleportedModeParams(); + bicycleRouteParams.setMode("bicycle"); + bicycleRouteParams.setTeleportedModeSpeed(15.0 / 3.6); + bicycleRouteParams.setBeelineDistanceFactor(1.3); + config.routing().addTeleportedModeParams(bicycleRouteParams); + + for (String mode : Arrays.asList("motorbike", "bicycle", "passenger")) { + ModeParams modeScoringParams = new ModeParams(mode); + modeScoringParams.setMarginalUtilityOfTraveling(-1.0); + config.scoring().addModeParams(modeScoringParams); + } + // Adjust eqasim config EqasimConfigGroup eqasimConfig = EqasimConfigGroup.get(config); eqasimConfig.setCostModel(TransportMode.car, IDFModeChoiceModule.CAR_COST_MODEL_NAME); eqasimConfig.setCostModel(TransportMode.pt, IDFModeChoiceModule.PT_COST_MODEL_NAME); + eqasimConfig.setCostModel(IDFModeChoiceModule.MOTORBIKE, IDFModeChoiceModule.MOTORBIKE_COST_MODEL_NAME); eqasimConfig.setEstimator(TransportMode.car, IDFModeChoiceModule.CAR_ESTIMATOR_NAME); eqasimConfig.setEstimator(IDFModeChoiceModule.BICYCLE, IDFModeChoiceModule.BICYCLE_ESTIMATOR_NAME); eqasimConfig.setEstimator(IDFModeChoiceModule.MOTORBIKE, IDFModeChoiceModule.MOTORBIKE_ESTIMATOR_NAME); eqasimConfig.setEstimator(IDFModeChoiceModule.PASSENGER, IDFModeChoiceModule.PASSENGER_ESTIMATOR_NAME); - + eqasimConfig.removeEstimator(TransportMode.bike); + + // Discrete mode choice DiscreteModeChoiceConfigGroup dmcConfig = (DiscreteModeChoiceConfigGroup) config.getModules() .get(DiscreteModeChoiceConfigGroup.GROUP_NAME); dmcConfig.setModeAvailability(IDFModeChoiceModule.MODE_AVAILABILITY_NAME); + Set tripConstraints = new HashSet<>(dmcConfig.getTripConstraints()); + tripConstraints.remove(EqasimModeChoiceModule.PASSENGER_CONSTRAINT_NAME); + dmcConfig.setTripConstraints(tripConstraints); + + VehicleTourConstraintConfigGroup vehicleTourConstraint = dmcConfig.getVehicleTourConstraintConfig(); + vehicleTourConstraint.setRestrictedModes(Arrays.asList("car", "bicycle", "motorbike")); + // Major crossing penalty from calibration eqasimConfig.setCrossingPenalty(4.2); From 757ea13fdcb528631ca7e42efa7d0b2a63a0aec8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Tue, 1 Oct 2024 15:43:51 +0200 Subject: [PATCH 06/37] add fix for population routing --- .../core/scenario/routing/RunPopulationRouting.java | 6 +++++- .../test/java/org/eqasim/TestSimulationPipeline.java | 12 ++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/eqasim/core/scenario/routing/RunPopulationRouting.java b/core/src/main/java/org/eqasim/core/scenario/routing/RunPopulationRouting.java index f0c7b7f2e..2607b1ad7 100644 --- a/core/src/main/java/org/eqasim/core/scenario/routing/RunPopulationRouting.java +++ b/core/src/main/java/org/eqasim/core/scenario/routing/RunPopulationRouting.java @@ -9,8 +9,10 @@ import org.eqasim.core.simulation.mode_choice.AbstractEqasimExtension; import org.eqasim.core.simulation.termination.EqasimTerminationConfigGroup; import org.matsim.api.core.v01.Scenario; +import org.matsim.contribs.discrete_mode_choice.modules.DiscreteModeChoiceModule; import org.matsim.core.config.CommandLine; import org.matsim.core.config.CommandLine.ConfigurationException; +import org.matsim.core.controler.AbstractModule; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.population.io.PopulationWriter; @@ -59,7 +61,9 @@ static public void main(String[] args) throws ConfigurationException, Interrupte Injector injector = new InjectorBuilder(scenario) // .addOverridingModules(configurator.getModules().stream() - .filter(module -> !(module instanceof AbstractEqasimExtension)).toList()) // + .filter(module -> !(module instanceof AbstractEqasimExtension)) // + .filter(module -> !(module instanceof DiscreteModeChoiceModule)) // + .toList()) // .addOverridingModule(new PopulationRouterModule(numberOfThreads, batchSize, true, modes)) // .addOverridingModule(new TimeInterpretationModule()).build(); diff --git a/core/src/test/java/org/eqasim/TestSimulationPipeline.java b/core/src/test/java/org/eqasim/TestSimulationPipeline.java index c9e417f01..11856461a 100644 --- a/core/src/test/java/org/eqasim/TestSimulationPipeline.java +++ b/core/src/test/java/org/eqasim/TestSimulationPipeline.java @@ -15,6 +15,7 @@ import org.eqasim.core.analysis.run.RunTripAnalysis; import org.eqasim.core.scenario.cutter.RunScenarioCutter; import org.eqasim.core.scenario.cutter.RunScenarioCutterV2; +import org.eqasim.core.scenario.routing.RunPopulationRouting; import org.eqasim.core.simulation.EqasimConfigurator; import org.eqasim.core.simulation.analysis.EqasimAnalysisModule; import org.eqasim.core.simulation.mode_choice.AbstractEqasimExtension; @@ -407,6 +408,7 @@ public void runVdf() throws CommandLine.ConfigurationException, IOException, Int @Test public void testPipeline() throws Exception { runMelunSimulation("melun_test/input/config.xml", "melun_test/output"); + runPopulationRouting(); runStandaloneModeChoice(); runVdf(); runAnalyses(); @@ -414,8 +416,14 @@ public void testPipeline() throws Exception { runCutter(); runCutterV2(); } - - + + public void runPopulationRouting() throws CommandLine.ConfigurationException, IOException, InterruptedException { + RunPopulationRouting.main(new String[] { + "--config-path", "melun_test/input/config.xml", + "--output-path", "melun_test/output/routed_population.xml.gz" + }); + } + public void runStandaloneModeChoice() throws CommandLine.ConfigurationException, IOException, InterruptedException { RunStandaloneModeChoice.main(new String[] { "--config-path", "melun_test/input/config.xml", From 047bb4fcf28c8c2fbad84949316c5b8bfae3e66e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Wed, 2 Oct 2024 21:56:44 +0200 Subject: [PATCH 07/37] add modes for convergence --- .../org/eqasim/ile_de_france/scenario/RunAdaptConfig.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java index a37e2c5f8..8cc060ff4 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java @@ -8,6 +8,7 @@ import org.eqasim.core.components.config.EqasimConfigGroup; import org.eqasim.core.simulation.mode_choice.EqasimModeChoiceModule; import org.eqasim.core.simulation.mode_choice.epsilon.AdaptConfigForEpsilon; +import org.eqasim.core.simulation.termination.EqasimTerminationConfigGroup; import org.eqasim.ile_de_france.IDFConfigurator; import org.eqasim.ile_de_france.mode_choice.IDFModeChoiceModule; import org.matsim.api.core.v01.TransportMode; @@ -88,5 +89,9 @@ static public void adaptConfiguration(Config config, String prefix) { VehiclesConfigGroup vehiclesConfig = config.vehicles(); vehiclesConfig.setVehiclesFile(prefix + "vehicles.xml.gz"); + + // Convergence + EqasimTerminationConfigGroup terminationConfig = EqasimTerminationConfigGroup.getOrCreate(config); + terminationConfig.setModes(Arrays.asList("car", "passenger", "motorbike", "pt", "bicycle", "walk")); } } From 1ef466df88a0697db632f1597a94b34f87ca2072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Thu, 3 Oct 2024 16:04:32 +0200 Subject: [PATCH 08/37] revert integration of motorbikes for no --- .../mode_choice/IDFModeAvailability.java | 5 -- .../mode_choice/IDFModeChoiceModule.java | 13 +---- .../costs/IDFMotorbikeCostModel.java | 27 --------- .../parameters/IDFModeParameters.java | 23 ++------ .../IDFMotorbikeUtilityEstimator.java | 56 ------------------- .../predictors/IDFMotorbikePredictor.java | 53 ------------------ .../predictors/IDFPredictorUtils.java | 4 -- .../scenario/RunAdaptConfig.java | 26 ++++----- 8 files changed, 19 insertions(+), 188 deletions(-) delete mode 100644 ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFMotorbikeCostModel.java delete mode 100644 ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFMotorbikeUtilityEstimator.java delete mode 100644 ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFMotorbikePredictor.java diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeAvailability.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeAvailability.java index cf77d84a1..9a3a9bf71 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeAvailability.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeAvailability.java @@ -25,11 +25,6 @@ public Collection getAvailableModes(Person person, List> factory, EqasimConfigGroup config) { diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFMotorbikeCostModel.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFMotorbikeCostModel.java deleted file mode 100644 index 2fcea5fff..000000000 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFMotorbikeCostModel.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.eqasim.ile_de_france.mode_choice.costs; - -import java.util.List; - -import org.eqasim.core.simulation.mode_choice.cost.AbstractCostModel; -import org.eqasim.ile_de_france.mode_choice.IDFModeChoiceModule; -import org.eqasim.ile_de_france.mode_choice.parameters.IDFCostParameters; -import org.matsim.api.core.v01.population.Person; -import org.matsim.api.core.v01.population.PlanElement; -import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; - -import com.google.inject.Inject; - -public class IDFMotorbikeCostModel extends AbstractCostModel { - private final IDFCostParameters costParameters; - - @Inject - public IDFMotorbikeCostModel(IDFCostParameters costParameters) { - super(IDFModeChoiceModule.MOTORBIKE); - this.costParameters = costParameters; - } - - @Override - public double calculateCost_MU(Person person, DiscreteModeChoiceTrip trip, List elements) { - return costParameters.motorbikeCost_EUR_km * getInVehicleDistance_km(elements); - } -} diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFModeParameters.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFModeParameters.java index fbab01232..714920e0c 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFModeParameters.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFModeParameters.java @@ -8,7 +8,7 @@ public class IDFCarParameters { } public final IDFCarParameters idfCar = new IDFCarParameters(); - + public class IDFPassengerParameters { public double alpha_u; public double betaInVehicleTravelTime_u_min; @@ -17,20 +17,13 @@ public class IDFPassengerParameters { public final IDFPassengerParameters idfPassenger = new IDFPassengerParameters(); - public class IDFMotorbikeParameters { - public double alpha_u; - public double betaInVehicleTravelTime_u_min; - } - - public final IDFMotorbikeParameters idfMotorbike = new IDFMotorbikeParameters(); - public class IDFPtParameters { public double betaDrivingPermit_u; public double onlyBus_u; } public final IDFPtParameters idfPt = new IDFPtParameters(); - + public double betaAccessTime_u_min; public static IDFModeParameters buildDefault() { @@ -38,7 +31,7 @@ public static IDFModeParameters buildDefault() { // Access parameters.betaAccessTime_u_min = -0.0313; - + // Cost parameters.betaCost_u_MU = -0.474; parameters.lambdaCostEuclideanDistance = -0.274; @@ -47,18 +40,14 @@ public static IDFModeParameters buildDefault() { // Car parameters.car.alpha_u = -0.662; parameters.car.betaTravelTime_u_min = -0.0262; - + parameters.idfCar.betaInVehicleTravelTime_u_min = -0.0262; - + // Car passenger parameters.idfPassenger.alpha_u = -2.08; parameters.idfPassenger.betaDrivingPermit_u = -1.17; parameters.idfPassenger.betaInVehicleTravelTime_u_min = -0.0608; - // Motorbike - parameters.idfMotorbike.alpha_u = -2.2; - parameters.idfMotorbike.betaInVehicleTravelTime_u_min = -0.0321; - // PT parameters.pt.alpha_u = 0.0; parameters.pt.betaLineSwitch_u = -0.452; @@ -68,7 +57,7 @@ public static IDFModeParameters buildDefault() { parameters.idfPt.betaDrivingPermit_u = -0.712; parameters.idfPt.onlyBus_u = -1.42; - + // Bike parameters.bike.alpha_u = -3.42; parameters.bike.betaTravelTime_u_min = -0.0824; diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFMotorbikeUtilityEstimator.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFMotorbikeUtilityEstimator.java deleted file mode 100644 index 38f1942c6..000000000 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFMotorbikeUtilityEstimator.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.eqasim.ile_de_france.mode_choice.utilities.estimators; - -import java.util.List; - -import org.eqasim.core.simulation.mode_choice.utilities.UtilityEstimator; -import org.eqasim.core.simulation.mode_choice.utilities.estimators.EstimatorUtils; -import org.eqasim.ile_de_france.mode_choice.parameters.IDFModeParameters; -import org.eqasim.ile_de_france.mode_choice.utilities.predictors.IDFMotorbikePredictor; -import org.eqasim.ile_de_france.mode_choice.utilities.variables.IDFMotorbikeVariables; -import org.matsim.api.core.v01.population.Person; -import org.matsim.api.core.v01.population.PlanElement; -import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; - -import com.google.inject.Inject; - -public class IDFMotorbikeUtilityEstimator implements UtilityEstimator { - private final IDFModeParameters parameters; - private final IDFMotorbikePredictor predictor; - - @Inject - public IDFMotorbikeUtilityEstimator(IDFModeParameters parameters, IDFMotorbikePredictor predictor) { - this.parameters = parameters; - this.predictor = predictor; - } - - protected double estimateConstantUtility() { - return parameters.idfMotorbike.alpha_u; - } - - protected double estimateTravelTimeUtility(IDFMotorbikeVariables variables) { - return parameters.idfMotorbike.betaInVehicleTravelTime_u_min * variables.travelTime_min; - } - - protected double estimateAccessEgressTimeUtility(IDFMotorbikeVariables variables) { - return parameters.betaAccessTime_u_min * variables.accessEgressTime_min; - } - - protected double estimateMonetaryCostUtility(IDFMotorbikeVariables variables) { - return parameters.betaCost_u_MU * EstimatorUtils.interaction(variables.euclideanDistance_km, - parameters.referenceEuclideanDistance_km, parameters.lambdaCostEuclideanDistance) * variables.cost_MU; - } - - @Override - public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List elements) { - IDFMotorbikeVariables variables = predictor.predictVariables(person, trip, elements); - - double utility = 0.0; - - utility += estimateConstantUtility(); - utility += estimateTravelTimeUtility(variables); - utility += estimateAccessEgressTimeUtility(variables); - utility += estimateMonetaryCostUtility(variables); - - return utility; - } -} \ No newline at end of file diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFMotorbikePredictor.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFMotorbikePredictor.java deleted file mode 100644 index 43cf46fe8..000000000 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFMotorbikePredictor.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.eqasim.ile_de_france.mode_choice.utilities.predictors; - -import java.util.List; - -import org.eqasim.core.simulation.mode_choice.cost.CostModel; -import org.eqasim.core.simulation.mode_choice.utilities.predictors.CachedVariablePredictor; -import org.eqasim.core.simulation.mode_choice.utilities.predictors.PredictorUtils; -import org.eqasim.ile_de_france.mode_choice.IDFModeChoiceModule; -import org.eqasim.ile_de_france.mode_choice.utilities.variables.IDFMotorbikeVariables; -import org.matsim.api.core.v01.TransportMode; -import org.matsim.api.core.v01.population.Leg; -import org.matsim.api.core.v01.population.Person; -import org.matsim.api.core.v01.population.PlanElement; -import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; -import org.matsim.core.router.TripStructureUtils; - -import com.google.common.base.Verify; -import com.google.inject.Inject; -import com.google.inject.name.Named; - -public class IDFMotorbikePredictor extends CachedVariablePredictor { - private final CostModel costModel; - - @Inject - public IDFMotorbikePredictor(@Named(IDFModeChoiceModule.MOTORBIKE) CostModel costModel) { - this.costModel = costModel; - } - - @Override - public IDFMotorbikeVariables predict(Person person, DiscreteModeChoiceTrip trip, - List elements) { - double motorbikeTravelTime_min = 0.0; - double accessEgressTime_min = 0.0; - - boolean foundCar = false; - - for (Leg leg : TripStructureUtils.getLegs(elements)) { - if (leg.getMode().equals(IDFModeChoiceModule.MOTORBIKE)) { - Verify.verify(!foundCar); - motorbikeTravelTime_min += leg.getTravelTime().seconds() / 60.0; - } else if (leg.getMode().equals(TransportMode.walk)) { - accessEgressTime_min += leg.getTravelTime().seconds() / 60.0; - } else { - throw new IllegalStateException("Unexpected mode in motorbike chain: " + leg.getMode()); - } - } - - double cost_MU = costModel.calculateCost_MU(person, trip, elements); - double euclideanDistance_km = PredictorUtils.calculateEuclideanDistance_km(trip); - - return new IDFMotorbikeVariables(motorbikeTravelTime_min, cost_MU, euclideanDistance_km, accessEgressTime_min); - } -} \ No newline at end of file diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPredictorUtils.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPredictorUtils.java index b49d88e00..d8169e0ac 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPredictorUtils.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPredictorUtils.java @@ -25,8 +25,4 @@ static public boolean hasCarAvailability(Person person) { static public boolean hasBicycleAvailability(Person person) { return !"none".equals((String) person.getAttributes().getAttribute("bicycleAvailability")); } - - static public boolean hasMotorbikeAvailability(Person person) { - return !"none".equals((String) person.getAttributes().getAttribute("motorbikeAvailability")); - } } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java index 8cc060ff4..f3d8beea3 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java @@ -32,64 +32,62 @@ static public void main(String[] args) throws ConfigurationException { static public void adaptConfiguration(Config config, String prefix) { // MATSim: routing config.routing().setAccessEgressType(AccessEgressType.accessEgressModeToLink); - + Set networkModes = new HashSet<>(config.routing().getNetworkModes()); networkModes.add("passenger"); networkModes.add("motorbike"); config.routing().setNetworkModes(networkModes); - + // MATSim: scoring TeleportedModeParams bicycleRouteParams = new TeleportedModeParams(); bicycleRouteParams.setMode("bicycle"); bicycleRouteParams.setTeleportedModeSpeed(15.0 / 3.6); bicycleRouteParams.setBeelineDistanceFactor(1.3); config.routing().addTeleportedModeParams(bicycleRouteParams); - + for (String mode : Arrays.asList("motorbike", "bicycle", "passenger")) { ModeParams modeScoringParams = new ModeParams(mode); modeScoringParams.setMarginalUtilityOfTraveling(-1.0); config.scoring().addModeParams(modeScoringParams); } - + // Adjust eqasim config EqasimConfigGroup eqasimConfig = EqasimConfigGroup.get(config); eqasimConfig.setCostModel(TransportMode.car, IDFModeChoiceModule.CAR_COST_MODEL_NAME); eqasimConfig.setCostModel(TransportMode.pt, IDFModeChoiceModule.PT_COST_MODEL_NAME); - eqasimConfig.setCostModel(IDFModeChoiceModule.MOTORBIKE, IDFModeChoiceModule.MOTORBIKE_COST_MODEL_NAME); eqasimConfig.setEstimator(TransportMode.car, IDFModeChoiceModule.CAR_ESTIMATOR_NAME); eqasimConfig.setEstimator(IDFModeChoiceModule.BICYCLE, IDFModeChoiceModule.BICYCLE_ESTIMATOR_NAME); - eqasimConfig.setEstimator(IDFModeChoiceModule.MOTORBIKE, IDFModeChoiceModule.MOTORBIKE_ESTIMATOR_NAME); eqasimConfig.setEstimator(IDFModeChoiceModule.PASSENGER, IDFModeChoiceModule.PASSENGER_ESTIMATOR_NAME); eqasimConfig.removeEstimator(TransportMode.bike); - + // Discrete mode choice DiscreteModeChoiceConfigGroup dmcConfig = (DiscreteModeChoiceConfigGroup) config.getModules() .get(DiscreteModeChoiceConfigGroup.GROUP_NAME); dmcConfig.setModeAvailability(IDFModeChoiceModule.MODE_AVAILABILITY_NAME); - + Set tripConstraints = new HashSet<>(dmcConfig.getTripConstraints()); tripConstraints.remove(EqasimModeChoiceModule.PASSENGER_CONSTRAINT_NAME); dmcConfig.setTripConstraints(tripConstraints); - + VehicleTourConstraintConfigGroup vehicleTourConstraint = dmcConfig.getVehicleTourConstraintConfig(); vehicleTourConstraint.setRestrictedModes(Arrays.asList("car", "bicycle", "motorbike")); - + // Major crossing penalty from calibration eqasimConfig.setCrossingPenalty(4.2); - + // Epsilon AdaptConfigForEpsilon.run(config); - + // Vehicles QSimConfigGroup qsimConfig = config.qsim(); qsimConfig.setVehiclesSource(VehiclesSource.fromVehiclesData); - + VehiclesConfigGroup vehiclesConfig = config.vehicles(); vehiclesConfig.setVehiclesFile(prefix + "vehicles.xml.gz"); - + // Convergence EqasimTerminationConfigGroup terminationConfig = EqasimTerminationConfigGroup.getOrCreate(config); terminationConfig.setModes(Arrays.asList("car", "passenger", "motorbike", "pt", "bicycle", "walk")); From 0c8e28841c9464d1e399704e553320ac7431c1c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Thu, 3 Oct 2024 16:09:13 +0200 Subject: [PATCH 09/37] further cleanup --- .../eqasim/ile_de_france/RunSimulation.java | 5 +---- .../mode_choice/IDFModeChoiceModule.java | 6 ------ .../ile_de_france/mode_choice/SynpopTODO.java | 9 --------- .../parameters/IDFCostParameters.java | 2 -- .../variables/IDFMotorbikeVariables.java | 18 ------------------ .../ile_de_france/scenario/RunAdaptConfig.java | 7 +++---- 6 files changed, 4 insertions(+), 43 deletions(-) delete mode 100644 ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/SynpopTODO.java delete mode 100644 ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFMotorbikeVariables.java diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java index 95c288a56..19c6d0cdb 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java @@ -65,7 +65,7 @@ static public void main(String[] args) throws ConfigurationException { for (Person person : scenario.getPopulation().getPersons().values()) { Map> personVehicles = new HashMap<>(); - for (String mode : Arrays.asList("motorbike", "passenger")) { + for (String mode : Arrays.asList("passenger")) { Vehicle vehicle = factory.createVehicle(Id.createVehicleId(person.getId().toString() + ":" + mode), vehicleType); vehicles.addVehicle(vehicle); @@ -79,8 +79,6 @@ static public void main(String[] args) throws ConfigurationException { for (Person person : scenario.getPopulation().getPersons().values()) { person.getAttributes().putAttribute("bicycleAvailability", person.getAttributes().getAttribute("bikeAvailability")); // ok done in pipeline - person.getAttributes().putAttribute("motorbikeAvailability", - person.getAttributes().getAttribute("bikeAvailability")); // ok done in pipeline // ok mode changes in pipeline for (Plan plan : person.getPlans()) { @@ -99,7 +97,6 @@ static public void main(String[] args) throws ConfigurationException { if (allowedModes.contains("car")) { allowedModes.add("passenger"); - allowedModes.add("motorbike"); } link.setAllowedModes(allowedModes); diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeChoiceModule.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeChoiceModule.java index 9466443d5..65d6bd0d5 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeChoiceModule.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeChoiceModule.java @@ -111,10 +111,4 @@ public ActivityTourFinderWithExcludedActivities provideActivityTourFinderWithExc return new ActivityTourFinderWithExcludedActivities(List.of("outside"), new ActivityTourFinder(config.getActivityTypes())); } - - @Provides - @Named("motorbike") - public CostModel providePtCostModel(Map> factory, EqasimConfigGroup config) { - return getCostModel(factory, config, "motorbike"); - } } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/SynpopTODO.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/SynpopTODO.java deleted file mode 100644 index e9162ac47..000000000 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/SynpopTODO.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.eqasim.ile_de_france.mode_choice; - -public class SynpopTODO { - /*- - * - bicycleAvailability - * - motorbikeAvailability - * - attribute to indicate paris for stops / activities - */ -} diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFCostParameters.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFCostParameters.java index bdf6b5e1a..098ecb189 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFCostParameters.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFCostParameters.java @@ -4,13 +4,11 @@ public class IDFCostParameters implements ParameterDefinition { public double carCost_EUR_km = 0.0; - public double motorbikeCost_EUR_km = 0.0; public static IDFCostParameters buildDefault() { IDFCostParameters parameters = new IDFCostParameters(); parameters.carCost_EUR_km = 0.2; - parameters.motorbikeCost_EUR_km = 0.1; return parameters; } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFMotorbikeVariables.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFMotorbikeVariables.java deleted file mode 100644 index 31065c9ad..000000000 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFMotorbikeVariables.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.eqasim.ile_de_france.mode_choice.utilities.variables; - -import org.eqasim.core.simulation.mode_choice.utilities.variables.BaseVariables; - -public class IDFMotorbikeVariables implements BaseVariables { - final public double travelTime_min; - final public double cost_MU; - final public double euclideanDistance_km; - final public double accessEgressTime_min; - - public IDFMotorbikeVariables(double travelTime_min, double cost_MU, double euclideanDistance_km, - double accessEgressTime_min) { - this.travelTime_min = travelTime_min; - this.cost_MU = cost_MU; - this.euclideanDistance_km = euclideanDistance_km; - this.accessEgressTime_min = accessEgressTime_min; - } -} diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java index f3d8beea3..03917f9fc 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java @@ -35,7 +35,6 @@ static public void adaptConfiguration(Config config, String prefix) { Set networkModes = new HashSet<>(config.routing().getNetworkModes()); networkModes.add("passenger"); - networkModes.add("motorbike"); config.routing().setNetworkModes(networkModes); // MATSim: scoring @@ -45,7 +44,7 @@ static public void adaptConfiguration(Config config, String prefix) { bicycleRouteParams.setBeelineDistanceFactor(1.3); config.routing().addTeleportedModeParams(bicycleRouteParams); - for (String mode : Arrays.asList("motorbike", "bicycle", "passenger")) { + for (String mode : Arrays.asList("bicycle", "passenger")) { ModeParams modeScoringParams = new ModeParams(mode); modeScoringParams.setMarginalUtilityOfTraveling(-1.0); config.scoring().addModeParams(modeScoringParams); @@ -73,7 +72,7 @@ static public void adaptConfiguration(Config config, String prefix) { dmcConfig.setTripConstraints(tripConstraints); VehicleTourConstraintConfigGroup vehicleTourConstraint = dmcConfig.getVehicleTourConstraintConfig(); - vehicleTourConstraint.setRestrictedModes(Arrays.asList("car", "bicycle", "motorbike")); + vehicleTourConstraint.setRestrictedModes(Arrays.asList("car", "bicycle")); // Major crossing penalty from calibration eqasimConfig.setCrossingPenalty(4.2); @@ -90,6 +89,6 @@ static public void adaptConfiguration(Config config, String prefix) { // Convergence EqasimTerminationConfigGroup terminationConfig = EqasimTerminationConfigGroup.getOrCreate(config); - terminationConfig.setModes(Arrays.asList("car", "passenger", "motorbike", "pt", "bicycle", "walk")); + terminationConfig.setModes(Arrays.asList("car", "passenger", "pt", "bicycle", "walk")); } } From 9f95c51d6448fbbcde9a6669778d4d484859e860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Thu, 3 Oct 2024 16:26:17 +0200 Subject: [PATCH 10/37] fix --- .../java/org/eqasim/core/simulation/EqasimConfigurator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java b/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java index 00c4d233e..96402b2a3 100644 --- a/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java +++ b/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java @@ -70,7 +70,8 @@ public EqasimConfigurator() { new SwissRailRaptorConfigGroup(), // new EqasimConfigGroup(), // new DiscreteModeChoiceConfigGroup(), // - new EqasimRaptorConfigGroup() // + new EqasimRaptorConfigGroup(), // + new EqasimTerminationConfigGroup() )); modules.addAll(Arrays.asList( // From c1937f3da5292349352d57043b1c589855d611d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Thu, 3 Oct 2024 16:39:45 +0200 Subject: [PATCH 11/37] config --- .../java/org/eqasim/core/simulation/EqasimConfigurator.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java b/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java index 96402b2a3..00c4d233e 100644 --- a/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java +++ b/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java @@ -70,8 +70,7 @@ public EqasimConfigurator() { new SwissRailRaptorConfigGroup(), // new EqasimConfigGroup(), // new DiscreteModeChoiceConfigGroup(), // - new EqasimRaptorConfigGroup(), // - new EqasimTerminationConfigGroup() + new EqasimRaptorConfigGroup() // )); modules.addAll(Arrays.asList( // From 4d7f4c709efdb170fb8a14f0264a1d92a322df8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Thu, 3 Oct 2024 16:43:20 +0200 Subject: [PATCH 12/37] config --- .../java/org/eqasim/core/simulation/EqasimConfigurator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java b/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java index 00c4d233e..72a69cecd 100644 --- a/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java +++ b/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java @@ -70,7 +70,8 @@ public EqasimConfigurator() { new SwissRailRaptorConfigGroup(), // new EqasimConfigGroup(), // new DiscreteModeChoiceConfigGroup(), // - new EqasimRaptorConfigGroup() // + new EqasimRaptorConfigGroup(), // + new EqasimTerminationConfigGroup() // )); modules.addAll(Arrays.asList( // From 0938b218257a83dfd42e9d9e119239b1a8116654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Thu, 3 Oct 2024 16:59:40 +0200 Subject: [PATCH 13/37] reconfigure termination --- .../org/eqasim/core/simulation/EqasimConfigurator.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java b/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java index 72a69cecd..c27c228c2 100644 --- a/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java +++ b/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java @@ -71,7 +71,7 @@ public EqasimConfigurator() { new EqasimConfigGroup(), // new DiscreteModeChoiceConfigGroup(), // new EqasimRaptorConfigGroup(), // - new EqasimTerminationConfigGroup() // + new EqasimTerminationConfigGroup() // )); modules.addAll(Arrays.asList( // @@ -82,7 +82,9 @@ public EqasimConfigurator() { new EpsilonModule(), // new EqasimRaptorModule(), new EqasimModeChoiceModule(), // - new EqasimTrafficModule() // + new EqasimTrafficModule(), // + new EqasimTerminationModule(), // + new ModeShareModule() // )); qsimModules.addAll(Arrays.asList( // @@ -97,7 +99,6 @@ public EqasimConfigurator() { DvrpQSimComponents.activateAllModes((MultiModal) controller.getConfig().getModules().get(MultiModeDrtConfigGroup.GROUP_NAME)).configure(components))); this.registerOptionalConfigGroup(new DvrpConfigGroup(), Collections.singleton(new DvrpModule())); - this.registerOptionalConfigGroup(new EqasimTerminationConfigGroup(), List.of(new EqasimTerminationModule(), new ModeShareModule())); this.registerOptionalConfigGroup(new MultiModeFeederDrtConfigGroup(), List.of(new MultiModeFeederDrtModule(), new EqasimFeederDrtModeChoiceModule())); this.registerOptionalConfigGroup( new TransitWithAbstractAbstractAccessModuleConfigGroup(), From 9d5623fd4f0773a7397057d60f460c3e332d7362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Thu, 3 Oct 2024 17:06:03 +0200 Subject: [PATCH 14/37] revert termination configuration --- .../org/eqasim/core/simulation/EqasimConfigurator.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java b/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java index c27c228c2..a46a7590e 100644 --- a/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java +++ b/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java @@ -70,8 +70,7 @@ public EqasimConfigurator() { new SwissRailRaptorConfigGroup(), // new EqasimConfigGroup(), // new DiscreteModeChoiceConfigGroup(), // - new EqasimRaptorConfigGroup(), // - new EqasimTerminationConfigGroup() // + new EqasimRaptorConfigGroup() // )); modules.addAll(Arrays.asList( // @@ -81,10 +80,7 @@ public EqasimConfigurator() { new EqasimComponentsModule(), // new EpsilonModule(), // new EqasimRaptorModule(), - new EqasimModeChoiceModule(), // - new EqasimTrafficModule(), // - new EqasimTerminationModule(), // - new ModeShareModule() // + new EqasimModeChoiceModule() // )); qsimModules.addAll(Arrays.asList( // @@ -99,6 +95,7 @@ public EqasimConfigurator() { DvrpQSimComponents.activateAllModes((MultiModal) controller.getConfig().getModules().get(MultiModeDrtConfigGroup.GROUP_NAME)).configure(components))); this.registerOptionalConfigGroup(new DvrpConfigGroup(), Collections.singleton(new DvrpModule())); + this.registerOptionalConfigGroup(new EqasimTerminationConfigGroup(), List.of(new EqasimTerminationModule(), new ModeShareModule())); this.registerOptionalConfigGroup(new MultiModeFeederDrtConfigGroup(), List.of(new MultiModeFeederDrtModule(), new EqasimFeederDrtModeChoiceModule())); this.registerOptionalConfigGroup( new TransitWithAbstractAbstractAccessModuleConfigGroup(), From 18b39257492e00894449c5b19b748d8f7fa598a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Thu, 3 Oct 2024 17:11:49 +0200 Subject: [PATCH 15/37] rename passenger -> car_passenger --- .../mode_choice/IDFModeAvailability.java | 2 +- .../mode_choice/IDFModeChoiceModule.java | 16 ++++++--------- .../parameters/IDFModeParameters.java | 10 +++++----- ...a => IDFCarPassengerUtilityEstimator.java} | 20 +++++++++---------- ...tor.java => IDFCarPassengerPredictor.java} | 10 +++++----- ...les.java => IDFCarPassengerVariables.java} | 4 ++-- .../scenario/RunAdaptConfig.java | 4 ++-- 7 files changed, 31 insertions(+), 35 deletions(-) rename ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/{IDFPassengerUtilityEstimator.java => IDFCarPassengerUtilityEstimator.java} (62%) rename ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/{IDFPassengerPredictor.java => IDFCarPassengerPredictor.java} (78%) rename ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/{IDFPassengerVariables.java => IDFCarPassengerVariables.java} (69%) diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeAvailability.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeAvailability.java index 9a3a9bf71..1b1c9d451 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeAvailability.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeAvailability.java @@ -18,7 +18,7 @@ public Collection getAvailableModes(Person person, List elements) { - IDFPassengerVariables variables = predictor.predictVariables(person, trip, elements); + IDFCarPassengerVariables variables = predictor.predictVariables(person, trip, elements); double utility = 0.0; diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPassengerPredictor.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFCarPassengerPredictor.java similarity index 78% rename from ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPassengerPredictor.java rename to ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFCarPassengerPredictor.java index 2fea60c66..5d3cd491c 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPassengerPredictor.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFCarPassengerPredictor.java @@ -5,7 +5,7 @@ import org.eqasim.core.simulation.mode_choice.utilities.predictors.CachedVariablePredictor; import org.eqasim.core.simulation.mode_choice.utilities.predictors.PredictorUtils; import org.eqasim.ile_de_france.mode_choice.IDFModeChoiceModule; -import org.eqasim.ile_de_france.mode_choice.utilities.variables.IDFPassengerVariables; +import org.eqasim.ile_de_france.mode_choice.utilities.variables.IDFCarPassengerVariables; import org.matsim.api.core.v01.TransportMode; import org.matsim.api.core.v01.population.Leg; import org.matsim.api.core.v01.population.Person; @@ -15,9 +15,9 @@ import com.google.common.base.Verify; -public class IDFPassengerPredictor extends CachedVariablePredictor { +public class IDFCarPassengerPredictor extends CachedVariablePredictor { @Override - public IDFPassengerVariables predict(Person person, DiscreteModeChoiceTrip trip, + public IDFCarPassengerVariables predict(Person person, DiscreteModeChoiceTrip trip, List elements) { double passengerTravelTime_min = 0.0; double accessEgressTime_min = 0.0; @@ -25,7 +25,7 @@ public IDFPassengerVariables predict(Person person, DiscreteModeChoiceTrip trip, boolean foundCar = false; for (Leg leg : TripStructureUtils.getLegs(elements)) { - if (leg.getMode().equals(IDFModeChoiceModule.PASSENGER)) { + if (leg.getMode().equals(IDFModeChoiceModule.CAR_PASSENGER)) { Verify.verify(!foundCar); passengerTravelTime_min += leg.getTravelTime().seconds() / 60.0; } else if (leg.getMode().equals(TransportMode.walk)) { @@ -37,6 +37,6 @@ public IDFPassengerVariables predict(Person person, DiscreteModeChoiceTrip trip, double euclideanDistance_km = PredictorUtils.calculateEuclideanDistance_km(trip); - return new IDFPassengerVariables(passengerTravelTime_min, euclideanDistance_km, accessEgressTime_min); + return new IDFCarPassengerVariables(passengerTravelTime_min, euclideanDistance_km, accessEgressTime_min); } } \ No newline at end of file diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPassengerVariables.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFCarPassengerVariables.java similarity index 69% rename from ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPassengerVariables.java rename to ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFCarPassengerVariables.java index 6701629a9..21523bc33 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPassengerVariables.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFCarPassengerVariables.java @@ -2,12 +2,12 @@ import org.eqasim.core.simulation.mode_choice.utilities.variables.BaseVariables; -public class IDFPassengerVariables implements BaseVariables { +public class IDFCarPassengerVariables implements BaseVariables { final public double travelTime_min; final public double euclideanDistance_km; final public double accessEgressTime_min; - public IDFPassengerVariables(double travelTime_min, double euclideanDistance_km, double accessEgressTime_min) { + public IDFCarPassengerVariables(double travelTime_min, double euclideanDistance_km, double accessEgressTime_min) { this.travelTime_min = travelTime_min; this.euclideanDistance_km = euclideanDistance_km; this.accessEgressTime_min = accessEgressTime_min; diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java index 03917f9fc..e43cc079f 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java @@ -58,7 +58,7 @@ static public void adaptConfiguration(Config config, String prefix) { eqasimConfig.setEstimator(TransportMode.car, IDFModeChoiceModule.CAR_ESTIMATOR_NAME); eqasimConfig.setEstimator(IDFModeChoiceModule.BICYCLE, IDFModeChoiceModule.BICYCLE_ESTIMATOR_NAME); - eqasimConfig.setEstimator(IDFModeChoiceModule.PASSENGER, IDFModeChoiceModule.PASSENGER_ESTIMATOR_NAME); + eqasimConfig.setEstimator(IDFModeChoiceModule.CAR_PASSENGER, IDFModeChoiceModule.CAR_PASSENGER_ESTIMATOR_NAME); eqasimConfig.removeEstimator(TransportMode.bike); // Discrete mode choice @@ -89,6 +89,6 @@ static public void adaptConfiguration(Config config, String prefix) { // Convergence EqasimTerminationConfigGroup terminationConfig = EqasimTerminationConfigGroup.getOrCreate(config); - terminationConfig.setModes(Arrays.asList("car", "passenger", "pt", "bicycle", "walk")); + terminationConfig.setModes(Arrays.asList("car", "car_passenger", "pt", "bicycle", "walk")); } } From a85e04fd604f1c6e6784aa6dce930c8d6417b786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Thu, 3 Oct 2024 18:32:41 +0200 Subject: [PATCH 16/37] update configurator --- .../java/org/eqasim/core/simulation/EqasimConfigurator.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java b/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java index a46a7590e..23a491d02 100644 --- a/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java +++ b/core/src/main/java/org/eqasim/core/simulation/EqasimConfigurator.java @@ -79,8 +79,9 @@ public EqasimConfigurator() { new DiscreteModeChoiceModule(), // new EqasimComponentsModule(), // new EpsilonModule(), // - new EqasimRaptorModule(), - new EqasimModeChoiceModule() // + new EqasimRaptorModule(), // + new EqasimModeChoiceModule(), // + new EqasimTrafficModule() // )); qsimModules.addAll(Arrays.asList( // From 7c895345f5e7629195c73b8125f7dedba9a3285b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Thu, 3 Oct 2024 18:39:54 +0200 Subject: [PATCH 17/37] update parameters without motorbike --- .../parameters/IDFModeParameters.java | 40 ++++++++----------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFModeParameters.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFModeParameters.java index 8ebac229d..7b4bcb5b7 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFModeParameters.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFModeParameters.java @@ -3,12 +3,6 @@ import org.eqasim.core.simulation.mode_choice.parameters.ModeParameters; public class IDFModeParameters extends ModeParameters { - public class IDFCarParameters { - public double betaInVehicleTravelTime_u_min; - } - - public final IDFCarParameters idfCar = new IDFCarParameters(); - public class IDFCarPassengerParameters { public double alpha_u; public double betaInVehicleTravelTime_u_min; @@ -30,40 +24,38 @@ public static IDFModeParameters buildDefault() { IDFModeParameters parameters = new IDFModeParameters(); // Access - parameters.betaAccessTime_u_min = -0.0313; + parameters.betaAccessTime_u_min = -0.0318; // Cost - parameters.betaCost_u_MU = -0.474; - parameters.lambdaCostEuclideanDistance = -0.274; + parameters.betaCost_u_MU = -0.425; + parameters.lambdaCostEuclideanDistance = -0.268; parameters.referenceEuclideanDistance_km = 4.4; // Car - parameters.car.alpha_u = -0.662; - parameters.car.betaTravelTime_u_min = -0.0262; - - parameters.idfCar.betaInVehicleTravelTime_u_min = -0.0262; + parameters.car.alpha_u = -0.613; + parameters.car.betaTravelTime_u_min = -0.0285; // Car passenger - parameters.idfCarPassenger.alpha_u = -2.08; - parameters.idfCarPassenger.betaDrivingPermit_u = -1.17; - parameters.idfCarPassenger.betaInVehicleTravelTime_u_min = -0.0608; + parameters.idfCarPassenger.alpha_u = -2.04; + parameters.idfCarPassenger.betaDrivingPermit_u = -1.16; + parameters.idfCarPassenger.betaInVehicleTravelTime_u_min = -0.0605; // PT parameters.pt.alpha_u = 0.0; - parameters.pt.betaLineSwitch_u = -0.452; - parameters.pt.betaInVehicleTime_u_min = -0.0201; - parameters.pt.betaWaitingTime_u_min = -0.0191; + parameters.pt.betaLineSwitch_u = -0.457; + parameters.pt.betaInVehicleTime_u_min = -0.0195; + parameters.pt.betaWaitingTime_u_min = -0.0195; parameters.pt.betaAccessEgressTime_u_min = parameters.betaAccessTime_u_min; - parameters.idfPt.betaDrivingPermit_u = -0.712; - parameters.idfPt.onlyBus_u = -1.42; + parameters.idfPt.betaDrivingPermit_u = -0.722; + parameters.idfPt.onlyBus_u = -1.43; // Bike - parameters.bike.alpha_u = -3.42; - parameters.bike.betaTravelTime_u_min = -0.0824; + parameters.bike.alpha_u = -3.39; + parameters.bike.betaTravelTime_u_min = -0.0823; // Walk - parameters.walk.alpha_u = 1.2; + parameters.walk.alpha_u = 1.24; parameters.walk.betaTravelTime_u_min = -0.158; return parameters; From 8296a1cfe626d99708a99e998c861dde666f702e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Mon, 7 Oct 2024 07:59:33 +0200 Subject: [PATCH 18/37] add parking costs --- .../spatial/ImputeSpatialAttribute.java | 4 ++ .../mode_choice/costs/IDFCarCostModel.java | 49 ++++++++++++++++++- .../parameters/IDFCostParameters.java | 2 + .../predictors/IDFPersonPredictor.java | 6 +-- .../predictors/IDFPredictorUtils.java | 5 ++ .../variables/IDFPersonVariables.java | 4 +- 6 files changed, 64 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/org/eqasim/core/scenario/spatial/ImputeSpatialAttribute.java b/core/src/main/java/org/eqasim/core/scenario/spatial/ImputeSpatialAttribute.java index d76d34b7f..8069f8c56 100644 --- a/core/src/main/java/org/eqasim/core/scenario/spatial/ImputeSpatialAttribute.java +++ b/core/src/main/java/org/eqasim/core/scenario/spatial/ImputeSpatialAttribute.java @@ -39,6 +39,10 @@ public void run(Population population) throws InterruptedException { if (geometry.contains(point)) { activity.getAttributes().putAttribute(attribute, true); + + if (activity.getType().equals("home")) { + person.getAttributes().putAttribute(attribute, true); + } } } } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFCarCostModel.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFCarCostModel.java index 8a8a45263..ac5153ee8 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFCarCostModel.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFCarCostModel.java @@ -4,23 +4,68 @@ import org.eqasim.core.simulation.mode_choice.cost.AbstractCostModel; import org.eqasim.ile_de_france.mode_choice.parameters.IDFCostParameters; +import org.eqasim.ile_de_france.mode_choice.utilities.predictors.IDFPersonPredictor; +import org.eqasim.ile_de_france.mode_choice.utilities.variables.IDFPersonVariables; import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.Plan; import org.matsim.api.core.v01.population.PlanElement; import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; +import org.matsim.core.utils.timing.TimeInterpretation; +import org.matsim.core.utils.timing.TimeTracker; import com.google.inject.Inject; public class IDFCarCostModel extends AbstractCostModel { + private final TimeInterpretation timeInterpretation; private final IDFCostParameters costParameters; + private final IDFPersonPredictor personPredictor; @Inject - public IDFCarCostModel(IDFCostParameters costParameters) { + public IDFCarCostModel(IDFCostParameters costParameters, IDFPersonPredictor personPredictor, + TimeInterpretation timeInterpretation) { super("car"); + this.costParameters = costParameters; + this.personPredictor = personPredictor; + this.timeInterpretation = timeInterpretation; } @Override public double calculateCost_MU(Person person, DiscreteModeChoiceTrip trip, List elements) { - return costParameters.carCost_EUR_km * getInVehicleDistance_km(elements); + double parkingCost_EUR = calculateParkingCost_EUR(person, trip, elements); + return costParameters.carCost_EUR_km * getInVehicleDistance_km(elements) + parkingCost_EUR; + } + + private double calculateParkingCost_EUR(Person person, DiscreteModeChoiceTrip trip, + List elements) { + IDFPersonVariables personVariables = personPredictor.predictVariables(person, trip, elements); + + if (!personVariables.isParisResident && hasParisDestination(trip)) { + final double parkingDuration_min; + + Plan plan = person.getSelectedPlan(); + if (trip.getDestinationActivity() == plan.getPlanElements().get(plan.getPlanElements().size() - 1)) { + parkingDuration_min = 8.0 * 3600.0 / 60.0; + } else { + TimeTracker timeTracker = new TimeTracker(timeInterpretation); + + timeTracker.setTime(trip.getDepartureTime()); + timeTracker.addElements(elements); + + double activityStartTime = timeTracker.getTime().seconds(); + timeTracker.addActivity(trip.getDestinationActivity()); + + parkingDuration_min = (timeTracker.getTime().seconds() - activityStartTime) / 60.0; + } + + return Math.max(1.0, Math.ceil(parkingDuration_min / 60.0)) * costParameters.parisParkingCost_EUR_h; + } + + return 0.0; + } + + private boolean hasParisDestination(DiscreteModeChoiceTrip trip) { + Boolean isParis = (Boolean) trip.getDestinationActivity().getAttributes().getAttribute("isParis"); + return isParis != null && isParis; } } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFCostParameters.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFCostParameters.java index 098ecb189..73e7929e3 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFCostParameters.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFCostParameters.java @@ -4,11 +4,13 @@ public class IDFCostParameters implements ParameterDefinition { public double carCost_EUR_km = 0.0; + public double parisParkingCost_EUR_h = 0.0; public static IDFCostParameters buildDefault() { IDFCostParameters parameters = new IDFCostParameters(); parameters.carCost_EUR_km = 0.2; + parameters.parisParkingCost_EUR_h = 3.0; return parameters; } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPersonPredictor.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPersonPredictor.java index 249b82371..afd31a462 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPersonPredictor.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPersonPredictor.java @@ -7,14 +7,14 @@ import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.PlanElement; import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; -import org.matsim.core.population.PersonUtils; public class IDFPersonPredictor extends CachedVariablePredictor { @Override protected IDFPersonVariables predict(Person person, DiscreteModeChoiceTrip trip, List elements) { boolean hasSubscription = IDFPredictorUtils.hasSubscription(person); - boolean hasDrivingPermit = !"no".equals(PersonUtils.getLicense(person)); - return new IDFPersonVariables(hasSubscription, hasDrivingPermit); + boolean hasDrivingPermit = IDFPredictorUtils.hasDrivingLicense(person); + boolean isParisResident = IDFPredictorUtils.isParisResident(person); + return new IDFPersonVariables(hasSubscription, hasDrivingPermit, isParisResident); } } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPredictorUtils.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPredictorUtils.java index d8169e0ac..cc6f62dfb 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPredictorUtils.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPredictorUtils.java @@ -25,4 +25,9 @@ static public boolean hasCarAvailability(Person person) { static public boolean hasBicycleAvailability(Person person) { return !"none".equals((String) person.getAttributes().getAttribute("bicycleAvailability")); } + + static public boolean isParisResident(Person person) { + Boolean isResident = (Boolean) person.getAttributes().getAttribute("isParis"); + return isResident != null && isResident; + } } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPersonVariables.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPersonVariables.java index 9d668747d..a46adf04d 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPersonVariables.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/variables/IDFPersonVariables.java @@ -5,9 +5,11 @@ public class IDFPersonVariables implements BaseVariables { public final boolean hasSubscription; public final boolean hasDrivingPermit; + public final boolean isParisResident; - public IDFPersonVariables(boolean hasSubscription, boolean hasDrivingPermit) { + public IDFPersonVariables(boolean hasSubscription, boolean hasDrivingPermit, boolean isParisResident) { this.hasSubscription = hasSubscription; this.hasDrivingPermit = hasDrivingPermit; + this.isParisResident = isParisResident; } } From a666bbb7e636a97900fed55868e68b06ed7650eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Mon, 7 Oct 2024 18:10:09 +0200 Subject: [PATCH 19/37] update certain definitions in estimator --- .../estimators/IDFPtUtilityEstimator.java | 43 ++++++++++--- .../utilities/predictors/IDFPtPredictor.java | 61 ++++++++++++++++++- .../utilities/variables/IDFPtVariables.java | 18 +++++- 3 files changed, 112 insertions(+), 10 deletions(-) diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFPtUtilityEstimator.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFPtUtilityEstimator.java index e61ec0dcf..b79c8859b 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFPtUtilityEstimator.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFPtUtilityEstimator.java @@ -2,8 +2,8 @@ import java.util.List; -import org.eqasim.core.simulation.mode_choice.utilities.estimators.PtUtilityEstimator; -import org.eqasim.core.simulation.mode_choice.utilities.predictors.PtPredictor; +import org.eqasim.core.simulation.mode_choice.utilities.UtilityEstimator; +import org.eqasim.core.simulation.mode_choice.utilities.estimators.EstimatorUtils; import org.eqasim.ile_de_france.mode_choice.parameters.IDFModeParameters; import org.eqasim.ile_de_france.mode_choice.utilities.predictors.IDFPersonPredictor; import org.eqasim.ile_de_france.mode_choice.utilities.predictors.IDFPtPredictor; @@ -15,21 +15,44 @@ import com.google.inject.Inject; -public class IDFPtUtilityEstimator extends PtUtilityEstimator { +public class IDFPtUtilityEstimator implements UtilityEstimator { private final IDFModeParameters parameters; private final IDFPersonPredictor personPredictor; private final IDFPtPredictor idfPtPredictor; @Inject public IDFPtUtilityEstimator(IDFModeParameters parameters, IDFPtPredictor idfPtPredictor, - IDFPersonPredictor personPredictor, PtPredictor ptPredictor) { - super(parameters, ptPredictor); - + IDFPersonPredictor personPredictor) { this.personPredictor = personPredictor; this.idfPtPredictor = idfPtPredictor; this.parameters = parameters; } + protected double estimateConstantUtility() { + return parameters.pt.alpha_u; + } + + protected double estimateAccessEgressTimeUtility(IDFPtVariables variables) { + return parameters.pt.betaAccessEgressTime_u_min * variables.accessEgressTime_min; + } + + protected double estimateInVehicleTimeUtility(IDFPtVariables variables) { + return parameters.pt.betaInVehicleTime_u_min * variables.inVehicleTime_min; + } + + protected double estimateWaitingTimeUtility(IDFPtVariables variables) { + return parameters.pt.betaWaitingTime_u_min * variables.waitingTime_min; + } + + protected double estimateLineSwitchUtility(IDFPtVariables variables) { + return parameters.pt.betaLineSwitch_u * variables.numberOfLineSwitches; + } + + protected double estimateMonetaryCostUtility(IDFPtVariables variables) { + return parameters.betaCost_u_MU * EstimatorUtils.interaction(variables.euclideanDistance_km, + parameters.referenceEuclideanDistance_km, parameters.lambdaCostEuclideanDistance) * variables.cost_MU; + } + protected double estimateDrivingPermitUtility(IDFPersonVariables variables) { return variables.hasDrivingPermit ? parameters.idfPt.betaDrivingPermit_u : 0.0; } @@ -45,7 +68,13 @@ public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List { static public final String PARIS_ATTRIBUTE = "isParis"; private final TransitSchedule schedule; + private final CostModel costModel; @Inject - public IDFPtPredictor(TransitSchedule schedule) { + public IDFPtPredictor(TransitSchedule schedule, @Named("pt") CostModel costModel) { this.schedule = schedule; + this.costModel = costModel; + } + + protected CostModel getCostModel() { + return this.costModel; } @Override public IDFPtVariables predict(Person person, DiscreteModeChoiceTrip trip, List elements) { + int numberOfVehicularTrips = 0; + boolean isFirstWaitingTime = false; // different from standard estimator + + // Track relevant variables (from standard estimator) + double inVehicleTime_min = 0.0; + double waitingTime_min = 0.0; + double accessEgressTime_min = 0.0; + + // Track IDF variables int busCount = 0; int subwayCount = 0; int otherCount = 0; @@ -37,6 +56,36 @@ public IDFPtVariables predict(Person person, DiscreteModeChoiceTrip trip, List 0 && subwayCount == 0 && otherCount == 0; boolean hasOnlySubwayAndBus = (busCount > 0 || subwayCount > 0) && otherCount == 0; @@ -72,6 +128,7 @@ public IDFPtVariables predict(Person person, DiscreteModeChoiceTrip trip, List Date: Mon, 7 Oct 2024 18:52:32 +0200 Subject: [PATCH 20/37] avoid circular dependency for predictor --- .../estimators/IDFPtUtilityEstimator.java | 14 ++++++++++---- .../utilities/predictors/IDFPtPredictor.java | 12 +++--------- .../utilities/variables/IDFPtVariables.java | 4 +--- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFPtUtilityEstimator.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFPtUtilityEstimator.java index b79c8859b..39bdaee0f 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFPtUtilityEstimator.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFPtUtilityEstimator.java @@ -2,6 +2,7 @@ import java.util.List; +import org.eqasim.core.simulation.mode_choice.cost.CostModel; import org.eqasim.core.simulation.mode_choice.utilities.UtilityEstimator; import org.eqasim.core.simulation.mode_choice.utilities.estimators.EstimatorUtils; import org.eqasim.ile_de_france.mode_choice.parameters.IDFModeParameters; @@ -14,18 +15,21 @@ import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; import com.google.inject.Inject; +import com.google.inject.name.Named; public class IDFPtUtilityEstimator implements UtilityEstimator { private final IDFModeParameters parameters; private final IDFPersonPredictor personPredictor; private final IDFPtPredictor idfPtPredictor; + private final CostModel costModel; @Inject public IDFPtUtilityEstimator(IDFModeParameters parameters, IDFPtPredictor idfPtPredictor, - IDFPersonPredictor personPredictor) { + IDFPersonPredictor personPredictor, @Named("pt") CostModel costModel) { this.personPredictor = personPredictor; this.idfPtPredictor = idfPtPredictor; this.parameters = parameters; + this.costModel = costModel; } protected double estimateConstantUtility() { @@ -48,9 +52,9 @@ protected double estimateLineSwitchUtility(IDFPtVariables variables) { return parameters.pt.betaLineSwitch_u * variables.numberOfLineSwitches; } - protected double estimateMonetaryCostUtility(IDFPtVariables variables) { + protected double estimateMonetaryCostUtility(IDFPtVariables variables, double cost_EUR) { return parameters.betaCost_u_MU * EstimatorUtils.interaction(variables.euclideanDistance_km, - parameters.referenceEuclideanDistance_km, parameters.lambdaCostEuclideanDistance) * variables.cost_MU; + parameters.referenceEuclideanDistance_km, parameters.lambdaCostEuclideanDistance) * cost_EUR; } protected double estimateDrivingPermitUtility(IDFPersonVariables variables) { @@ -66,6 +70,8 @@ public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List { static public final String PARIS_ATTRIBUTE = "isParis"; private final TransitSchedule schedule; - private final CostModel costModel; @Inject - public IDFPtPredictor(TransitSchedule schedule, @Named("pt") CostModel costModel) { + public IDFPtPredictor(TransitSchedule schedule) { this.schedule = schedule; - this.costModel = costModel; } protected CostModel getCostModel() { - return this.costModel; + return null; } @Override @@ -108,9 +105,6 @@ public IDFPtVariables predict(Person person, DiscreteModeChoiceTrip trip, List 0 && subwayCount == 0 && otherCount == 0; @@ -129,6 +123,6 @@ public IDFPtVariables predict(Person person, DiscreteModeChoiceTrip trip, List Date: Mon, 7 Oct 2024 22:06:02 +0200 Subject: [PATCH 21/37] fix error in cost model --- .../mode_choice/utilities/predictors/IDFPtPredictor.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java index c34eb34fe..dce29ec6e 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java @@ -92,6 +92,8 @@ public IDFPtVariables predict(Person person, DiscreteModeChoiceTrip trip, List Date: Tue, 8 Oct 2024 08:09:50 +0200 Subject: [PATCH 22/37] idf pt estimator was not enabled --- .../java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java | 1 + 1 file changed, 1 insertion(+) diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java index dadc344f3..b382ea34a 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java @@ -56,6 +56,7 @@ static public void adaptConfiguration(Config config, String prefix) { eqasimConfig.setCostModel(TransportMode.pt, IDFModeChoiceModule.PT_COST_MODEL_NAME); eqasimConfig.setEstimator(TransportMode.car, IDFModeChoiceModule.CAR_ESTIMATOR_NAME); + eqasimConfig.setEstimator(TransportMode.pt, IDFModeChoiceModule.PT_ESTIMATOR_NAME); eqasimConfig.setEstimator(IDFModeChoiceModule.BICYCLE, IDFModeChoiceModule.BICYCLE_ESTIMATOR_NAME); eqasimConfig.setEstimator(IDFModeChoiceModule.CAR_PASSENGER, IDFModeChoiceModule.CAR_PASSENGER_ESTIMATOR_NAME); eqasimConfig.removeEstimator(TransportMode.bike); From a57fa7d5adb34b6f8c841e88596257fd3962dfec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Tue, 8 Oct 2024 10:56:57 +0200 Subject: [PATCH 23/37] fixes and forgot to add driving permit for car passenger --- .../components/traffic/EqasimTrafficQSimModule.java | 3 +-- .../estimators/IDFCarPassengerUtilityEstimator.java | 13 ++++++++++++- .../ile_de_france/scenario/RunAdaptConfig.java | 1 + 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/eqasim/core/components/traffic/EqasimTrafficQSimModule.java b/core/src/main/java/org/eqasim/core/components/traffic/EqasimTrafficQSimModule.java index e102c8db6..ce1b10c3e 100644 --- a/core/src/main/java/org/eqasim/core/components/traffic/EqasimTrafficQSimModule.java +++ b/core/src/main/java/org/eqasim/core/components/traffic/EqasimTrafficQSimModule.java @@ -1,7 +1,6 @@ package org.eqasim.core.components.traffic; import org.matsim.core.mobsim.qsim.AbstractQSimModule; -import org.matsim.core.mobsim.qsim.qnetsimengine.linkspeedcalculator.LinkSpeedCalculator; import com.google.inject.Provides; import com.google.inject.Singleton; @@ -9,7 +8,7 @@ public class EqasimTrafficQSimModule extends AbstractQSimModule { @Override protected void configureQSim() { - bind(LinkSpeedCalculator.class).to(EqasimLinkSpeedCalculator.class); + addLinkSpeedCalculator().to(EqasimLinkSpeedCalculator.class); } @Provides diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFCarPassengerUtilityEstimator.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFCarPassengerUtilityEstimator.java index f7574f5de..b72d1600b 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFCarPassengerUtilityEstimator.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFCarPassengerUtilityEstimator.java @@ -5,7 +5,9 @@ import org.eqasim.core.simulation.mode_choice.utilities.UtilityEstimator; import org.eqasim.ile_de_france.mode_choice.parameters.IDFModeParameters; import org.eqasim.ile_de_france.mode_choice.utilities.predictors.IDFCarPassengerPredictor; +import org.eqasim.ile_de_france.mode_choice.utilities.predictors.IDFPersonPredictor; import org.eqasim.ile_de_france.mode_choice.utilities.variables.IDFCarPassengerVariables; +import org.eqasim.ile_de_france.mode_choice.utilities.variables.IDFPersonVariables; import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.PlanElement; import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; @@ -15,11 +17,14 @@ public class IDFCarPassengerUtilityEstimator implements UtilityEstimator { private final IDFModeParameters parameters; private final IDFCarPassengerPredictor predictor; + private final IDFPersonPredictor personPredictor; @Inject - public IDFCarPassengerUtilityEstimator(IDFModeParameters parameters, IDFCarPassengerPredictor predictor) { + public IDFCarPassengerUtilityEstimator(IDFModeParameters parameters, IDFCarPassengerPredictor predictor, + IDFPersonPredictor personPredictor) { this.parameters = parameters; this.predictor = predictor; + this.personPredictor = personPredictor; } protected double estimateConstantUtility() { @@ -34,15 +39,21 @@ protected double estimateAccessEgressTimeUtility(IDFCarPassengerVariables variab return parameters.betaAccessTime_u_min * variables.accessEgressTime_min; } + protected double estimateDrivingPermit(IDFPersonVariables variables) { + return variables.hasDrivingPermit ? parameters.idfCarPassenger.betaDrivingPermit_u : 0.0; + } + @Override public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List elements) { IDFCarPassengerVariables variables = predictor.predictVariables(person, trip, elements); + IDFPersonVariables personVariables = personPredictor.predictVariables(person, trip, elements); double utility = 0.0; utility += estimateConstantUtility(); utility += estimateTravelTimeUtility(variables); utility += estimateAccessEgressTimeUtility(variables); + utility += estimateDrivingPermit(personVariables); return utility; } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java index b382ea34a..f6b50f7f5 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java @@ -66,6 +66,7 @@ static public void adaptConfiguration(Config config, String prefix) { .get(DiscreteModeChoiceConfigGroup.GROUP_NAME); dmcConfig.setModeAvailability(IDFModeChoiceModule.MODE_AVAILABILITY_NAME); + dmcConfig.setCachedModes(Arrays.asList("car", "bicycle", "pt", "walk", "car_passenger", "truck")); Set tripConstraints = new HashSet<>(dmcConfig.getTripConstraints()); tripConstraints.remove(EqasimModeChoiceModule.PASSENGER_CONSTRAINT_NAME); From c0645372957b594a7c291b504cd4c868d1a8c40a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Wed, 9 Oct 2024 11:37:21 +0200 Subject: [PATCH 24/37] update passenger availability and some other parameters --- .../mode_choice/IDFModeAvailability.java | 9 +++-- .../parameters/IDFModeParameters.java | 35 +++++++++---------- .../estimators/IDFPtUtilityEstimator.java | 2 +- .../scenario/RunAdaptConfig.java | 6 +++- 4 files changed, 29 insertions(+), 23 deletions(-) diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeAvailability.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeAvailability.java index 1b1c9d451..f743af0d1 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeAvailability.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/IDFModeAvailability.java @@ -18,11 +18,14 @@ public Collection getAvailableModes(Person person, List Date: Wed, 9 Oct 2024 17:29:34 +0200 Subject: [PATCH 25/37] fix bug in cost model --- .../ile_de_france/mode_choice/costs/IDFPtCostModel.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFPtCostModel.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFPtCostModel.java index 8c98f0510..d2a65a370 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFPtCostModel.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFPtCostModel.java @@ -31,6 +31,7 @@ public IDFPtCostModel(IDFPersonPredictor personPredictor, IDFPtPredictor ptPredi private final static double regressionB = 0.006; private final static double regressionC = 0.006; private final static double regressionD = -0.77; + private final static double basePrice = 5.5; @Override public double calculateCost_MU(Person person, DiscreteModeChoiceTrip trip, List elements) { @@ -45,7 +46,7 @@ public double calculateCost_MU(Person person, DiscreteModeChoiceTrip trip, List< IDFPtVariables ptVariables = ptPredictor.predictVariables(person, trip, elements); if (ptVariables.hasOnlySubwayAndBus || ptVariables.isWithinParis) { - return 1.8; + return 1.9; } // III) Otherwise, use regression by Abdelkader DIB @@ -58,7 +59,7 @@ public double calculateCost_MU(Person person, DiscreteModeChoiceTrip trip, List< double destinationCenterDistance_km = 1e-3 * CoordUtils.calcEuclideanDistance(CENTER, trip.getDestinationActivity().getCoord()); - return Math.max(1.9, sigmoid(regressionA * directDistance_km + regressionB * originCenterDistance_km + return Math.max(1.9, basePrice * sigmoid(regressionA * directDistance_km + regressionB * originCenterDistance_km + regressionC * destinationCenterDistance_km + regressionD)); } From a7e5984911ae9eba18c79d0495fba6e539dc5a2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Thu, 10 Oct 2024 16:41:19 +0200 Subject: [PATCH 26/37] test in pt model --- .../utilities/predictors/IDFPtPredictor.java | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java index dce29ec6e..9f80e4597 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java @@ -11,6 +11,8 @@ import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.PlanElement; import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; +import org.matsim.core.utils.timing.TimeInterpretation; +import org.matsim.core.utils.timing.TimeTracker; import org.matsim.pt.routes.TransitPassengerRoute; import org.matsim.pt.transitSchedule.api.TransitLine; import org.matsim.pt.transitSchedule.api.TransitRoute; @@ -23,10 +25,12 @@ public class IDFPtPredictor extends CachedVariablePredictor { static public final String PARIS_ATTRIBUTE = "isParis"; private final TransitSchedule schedule; + private final TimeInterpretation timeInterpretation; @Inject - public IDFPtPredictor(TransitSchedule schedule) { + public IDFPtPredictor(TransitSchedule schedule, TimeInterpretation timeInterpretation) { this.schedule = schedule; + this.timeInterpretation = timeInterpretation; } protected CostModel getCostModel() { @@ -36,7 +40,7 @@ protected CostModel getCostModel() { @Override public IDFPtVariables predict(Person person, DiscreteModeChoiceTrip trip, List elements) { int numberOfVehicularTrips = 0; - boolean isFirstWaitingTime = false; // different from standard estimator + boolean isFirstTransitLeg = true; // Track relevant variables (from standard estimator) double inVehicleTime_min = 0.0; @@ -51,7 +55,13 @@ public IDFPtVariables predict(Person person, DiscreteModeChoiceTrip trip, List= 0.0; - if (!isFirstWaitingTime) { - waitingTime_min += waitingTime / 60.0; - } else { - isFirstWaitingTime = false; + if (isFirstTransitLeg) { + // if departure is in the future, offset here + waitingTime += Math.max(0.0, leg.getDepartureTime().seconds() - elementStartTime); + isFirstTransitLeg = false; } + inVehicleTime_min += inVehicleTime / 60.0; + waitingTime_min += waitingTime / 60.0; + numberOfVehicularTrips++; break; default: From 64864b44f88e7f4ae0140340190864f88212cb9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Thu, 10 Oct 2024 18:51:49 +0200 Subject: [PATCH 27/37] update model --- .../parameters/IDFModeParameters.java | 34 +++++++++---------- .../utilities/predictors/IDFPtPredictor.java | 21 +----------- 2 files changed, 18 insertions(+), 37 deletions(-) diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFModeParameters.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFModeParameters.java index c84fe2e83..9829632e2 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFModeParameters.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFModeParameters.java @@ -24,38 +24,38 @@ public static IDFModeParameters buildDefault() { IDFModeParameters parameters = new IDFModeParameters(); // Access - parameters.betaAccessTime_u_min = -0.0312; + parameters.betaAccessTime_u_min = -0.031239; // Cost - parameters.betaCost_u_MU = -0.311; - parameters.lambdaCostEuclideanDistance = -0.258; + parameters.betaCost_u_MU = -0.310998; + parameters.lambdaCostEuclideanDistance = -0.257501; parameters.referenceEuclideanDistance_km = 4.4; // Car - parameters.car.alpha_u = -0.201; - parameters.car.betaTravelTime_u_min = -0.0424; + parameters.car.alpha_u = -0.201465; + parameters.car.betaTravelTime_u_min = -0.042431; // Car passenger - parameters.idfCarPassenger.alpha_u = -1.71; - parameters.idfCarPassenger.betaDrivingPermit_u = -0.835; - parameters.idfCarPassenger.betaInVehicleTravelTime_u_min = -0.07; + parameters.idfCarPassenger.alpha_u = -1.713201; + parameters.idfCarPassenger.betaDrivingPermit_u = -0.835542; + parameters.idfCarPassenger.betaInVehicleTravelTime_u_min = -0.069976; // PT parameters.pt.alpha_u = 0.0; - parameters.pt.betaLineSwitch_u = -0.418; - parameters.pt.betaInVehicleTime_u_min = -0.0255; - parameters.pt.betaWaitingTime_u_min = -0.0218; + parameters.pt.betaLineSwitch_u = -0.417658; + parameters.pt.betaInVehicleTime_u_min = -0.025501; + parameters.pt.betaWaitingTime_u_min = -0.021801; - parameters.idfPt.betaDrivingPermit_u = -0.531; - parameters.idfPt.onlyBus_u = -1.42; + parameters.idfPt.betaDrivingPermit_u = -0.531426; + parameters.idfPt.onlyBus_u = -1.416309; // Bike - parameters.bike.alpha_u = -2.93; - parameters.bike.betaTravelTime_u_min = -0.0935; + parameters.bike.alpha_u = -2.927596 ; + parameters.bike.betaTravelTime_u_min = -0.093485; // Walk - parameters.walk.alpha_u = 1.69; - parameters.walk.betaTravelTime_u_min = -0.162; + parameters.walk.alpha_u = 1.685152; + parameters.walk.betaTravelTime_u_min = -0.162285; return parameters; } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java index 9f80e4597..2287c16ad 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java @@ -11,8 +11,6 @@ import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.PlanElement; import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip; -import org.matsim.core.utils.timing.TimeInterpretation; -import org.matsim.core.utils.timing.TimeTracker; import org.matsim.pt.routes.TransitPassengerRoute; import org.matsim.pt.transitSchedule.api.TransitLine; import org.matsim.pt.transitSchedule.api.TransitRoute; @@ -25,12 +23,10 @@ public class IDFPtPredictor extends CachedVariablePredictor { static public final String PARIS_ATTRIBUTE = "isParis"; private final TransitSchedule schedule; - private final TimeInterpretation timeInterpretation; @Inject - public IDFPtPredictor(TransitSchedule schedule, TimeInterpretation timeInterpretation) { + public IDFPtPredictor(TransitSchedule schedule) { this.schedule = schedule; - this.timeInterpretation = timeInterpretation; } protected CostModel getCostModel() { @@ -40,7 +36,6 @@ protected CostModel getCostModel() { @Override public IDFPtVariables predict(Person person, DiscreteModeChoiceTrip trip, List elements) { int numberOfVehicularTrips = 0; - boolean isFirstTransitLeg = true; // Track relevant variables (from standard estimator) double inVehicleTime_min = 0.0; @@ -55,13 +50,7 @@ public IDFPtVariables predict(Person person, DiscreteModeChoiceTrip trip, List= 0.0; - - if (isFirstTransitLeg) { - // if departure is in the future, offset here - waitingTime += Math.max(0.0, leg.getDepartureTime().seconds() - elementStartTime); - isFirstTransitLeg = false; - } - inVehicleTime_min += inVehicleTime / 60.0; waitingTime_min += waitingTime / 60.0; From 361463ad610eb16d76dfc4d2081847c3a761fc9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Sat, 12 Oct 2024 10:31:45 +0200 Subject: [PATCH 28/37] add debugging output --- .../ile_de_france/mode_choice/costs/IDFCarCostModel.java | 1 + .../ile_de_france/mode_choice/costs/IDFPtCostModel.java | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFCarCostModel.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFCarCostModel.java index ac5153ee8..8821859d4 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFCarCostModel.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFCarCostModel.java @@ -33,6 +33,7 @@ public IDFCarCostModel(IDFCostParameters costParameters, IDFPersonPredictor pers @Override public double calculateCost_MU(Person person, DiscreteModeChoiceTrip trip, List elements) { double parkingCost_EUR = calculateParkingCost_EUR(person, trip, elements); + System.err.println("Car: " + parkingCost_EUR + " + " + costParameters.carCost_EUR_km * getInVehicleDistance_km(elements)); return costParameters.carCost_EUR_km * getInVehicleDistance_km(elements) + parkingCost_EUR; } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFPtCostModel.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFPtCostModel.java index d2a65a370..8f6fa44fc 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFPtCostModel.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFPtCostModel.java @@ -39,6 +39,7 @@ public double calculateCost_MU(Person person, DiscreteModeChoiceTrip trip, List< IDFPersonVariables personVariables = personPredictor.predictVariables(person, trip, elements); if (personVariables.hasSubscription) { + System.err.println("PT Cost: Subscription"); return 0.0; } @@ -46,6 +47,7 @@ public double calculateCost_MU(Person person, DiscreteModeChoiceTrip trip, List< IDFPtVariables ptVariables = ptPredictor.predictVariables(person, trip, elements); if (ptVariables.hasOnlySubwayAndBus || ptVariables.isWithinParis) { + System.err.println("PT Cost: Single"); return 1.9; } @@ -59,6 +61,8 @@ public double calculateCost_MU(Person person, DiscreteModeChoiceTrip trip, List< double destinationCenterDistance_km = 1e-3 * CoordUtils.calcEuclideanDistance(CENTER, trip.getDestinationActivity().getCoord()); + System.err.println("PT Cost: IDF " + Math.max(1.9, basePrice * sigmoid(regressionA * directDistance_km + regressionB * originCenterDistance_km + + regressionC * destinationCenterDistance_km + regressionD))); return Math.max(1.9, basePrice * sigmoid(regressionA * directDistance_km + regressionB * originCenterDistance_km + regressionC * destinationCenterDistance_km + regressionD)); } From db67327c0c1d83fde388b64a4e3022104f38cab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Sat, 12 Oct 2024 10:53:18 +0200 Subject: [PATCH 29/37] revert debugging --- .../ile_de_france/mode_choice/costs/IDFCarCostModel.java | 1 - .../ile_de_france/mode_choice/costs/IDFPtCostModel.java | 4 ---- 2 files changed, 5 deletions(-) diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFCarCostModel.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFCarCostModel.java index 8821859d4..ac5153ee8 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFCarCostModel.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFCarCostModel.java @@ -33,7 +33,6 @@ public IDFCarCostModel(IDFCostParameters costParameters, IDFPersonPredictor pers @Override public double calculateCost_MU(Person person, DiscreteModeChoiceTrip trip, List elements) { double parkingCost_EUR = calculateParkingCost_EUR(person, trip, elements); - System.err.println("Car: " + parkingCost_EUR + " + " + costParameters.carCost_EUR_km * getInVehicleDistance_km(elements)); return costParameters.carCost_EUR_km * getInVehicleDistance_km(elements) + parkingCost_EUR; } diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFPtCostModel.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFPtCostModel.java index 8f6fa44fc..d2a65a370 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFPtCostModel.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/costs/IDFPtCostModel.java @@ -39,7 +39,6 @@ public double calculateCost_MU(Person person, DiscreteModeChoiceTrip trip, List< IDFPersonVariables personVariables = personPredictor.predictVariables(person, trip, elements); if (personVariables.hasSubscription) { - System.err.println("PT Cost: Subscription"); return 0.0; } @@ -47,7 +46,6 @@ public double calculateCost_MU(Person person, DiscreteModeChoiceTrip trip, List< IDFPtVariables ptVariables = ptPredictor.predictVariables(person, trip, elements); if (ptVariables.hasOnlySubwayAndBus || ptVariables.isWithinParis) { - System.err.println("PT Cost: Single"); return 1.9; } @@ -61,8 +59,6 @@ public double calculateCost_MU(Person person, DiscreteModeChoiceTrip trip, List< double destinationCenterDistance_km = 1e-3 * CoordUtils.calcEuclideanDistance(CENTER, trip.getDestinationActivity().getCoord()); - System.err.println("PT Cost: IDF " + Math.max(1.9, basePrice * sigmoid(regressionA * directDistance_km + regressionB * originCenterDistance_km - + regressionC * destinationCenterDistance_km + regressionD))); return Math.max(1.9, basePrice * sigmoid(regressionA * directDistance_km + regressionB * originCenterDistance_km + regressionC * destinationCenterDistance_km + regressionD)); } From b59c19bd9b8982c5aac3c759ee4ed0a58f8b898b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Sat, 12 Oct 2024 23:20:34 +0200 Subject: [PATCH 30/37] formatting --- .../ile_de_france/mode_choice/parameters/IDFModeParameters.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFModeParameters.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFModeParameters.java index 9829632e2..4e88aff2e 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFModeParameters.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/parameters/IDFModeParameters.java @@ -50,7 +50,7 @@ public static IDFModeParameters buildDefault() { parameters.idfPt.onlyBus_u = -1.416309; // Bike - parameters.bike.alpha_u = -2.927596 ; + parameters.bike.alpha_u = -2.927596; parameters.bike.betaTravelTime_u_min = -0.093485; // Walk From f08ae29bd1816f4d99c9cc413682747b75b0933a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Mon, 14 Oct 2024 09:07:21 +0200 Subject: [PATCH 31/37] rearranging some code --- .../estimators/IDFPtUtilityEstimator.java | 18 +++++++++--------- .../utilities/predictors/IDFPtPredictor.java | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFPtUtilityEstimator.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFPtUtilityEstimator.java index 830866886..76633ad5c 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFPtUtilityEstimator.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/estimators/IDFPtUtilityEstimator.java @@ -40,23 +40,23 @@ protected double estimateAccessEgressTimeUtility(IDFPtVariables variables) { return parameters.betaAccessTime_u_min * variables.accessEgressTime_min; } - protected double estimateInVehicleTimeUtility(IDFPtVariables variables) { - return parameters.pt.betaInVehicleTime_u_min * variables.inVehicleTime_min; + protected double estimateLineSwitchUtility(IDFPtVariables variables) { + return parameters.pt.betaLineSwitch_u * variables.numberOfLineSwitches; } protected double estimateWaitingTimeUtility(IDFPtVariables variables) { return parameters.pt.betaWaitingTime_u_min * variables.waitingTime_min; } - protected double estimateLineSwitchUtility(IDFPtVariables variables) { - return parameters.pt.betaLineSwitch_u * variables.numberOfLineSwitches; - } - protected double estimateMonetaryCostUtility(IDFPtVariables variables, double cost_EUR) { return parameters.betaCost_u_MU * EstimatorUtils.interaction(variables.euclideanDistance_km, parameters.referenceEuclideanDistance_km, parameters.lambdaCostEuclideanDistance) * cost_EUR; } + protected double estimateInVehicleTimeUtility(IDFPtVariables variables) { + return parameters.pt.betaInVehicleTime_u_min * variables.inVehicleTime_min; + } + protected double estimateDrivingPermitUtility(IDFPersonVariables variables) { return variables.hasDrivingPermit ? parameters.idfPt.betaDrivingPermit_u : 0.0; } @@ -76,13 +76,13 @@ public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List elements) { - int numberOfVehicularTrips = 0; + int numberOfVehicularLegs = 0; // Track relevant variables (from standard estimator) double inVehicleTime_min = 0.0; @@ -71,7 +71,7 @@ public IDFPtVariables predict(Person person, DiscreteModeChoiceTrip trip, List Date: Sun, 20 Oct 2024 18:48:56 +0200 Subject: [PATCH 32/37] fix bug for pt variables --- .../mode_choice/utilities/predictors/IDFPtPredictor.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java index 11e12302a..5850fbfd6 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/mode_choice/utilities/predictors/IDFPtPredictor.java @@ -76,8 +76,8 @@ public IDFPtVariables predict(Person person, DiscreteModeChoiceTrip trip, List Date: Mon, 21 Oct 2024 02:50:46 +0200 Subject: [PATCH 33/37] add vdf --- .../core/simulation/vdf/VDFQSimModule.java | 14 +------------- .../eqasim/ile_de_france/RunSimulation.java | 19 ++++++++++++++++++- .../scenario/RunAdaptConfig.java | 4 ++-- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/org/eqasim/core/simulation/vdf/VDFQSimModule.java b/core/src/main/java/org/eqasim/core/simulation/vdf/VDFQSimModule.java index 2b250b3d9..3c72bd4c8 100644 --- a/core/src/main/java/org/eqasim/core/simulation/vdf/VDFQSimModule.java +++ b/core/src/main/java/org/eqasim/core/simulation/vdf/VDFQSimModule.java @@ -2,12 +2,8 @@ import org.eqasim.core.simulation.vdf.travel_time.VDFLinkSpeedCalculator; import org.eqasim.core.simulation.vdf.travel_time.VDFTravelTime; -import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.population.Population; -import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.mobsim.qsim.AbstractQSimModule; -import org.matsim.core.mobsim.qsim.qnetsimengine.ConfigurableQNetworkFactory; -import org.matsim.core.mobsim.qsim.qnetsimengine.QNetworkFactory; import com.google.inject.Provides; import com.google.inject.Singleton; @@ -15,15 +11,7 @@ public class VDFQSimModule extends AbstractQSimModule { @Override protected void configureQSim() { - } - - @Provides - @Singleton - public QNetworkFactory provideQNetworkFactory(EventsManager events, Scenario scenario, - VDFLinkSpeedCalculator linkSpeedCalculator) { - ConfigurableQNetworkFactory networkFactory = new ConfigurableQNetworkFactory(events, scenario); - networkFactory.setLinkSpeedCalculator(linkSpeedCalculator); - return networkFactory; + addLinkSpeedCalculator().to(VDFLinkSpeedCalculator.class); } @Provides diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java index 19c6d0cdb..4b84a560f 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java @@ -10,6 +10,8 @@ import org.eqasim.core.scenario.validation.VehiclesValidator; import org.eqasim.core.simulation.analysis.EqasimAnalysisModule; import org.eqasim.core.simulation.mode_choice.EqasimModeChoiceModule; +import org.eqasim.core.simulation.vdf.VDFConfigGroup; +import org.eqasim.core.simulation.vdf.engine.VDFEngineConfigGroup; import org.eqasim.ile_de_france.mode_choice.IDFModeChoiceModule; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; @@ -39,11 +41,26 @@ public class RunSimulation { static public void main(String[] args) throws ConfigurationException { CommandLine cmd = new CommandLine.Builder(args) // .requireOptions("config-path") // - .allowPrefixes("mode-choice-parameter", "cost-parameter") // + .allowPrefixes("mode-choice-parameter", "cost-parameter", "use-vdf") // .build(); IDFConfigurator configurator = new IDFConfigurator(); Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"), configurator.getConfigGroups()); + + if (cmd.getOption("use-vdf").map(Boolean::parseBoolean).orElse(false)) { + EqasimConfigGroup eqasimConfig = EqasimConfigGroup.get(config); + + VDFConfigGroup vdfConfig = new VDFConfigGroup(); + config.addModule(vdfConfig); + + vdfConfig.setCapacityFactor(eqasimConfig.getSampleSize()); + vdfConfig.setModes(Set.of("car", "car_passenger")); + + VDFEngineConfigGroup engineConfig = new VDFEngineConfigGroup(); + engineConfig.setModes(Set.of("car", "car_passenger")); + engineConfig.setGenerateNetworkEvents(false); + } + configurator.addOptionalConfigGroups(config); cmd.applyConfiguration(config); VehiclesValidator.validate(config); diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java index dee7678ef..4ca204479 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/scenario/RunAdaptConfig.java @@ -33,7 +33,7 @@ static public void adaptConfiguration(Config config, String prefix) { config.routing().setAccessEgressType(AccessEgressType.accessEgressModeToLink); Set networkModes = new HashSet<>(config.routing().getNetworkModes()); - networkModes.add("passenger"); + networkModes.add(IDFModeChoiceModule.CAR_PASSENGER); config.routing().setNetworkModes(networkModes); TeleportedModeParams bicycleRouteParams = new TeleportedModeParams(); @@ -70,7 +70,7 @@ static public void adaptConfiguration(Config config, String prefix) { .get(DiscreteModeChoiceConfigGroup.GROUP_NAME); dmcConfig.setModeAvailability(IDFModeChoiceModule.MODE_AVAILABILITY_NAME); - dmcConfig.setCachedModes(Arrays.asList("car", "bicycle", "pt", "walk", "car_passenger", "truck")); + dmcConfig.setCachedModes(Arrays.asList("car", "bicycle", "pt", "walk", IDFModeChoiceModule.CAR_PASSENGER, "truck")); Set tripConstraints = new HashSet<>(dmcConfig.getTripConstraints()); tripConstraints.remove(EqasimModeChoiceModule.PASSENGER_CONSTRAINT_NAME); From 3f1092a6a79da604892731a0c377950932e7ef8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Mon, 21 Oct 2024 12:03:30 +0200 Subject: [PATCH 34/37] fix vdf --- .../src/main/java/org/eqasim/ile_de_france/RunSimulation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java index 4b84a560f..8c7273e1e 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java @@ -59,7 +59,7 @@ static public void main(String[] args) throws ConfigurationException { VDFEngineConfigGroup engineConfig = new VDFEngineConfigGroup(); engineConfig.setModes(Set.of("car", "car_passenger")); engineConfig.setGenerateNetworkEvents(false); - } + config.addModule(engineConfig); } configurator.addOptionalConfigGroups(config); cmd.applyConfiguration(config); From ed09eea3a64e70eb83852c3043f529a0ac53cdc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Mon, 21 Oct 2024 12:12:58 +0200 Subject: [PATCH 35/37] update --- .../main/java/org/eqasim/ile_de_france/RunSimulation.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java index 8c7273e1e..d67fbe2d7 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java @@ -1,6 +1,7 @@ package org.eqasim.ile_de_france; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -37,6 +38,8 @@ import org.matsim.vehicles.Vehicles; import org.matsim.vehicles.VehiclesFactory; +import com.google.common.base.Verify; + public class RunSimulation { static public void main(String[] args) throws ConfigurationException { CommandLine cmd = new CommandLine.Builder(args) // @@ -59,7 +62,10 @@ static public void main(String[] args) throws ConfigurationException { VDFEngineConfigGroup engineConfig = new VDFEngineConfigGroup(); engineConfig.setModes(Set.of("car", "car_passenger")); engineConfig.setGenerateNetworkEvents(false); - config.addModule(engineConfig); } + config.addModule(engineConfig); + + config.qsim().setMainModes(Collections.emptySet()); + } configurator.addOptionalConfigGroups(config); cmd.applyConfiguration(config); From a930864974cf78d9c619ea126312d40923e6e8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Wed, 23 Oct 2024 10:15:28 +0200 Subject: [PATCH 36/37] fix capacity factor --- .../src/main/java/org/eqasim/ile_de_france/RunSimulation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java index d67fbe2d7..ed0abbb14 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java @@ -56,7 +56,7 @@ static public void main(String[] args) throws ConfigurationException { VDFConfigGroup vdfConfig = new VDFConfigGroup(); config.addModule(vdfConfig); - vdfConfig.setCapacityFactor(eqasimConfig.getSampleSize()); + vdfConfig.setCapacityFactor(1.0); vdfConfig.setModes(Set.of("car", "car_passenger")); VDFEngineConfigGroup engineConfig = new VDFEngineConfigGroup(); From 30f0372cff8706da4c3c5fab6136ee7d24093a65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Sat, 2 Nov 2024 22:21:51 +0100 Subject: [PATCH 37/37] fix --- .../src/main/java/org/eqasim/ile_de_france/RunSimulation.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java b/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java index aac11f284..8c3f4ebb6 100644 --- a/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java +++ b/ile_de_france/src/main/java/org/eqasim/ile_de_france/RunSimulation.java @@ -41,9 +41,9 @@ static public void main(String[] args) throws ConfigurationException { engineConfig.setModes(Set.of("car", "car_passenger")); engineConfig.setGenerateNetworkEvents(false); config.addModule(engineConfig); - } - config.qsim().setMainModes(Collections.emptySet()); + config.qsim().setMainModes(Collections.emptySet()); + } } cmd.applyConfiguration(config);