From b433c3516530a6d646dba55c3a12f3ddad843eea Mon Sep 17 00:00:00 2001 From: rakow Date: Mon, 2 Sep 2024 14:50:48 +0200 Subject: [PATCH] add new plan generator based on subtour modechoice --- input/v6.3/params/baseline_v1.yaml | 11 ++++ .../prepare/choices/ComputePlanChoices.java | 14 ++++- .../prepare/choices/SubtourPlanGenerator.java | 53 +++++++++++++++++++ src/main/sh/runPlanChoices.sh | 6 ++- 4 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 input/v6.3/params/baseline_v1.yaml create mode 100644 src/main/java/org/matsim/prepare/choices/SubtourPlanGenerator.java diff --git a/input/v6.3/params/baseline_v1.yaml b/input/v6.3/params/baseline_v1.yaml new file mode 100644 index 00000000..38bb67b5 --- /dev/null +++ b/input/v6.3/params/baseline_v1.yaml @@ -0,0 +1,11 @@ +scoring: + scoringParameters: + - performing: 7.547802 + modeParams: + - mode: walk + constant: 0 + - mode: car + constant: 0 + dailyMonetaryConstant: -5.1038273 +advancedScoring: + incomeExponent: 0.549347 \ No newline at end of file diff --git a/src/main/java/org/matsim/prepare/choices/ComputePlanChoices.java b/src/main/java/org/matsim/prepare/choices/ComputePlanChoices.java index b347d94c..19a5b59c 100644 --- a/src/main/java/org/matsim/prepare/choices/ComputePlanChoices.java +++ b/src/main/java/org/matsim/prepare/choices/ComputePlanChoices.java @@ -20,6 +20,7 @@ import org.matsim.core.controler.OutputDirectoryHierarchy; import org.matsim.core.population.PersonUtils; import org.matsim.core.population.algorithms.ParallelPersonAlgorithmUtils; +import org.matsim.core.population.algorithms.PermissibleModesCalculator; import org.matsim.core.population.algorithms.PersonAlgorithm; import org.matsim.core.router.*; import org.matsim.core.utils.timing.TimeInterpretation; @@ -37,6 +38,7 @@ import java.nio.file.Path; import java.util.*; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Pattern; @@ -84,6 +86,10 @@ public class ComputePlanChoices implements MATSimAppCommand, PersonAlgorithm { private ThreadLocal thread; private ProgressBar pb; private double globalAvgIncome; + /** + * Maximum numbers of plan options generated. + */ + private AtomicInteger maxK = new AtomicInteger(0); public static void main(String[] args) { new ComputePlanChoices().execute(args); @@ -160,6 +166,9 @@ public Integer call() throws Exception { case diverse -> new DiversePlanGenerator(topK, injector.getInstance(TopKChoicesGenerator.class)); case random -> new RandomPlanGenerator(topK, injector.getInstance(TopKChoicesGenerator.class)); case carAlternative -> new ExclusiveCarPlanGenerator(injector.getInstance(TopKChoicesGenerator.class)); + case subtour -> new SubtourPlanGenerator(topK, injector.getInstance(TopKChoicesGenerator.class), + injector.getInstance(PermissibleModesCalculator.class), + config); }, calcScores ? new PseudoScorer(injector, population) : null ) @@ -211,6 +220,7 @@ public Integer call() throws Exception { } csv.printComment("Average global income: " + globalAvgIncome); + csv.printComment("Max number of plan options: " + maxK.get()); csv.printRecord(header); @@ -299,6 +309,8 @@ public void run(Person person) { i++; } + maxK.accumulateAndGet(i, Math::max); + for (int j = i; j < topK; j++) { row.addAll(convert(null, ctx.scorer)); // not available @@ -384,7 +396,7 @@ private Map collect(Plan plan) { * Define how candidates are generated. */ public enum PlanCandidates { - bestK, diverse, random, carAlternative + bestK, diverse, random, carAlternative, subtour } private record ModeStats(int usage, double travelTime, double travelDistance, double rideTime, long numSwitches) { diff --git a/src/main/java/org/matsim/prepare/choices/SubtourPlanGenerator.java b/src/main/java/org/matsim/prepare/choices/SubtourPlanGenerator.java new file mode 100644 index 00000000..7d034585 --- /dev/null +++ b/src/main/java/org/matsim/prepare/choices/SubtourPlanGenerator.java @@ -0,0 +1,53 @@ +package org.matsim.prepare.choices; + + +import org.jetbrains.annotations.Nullable; +import org.matsim.api.core.v01.population.Plan; +import org.matsim.core.config.Config; +import org.matsim.core.population.algorithms.PermissibleModesCalculator; +import org.matsim.core.population.algorithms.PlanAlgorithm; +import org.matsim.core.replanning.modules.SubtourModeChoice; +import org.matsim.modechoice.CandidateGenerator; +import org.matsim.modechoice.PlanCandidate; +import org.matsim.modechoice.PlanModel; +import org.matsim.modechoice.search.TopKChoicesGenerator; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * Uses the subtour mutator to generate plans. + */ +public class SubtourPlanGenerator implements CandidateGenerator { + + private final int k; + private final SubtourModeChoice modeChoice; + private final PlanAlgorithm algo; + private final TopKChoicesGenerator gen; + + public SubtourPlanGenerator(int k, TopKChoicesGenerator generator, PermissibleModesCalculator permissibleModesCalculator, Config config) { + this.k = k; + this.modeChoice = new SubtourModeChoice(config.global(), config.subtourModeChoice(), permissibleModesCalculator); + this.algo = modeChoice.getPlanAlgoInstance(); + this.gen = generator; + } + + @Override + public List generate(PlanModel planModel, @Nullable Set set, @Nullable boolean[] booleans) { + + List result = new ArrayList<>(); + result.add(planModel.getCurrentModes()); + + for (int i = 0; i < k; i++) { + Plan plan = planModel.getPlan(); + algo.run(plan); + + PlanModel updated = PlanModel.newInstance(plan); + result.add(updated.getCurrentModesMutable()); + } + + return gen.generatePredefined(planModel, result) + .stream().distinct().toList(); + } +} diff --git a/src/main/sh/runPlanChoices.sh b/src/main/sh/runPlanChoices.sh index b575c2d1..a2992a67 100755 --- a/src/main/sh/runPlanChoices.sh +++ b/src/main/sh/runPlanChoices.sh @@ -22,5 +22,7 @@ run_eval() { #run_eval "--plan-candidates random --top-k 3" #run_eval "--plan-candidates random --top-k 5" #run_eval "--plan-candidates random --top-k 9" -run_eval "--plan-candidates diverse --top-k 9" -run_eval "--plan-candidates diverse --top-k 9 --time-util-only" \ No newline at end of file +#run_eval "--plan-candidates diverse --top-k 9" +#run_eval "--plan-candidates diverse --top-k 9 --time-util-only" + +run_eval "--plan-candidates subtour --top-k 70" \ No newline at end of file