From 2be0b7471ce4c424acfee6793de439f46557f72c Mon Sep 17 00:00:00 2001 From: Markus Straub Date: Tue, 14 Jan 2025 16:50:49 +0100 Subject: [PATCH] don't force subtourmodechoice remove the overly complex method to use subtourmodechoice together with drs. the permissiblemodescalculator alone is enough! --- README.md | 18 ++--- data/floridsdorf/config_drs.xml | 10 ++- data/vienna/config_drs.xml | 11 ++- prepare_config_for_drs.py | 14 +--- .../PermissibleModesCalculatorForDrs.java | 7 +- .../drs/engine/SubtourModeChoiceForDrs.java | 80 ------------------- .../ac/ait/matsim/drs/run/DrsConfigGroup.java | 75 ----------------- .../at/ac/ait/matsim/drs/run/DrsModule.java | 3 - .../drs/run/RunAdjacentMatchExample.java | 6 +- .../matsim/drs/run/RunNoDriverExample.java | 6 +- .../drs/run/RunPerfectMatchExample.java | 3 +- .../drs/run/RunTrivialMatchExample.java | 7 +- .../RunTrivialMatchWithReRouteExample.java | 7 +- 13 files changed, 47 insertions(+), 200 deletions(-) delete mode 100644 src/main/java/at/ac/ait/matsim/drs/engine/SubtourModeChoiceForDrs.java diff --git a/README.md b/README.md index b30c878..64e4fa9 100644 --- a/README.md +++ b/README.md @@ -57,8 +57,9 @@ In more detail, DRS is integrated into the MATSim loop as follows: ### Replanning -First the slightly adjusted innovation strategy `SubtourModeChoiceForDrs` assigns the new modes `drsDriver` and `drsRider` to agents' subtours. -This assignment can be restricted with the person attribute `drsAffinity`. +In case of using `SubtourModeChoice` replanning: +The drs modes must be added via the regular `SubtourModeChoice` config group. +Then `PermissibleModesCalculatorForDrs` takes care to remove drs for agents that don't want it using their `drsAffinity`. Then requests are collected and matched based on origin, destination, departure time and detour time. The riders' acceptance of deviations to their desired departure time can be controlled with the DRS config parameter `riderDepartureTimeAdjustmentSeconds`. @@ -156,10 +157,6 @@ List of all parameters: During the matching process, the arrival of driver to pick-up point is checked whether it is within the rider departure time +- the riderDepartureTimeAdjustment. -**Plan Innovation** - -- `subtourModeChoiceChainBasedModes`: Defines the chain-based modes for the `SubtourModeChoiceForDrs` strategy, separated by commas. -- `subtourModeChoiceModes`: Defines all modes available for the `SubtourModeChoiceForDrs` strategy, including chain-based modes, separated by commas. ### Run Example @@ -174,11 +171,12 @@ This should assure, that at the beginning of the simulation many drivers are pre (MATSim guarantees to try out / score all un-scored plans of an agent - see `RandomUnscoredPlanSelector` - before a different plan is selected e.g. via `SelectPlanExpBeta`). -### Mode Innovation +### Replanning / Mode Innovation + +#### SubtourModeChoice -Mode innovation relies on an adapted version of the innovation strategy `SubtourModeChoice` named `SubtourModeChoiceForDrs`. -`SubtourModeChoiceForDrs` will by default add the DRS driver and rider mode to the mix -and can also be configured via the relevant parameters in the `drs` config group. +The drs modes must be added via the regular `SubtourModeChoice` config group. +Then the `PermissibleModesCalculatorForDrs` takes care to remove drs for agents that don't want it using their `drsAffinity`. ### Output diff --git a/data/floridsdorf/config_drs.xml b/data/floridsdorf/config_drs.xml index 21c70f8..a6de885 100644 --- a/data/floridsdorf/config_drs.xml +++ b/data/floridsdorf/config_drs.xml @@ -164,16 +164,22 @@ - - + + + + + + + + diff --git a/data/vienna/config_drs.xml b/data/vienna/config_drs.xml index c98cfe0..386c65a 100644 --- a/data/vienna/config_drs.xml +++ b/data/vienna/config_drs.xml @@ -162,12 +162,17 @@ - - + + + + + + + @@ -186,6 +191,8 @@ + + diff --git a/prepare_config_for_drs.py b/prepare_config_for_drs.py index b5510f0..728424f 100644 --- a/prepare_config_for_drs.py +++ b/prepare_config_for_drs.py @@ -119,18 +119,10 @@ def adjust_replanning(tree: etree.ElementTree) -> None: "module[@name='replanning']/" "parameterset[@type='strategysettings' and param[@name='strategyName'] and param[@value='SubtourModeChoice']]" ) - logger.info( - f"replanning: changing {len(smc)} SubtourModeChoice strategies to SubtourModeChoiceForDrs" - ) - for p in smc: - p.find("param[@name='strategyName']").set("value", "SubtourModeChoiceForDrs") - - smc_for_drs = tree.xpath( - "module[@name='replanning']/" - "parameterset[@type='strategysettings' and param[@name='strategyName'] and param[@value='SubtourModeChoiceForDrs']]" + logger.info(f"replanning: using {len(smc)} SubtourModeChoice strategies") + logger.warning( + "TODO implement checking if drsDriver and drsRider are present to the subtourmodechoice config group" ) - if len(smc_for_drs) == 0: - logger.warning("replanning: no SubtourModeChoiceForDrs found") def adjust_routing(tree: etree.ElementTree) -> None: diff --git a/src/main/java/at/ac/ait/matsim/drs/engine/PermissibleModesCalculatorForDrs.java b/src/main/java/at/ac/ait/matsim/drs/engine/PermissibleModesCalculatorForDrs.java index 7ca10db..24092b0 100644 --- a/src/main/java/at/ac/ait/matsim/drs/engine/PermissibleModesCalculatorForDrs.java +++ b/src/main/java/at/ac/ait/matsim/drs/engine/PermissibleModesCalculatorForDrs.java @@ -17,13 +17,18 @@ import at.ac.ait.matsim.drs.run.Drs; import at.ac.ait.matsim.drs.util.DrsUtil; +/** + * Adds drs modes where applicable (see drsAffinity) in addition to the default + * modes. + * Mostly relevant for replanning with SubtourModeChoice. + */ public class PermissibleModesCalculatorForDrs implements PermissibleModesCalculator { private final Set availableModes; @Inject public PermissibleModesCalculatorForDrs(Config config) { - this.availableModes = ImmutableSet.copyOf(Drs.addOrGetConfigGroup(config).getSubtourModeChoiceModes()); + this.availableModes = ImmutableSet.copyOf(config.subtourModeChoice().getModes()); } @Override diff --git a/src/main/java/at/ac/ait/matsim/drs/engine/SubtourModeChoiceForDrs.java b/src/main/java/at/ac/ait/matsim/drs/engine/SubtourModeChoiceForDrs.java deleted file mode 100644 index 641342d..0000000 --- a/src/main/java/at/ac/ait/matsim/drs/engine/SubtourModeChoiceForDrs.java +++ /dev/null @@ -1,80 +0,0 @@ -package at.ac.ait.matsim.drs.engine; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.matsim.core.config.Config; -import org.matsim.core.gbl.MatsimRandom; -import org.matsim.core.population.algorithms.ChooseRandomLegModeForSubtour; -import org.matsim.core.population.algorithms.PermissibleModesCalculator; -import org.matsim.core.population.algorithms.PlanAlgorithm; -import org.matsim.core.replanning.PlanStrategy; -import org.matsim.core.replanning.PlanStrategyImpl; -import org.matsim.core.replanning.PlanStrategyImpl.Builder; -import org.matsim.core.replanning.modules.AbstractMultithreadedModule; -import org.matsim.core.replanning.modules.SubtourModeChoice; -import org.matsim.core.replanning.selectors.RandomPlanSelector; -import org.matsim.core.router.TripStructureUtils; - -import at.ac.ait.matsim.drs.run.Drs; -import at.ac.ait.matsim.drs.run.DrsConfigGroup; -import jakarta.inject.Inject; - -/** - * Based on {@link org.matsim.core.replanning.modules.SubtourModeChoice} - */ -public class SubtourModeChoiceForDrs extends AbstractMultithreadedModule { - - public static final String STRATEGY_NAME = "SubtourModeChoiceForDrs"; - - private final PermissibleModesCalculator permissibleModesCalculator; - private final String[] chainBasedModes; - private final String[] modes; - - public SubtourModeChoiceForDrs(Config config, - PermissibleModesCalculator permissibleModesCalculator) { - super(config.global().getNumberOfThreads()); - DrsConfigGroup drsConfig = Drs.addOrGetConfigGroup(config); - this.modes = drsConfig.getSubtourModeChoiceModes().clone(); - this.chainBasedModes = drsConfig.getSubtourModeChoiceChainBasedModes().clone(); - this.permissibleModesCalculator = permissibleModesCalculator; - } - - protected String[] getModes() { - return modes.clone(); - } - - @Override - public PlanAlgorithm getPlanAlgoInstance() { - SubtourModeChoice.Behavior behavior = SubtourModeChoice.Behavior.fromSpecifiedModesToSpecifiedModes; - double probaForChooseRandomSingleTripMode = 0; - ChooseRandomLegModeForSubtour chooseRandomLegMode = new ChooseRandomLegModeForSubtour( - TripStructureUtils.getRoutingModeIdentifier(), - this.permissibleModesCalculator, - this.modes, - this.chainBasedModes, - MatsimRandom.getLocalInstance(), - behavior, - probaForChooseRandomSingleTripMode); - return chooseRandomLegMode; - } - - public static class Provider implements jakarta.inject.Provider { - - private static final Logger LOGGER = LogManager.getLogger(); - - @Inject - private Config config; - @Inject - private PermissibleModesCalculator permissibleModesCalculator; - - @Override - public PlanStrategy get() { - LOGGER.info("Provider builds a new instance of {}", SubtourModeChoiceForDrs.STRATEGY_NAME); - PlanStrategyImpl.Builder builder = new Builder(new RandomPlanSelector<>()); - builder.addStrategyModule(new SubtourModeChoiceForDrs(config, permissibleModesCalculator)); - return builder.build(); - } - - } - -} diff --git a/src/main/java/at/ac/ait/matsim/drs/run/DrsConfigGroup.java b/src/main/java/at/ac/ait/matsim/drs/run/DrsConfigGroup.java index a036d6d..59efb0c 100644 --- a/src/main/java/at/ac/ait/matsim/drs/run/DrsConfigGroup.java +++ b/src/main/java/at/ac/ait/matsim/drs/run/DrsConfigGroup.java @@ -2,11 +2,7 @@ import java.util.Map; -import org.matsim.api.core.v01.TransportMode; import org.matsim.contrib.common.util.ReflectiveConfigGroupWithConfigurableParameterSets; -import org.matsim.core.utils.misc.StringUtils; - -import at.ac.ait.matsim.drs.engine.SubtourModeChoiceForDrs; public class DrsConfigGroup extends ReflectiveConfigGroupWithConfigurableParameterSets { @@ -33,14 +29,6 @@ public class DrsConfigGroup extends ReflectiveConfigGroupWithConfigurableParamet public static final String CAR_AND_DRS_DAILY_MONETARY_CONSTANT = "carAndDrsDailyMonetaryConstant"; private double carAndDrsDailyMonetaryConstant = 0; - public static final String SUBTOUR_MODE_CHOICE_MODES = "subtourModeChoiceModes"; - private String[] subtourModeChoiceModes = { TransportMode.car, Drs.DRIVER_MODE, Drs.RIDER_MODE, - TransportMode.pt, TransportMode.bike, TransportMode.walk }; - - public static final String SUBTOUR_MODE_CHOICE_CHAIN_BASED_MODES = "subtourModeChoiceChainBasedModes"; - private String[] subtourModeChoiceChainBasedModes = new String[] { TransportMode.car, Drs.DRIVER_MODE, - TransportMode.bike }; - public static final String MIN_DRIVER_LEG_METERS = "minDriverLegMeters"; private int minDriverLegMeters = 10; @@ -80,12 +68,6 @@ public Map getComments() { "Daily price for car usage including when using the private car as drsDriver. " + "If specified here do not additionaly specify it in planCalcScore.scoringParameters.modeParams.dailyMonetaryConstant - " + "otherwise it will be counted twice (typically negative)"); - map.put(SUBTOUR_MODE_CHOICE_MODES, - "Defines all modes available for the '" + SubtourModeChoiceForDrs.STRATEGY_NAME - + "' strategy, including chain-based modes, separated by commas"); - map.put(SUBTOUR_MODE_CHOICE_CHAIN_BASED_MODES, - "Defines the chain-based modes for the '" + SubtourModeChoiceForDrs.STRATEGY_NAME - + "' strategy, separated by commas"); map.put(MIN_DRIVER_LEG_METERS, "minimum length of legs (routed with the drsDriver mode) to be considered for the drs driver mode. 0 means no minimum."); map.put(MIN_RIDER_LEG_METERS, @@ -163,42 +145,6 @@ public void setCarAndDrsDailyMonetaryConstant(double carAndDrsDailyMonetaryConst this.carAndDrsDailyMonetaryConstant = carAndDrsDailyMonetaryConstant; } - public String[] getSubtourModeChoiceModes() { - return subtourModeChoiceModes; - } - - @StringGetter(SUBTOUR_MODE_CHOICE_MODES) - public String getSubtourModeChoiceModesString() { - return toString(subtourModeChoiceModes); - } - - public void setSubtourModeChoiceModes(String[] subtourModeChoiceModes) { - this.subtourModeChoiceModes = subtourModeChoiceModes; - } - - @StringSetter(SUBTOUR_MODE_CHOICE_MODES) - public void setSubtourModeChoiceModesString(String subtourModeChoiceModes) { - this.subtourModeChoiceModes = toArray(subtourModeChoiceModes); - } - - public String[] getSubtourModeChoiceChainBasedModes() { - return subtourModeChoiceChainBasedModes; - } - - @StringGetter(SUBTOUR_MODE_CHOICE_CHAIN_BASED_MODES) - public String getSubtourModeChoiceChainBasedModesString() { - return toString(subtourModeChoiceChainBasedModes); - } - - public void setSubtourModeChoiceChainBasedModes(String[] subtourModeChoiceChainBasedModes) { - this.subtourModeChoiceChainBasedModes = subtourModeChoiceChainBasedModes; - } - - @StringSetter(SUBTOUR_MODE_CHOICE_CHAIN_BASED_MODES) - public void setSubtourModeChoiceChainBasedModesString(String subtourModeChoiceChainBasedModes) { - this.subtourModeChoiceChainBasedModes = toArray(subtourModeChoiceChainBasedModes); - } - @StringGetter(MIN_DRIVER_LEG_METERS) public int getMinDriverLegMeters() { return minDriverLegMeters; @@ -219,25 +165,4 @@ public void setMinRiderLegMeters(int minRiderLegMeters) { this.minRiderLegMeters = minRiderLegMeters; } - /** copied from SubtourModeChoiceConfigGroup */ - private static String toString(final String[] modes) { - StringBuilder b = new StringBuilder(); - if (modes.length > 0) - b.append(modes[0]); - for (int i = 1; i < modes.length; i++) { - b.append(','); - b.append(modes[i]); - } - return b.toString(); - } - - /** copied from SubtourModeChoiceConfigGroup */ - private static String[] toArray(final String modes) { - String[] parts = StringUtils.explode(modes, ','); - for (int i = 0, n = parts.length; i < n; i++) { - parts[i] = parts[i].trim().intern(); - } - return parts; - } - } diff --git a/src/main/java/at/ac/ait/matsim/drs/run/DrsModule.java b/src/main/java/at/ac/ait/matsim/drs/run/DrsModule.java index 1e8cfd5..dfbe35e 100644 --- a/src/main/java/at/ac/ait/matsim/drs/run/DrsModule.java +++ b/src/main/java/at/ac/ait/matsim/drs/run/DrsModule.java @@ -14,7 +14,6 @@ import at.ac.ait.matsim.drs.engine.DrsReplanningListener; import at.ac.ait.matsim.drs.engine.PermissibleModesCalculatorForDrs; import at.ac.ait.matsim.drs.engine.PlanModificationUndoer; -import at.ac.ait.matsim.drs.engine.SubtourModeChoiceForDrs; import at.ac.ait.matsim.drs.engine.UnmatchedRiderConflictIdentifier; public final class DrsModule extends AbstractModule { @@ -34,8 +33,6 @@ public void install() { bind(DrsData.class).asEagerSingleton(); bind(PermissibleModesCalculator.class).to(PermissibleModesCalculatorForDrs.class); - addPlanStrategyBinding(SubtourModeChoiceForDrs.STRATEGY_NAME) - .toProvider(SubtourModeChoiceForDrs.Provider.class); installQSimModule(new DrsEngineQSimModule()); diff --git a/src/main/java/at/ac/ait/matsim/drs/run/RunAdjacentMatchExample.java b/src/main/java/at/ac/ait/matsim/drs/run/RunAdjacentMatchExample.java index 9781fbb..ffecd2c 100644 --- a/src/main/java/at/ac/ait/matsim/drs/run/RunAdjacentMatchExample.java +++ b/src/main/java/at/ac/ait/matsim/drs/run/RunAdjacentMatchExample.java @@ -26,11 +26,11 @@ public void adjustConfig(Config config) { // (so that we can demonstrate the match) config.replanning().clearStrategySettings(); config.replanning() - .addStrategySettings(new StrategySettings().setStrategyName("SubtourModeChoiceForDrs").setWeight(1)); + .addStrategySettings(new StrategySettings().setStrategyName("SubtourModeChoice").setWeight(1)); DrsConfigGroup drs = (DrsConfigGroup) config.getModules().get("drs"); - drs.setSubtourModeChoiceModes(new String[] { Drs.DRIVER_MODE, Drs.RIDER_MODE, TransportMode.bike }); - drs.setSubtourModeChoiceChainBasedModes(new String[] { Drs.DRIVER_MODE, TransportMode.bike }); + config.subtourModeChoice().setModes(new String[] { Drs.DRIVER_MODE, Drs.RIDER_MODE, TransportMode.bike }); + config.subtourModeChoice().setChainBasedModes(new String[] { Drs.DRIVER_MODE, TransportMode.bike }); } } diff --git a/src/main/java/at/ac/ait/matsim/drs/run/RunNoDriverExample.java b/src/main/java/at/ac/ait/matsim/drs/run/RunNoDriverExample.java index 2140ac0..3f582a2 100644 --- a/src/main/java/at/ac/ait/matsim/drs/run/RunNoDriverExample.java +++ b/src/main/java/at/ac/ait/matsim/drs/run/RunNoDriverExample.java @@ -24,11 +24,11 @@ public void adjustConfig(Config config) { // (so that we can demonstrate the unmatched rider problem) config.replanning().clearStrategySettings(); config.replanning() - .addStrategySettings(new StrategySettings().setStrategyName("SubtourModeChoiceForDrs").setWeight(1)); + .addStrategySettings(new StrategySettings().setStrategyName("SubtourModeChoice").setWeight(1)); DrsConfigGroup drs = (DrsConfigGroup) config.getModules().get("drs"); - drs.setSubtourModeChoiceModes(new String[] { Drs.RIDER_MODE, TransportMode.bike }); - drs.setSubtourModeChoiceChainBasedModes(new String[] { TransportMode.bike }); + config.subtourModeChoice().setModes(new String[] { Drs.RIDER_MODE, TransportMode.bike }); + config.subtourModeChoice().setChainBasedModes(new String[] { TransportMode.bike }); } } diff --git a/src/main/java/at/ac/ait/matsim/drs/run/RunPerfectMatchExample.java b/src/main/java/at/ac/ait/matsim/drs/run/RunPerfectMatchExample.java index 25cb33d..123fa92 100644 --- a/src/main/java/at/ac/ait/matsim/drs/run/RunPerfectMatchExample.java +++ b/src/main/java/at/ac/ait/matsim/drs/run/RunPerfectMatchExample.java @@ -17,10 +17,9 @@ public void adjustConfig(Config config) { config.controller().setLastIteration(100); config.controller().setOutputDirectory("output-floridsdorf-perfectMatch"); config.plans().setInputFile("population_drs_perfectMatch.xml"); + // just check if multi-threading breaks config.qsim().setNumberOfThreads(10); config.global().setNumberOfThreads(10); - - // DrsConfigGroup drs = (DrsConfigGroup) config.getModules().get("drs"); } } \ No newline at end of file diff --git a/src/main/java/at/ac/ait/matsim/drs/run/RunTrivialMatchExample.java b/src/main/java/at/ac/ait/matsim/drs/run/RunTrivialMatchExample.java index 80b44a2..7ccb285 100644 --- a/src/main/java/at/ac/ait/matsim/drs/run/RunTrivialMatchExample.java +++ b/src/main/java/at/ac/ait/matsim/drs/run/RunTrivialMatchExample.java @@ -24,11 +24,10 @@ public void adjustConfig(Config config) { // (so that we can demonstrate the perfect match) config.replanning().clearStrategySettings(); config.replanning() - .addStrategySettings(new StrategySettings().setStrategyName("SubtourModeChoiceForDrs").setWeight(1)); + .addStrategySettings(new StrategySettings().setStrategyName("SubtourModeChoice").setWeight(1)); - DrsConfigGroup drs = (DrsConfigGroup) config.getModules().get("drs"); - drs.setSubtourModeChoiceModes(new String[] { Drs.DRIVER_MODE, Drs.RIDER_MODE, TransportMode.bike }); - drs.setSubtourModeChoiceChainBasedModes(new String[] { Drs.DRIVER_MODE, TransportMode.bike }); + config.subtourModeChoice().setModes(new String[] { Drs.DRIVER_MODE, Drs.RIDER_MODE, TransportMode.bike }); + config.subtourModeChoice().setChainBasedModes(new String[] { Drs.DRIVER_MODE, TransportMode.bike }); } } diff --git a/src/main/java/at/ac/ait/matsim/drs/run/RunTrivialMatchWithReRouteExample.java b/src/main/java/at/ac/ait/matsim/drs/run/RunTrivialMatchWithReRouteExample.java index 55009d1..8761c0d 100644 --- a/src/main/java/at/ac/ait/matsim/drs/run/RunTrivialMatchWithReRouteExample.java +++ b/src/main/java/at/ac/ait/matsim/drs/run/RunTrivialMatchWithReRouteExample.java @@ -26,13 +26,12 @@ public void adjustConfig(Config config) { config.replanning() .addStrategySettings(new StrategySettings().setStrategyName("BestScore").setWeight(0.1)); config.replanning() - .addStrategySettings(new StrategySettings().setStrategyName("SubtourModeChoiceForDrs").setWeight(0.4)); + .addStrategySettings(new StrategySettings().setStrategyName("SubtourModeChoice").setWeight(0.4)); config.replanning() .addStrategySettings(new StrategySettings().setStrategyName("ReRoute").setWeight(0.5)); - DrsConfigGroup drs = (DrsConfigGroup) config.getModules().get("drs"); - drs.setSubtourModeChoiceModes(new String[] { Drs.DRIVER_MODE, Drs.RIDER_MODE, TransportMode.bike }); - drs.setSubtourModeChoiceChainBasedModes(new String[] { Drs.DRIVER_MODE, TransportMode.bike }); + config.subtourModeChoice().setModes(new String[] { Drs.DRIVER_MODE, Drs.RIDER_MODE, TransportMode.bike }); + config.subtourModeChoice().setChainBasedModes(new String[] { Drs.DRIVER_MODE, TransportMode.bike }); } }