diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 005f03a4b..8582a3001 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -11,8 +11,8 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: java-version: 21 architecture: x64 @@ -29,8 +29,8 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: java-version: 21 architecture: x64 @@ -54,8 +54,8 @@ jobs: java: [21] steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: java-version: ${{ matrix.java }} architecture: x64 @@ -64,7 +64,7 @@ jobs: - name: Test run: mvn --batch-mode --update-snapshots test -Dmatsim.preferLocalDtds=true -Dmaven.javadoc.skip -e - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: test-coverage path: target/site/jacoco/ @@ -77,8 +77,8 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: java-version: 21 architecture: x64 @@ -88,7 +88,7 @@ jobs: - name: Package run: mvn --batch-mode --update-snapshots package -DskipTests -Dmatsim.preferLocalDtds=true -Dmaven.javadoc.skip -e - run: mkdir staging && cp *.jar staging - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: Package path: staging diff --git a/pom.xml b/pom.xml index 0bf75f988..2a1a83a42 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ matsim-all - 2025.0-PR3636 + 2025.0-PR3642 diff --git a/src/main/java/org/matsim/run/policies/OpenBerlinChoiceExperiment.java b/src/main/java/org/matsim/run/policies/OpenBerlinChoiceExperiment.java index a123ffb34..2937235b4 100644 --- a/src/main/java/org/matsim/run/policies/OpenBerlinChoiceExperiment.java +++ b/src/main/java/org/matsim/run/policies/OpenBerlinChoiceExperiment.java @@ -10,6 +10,7 @@ import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.Controler; +import org.matsim.core.replanning.strategies.DefaultPlanStrategiesModule; import org.matsim.core.router.TripStructureUtils; import org.matsim.modechoice.InformedModeChoiceConfigGroup; import org.matsim.modechoice.InformedModeChoiceModule; @@ -18,11 +19,15 @@ import org.matsim.modechoice.estimators.DefaultActivityEstimator; import org.matsim.modechoice.estimators.DefaultLegScoreEstimator; import org.matsim.modechoice.estimators.FixedCostsEstimator; +import org.matsim.modechoice.pruning.PlanScoreThresholdPruner; import org.matsim.run.OpenBerlinScenario; import org.matsim.run.scoring.AdvancedScoringConfigGroup; +import org.matsim.run.scoring.PseudoRandomTripScoreEstimator; import org.matsim.vehicles.VehicleType; import picocli.CommandLine; +import java.util.List; + /** * This class can be used to run some synthetic mode choice experiments on the OpenBerlin scenario. */ @@ -34,6 +39,13 @@ public class OpenBerlinChoiceExperiment extends OpenBerlinScenario { @CommandLine.Option(names = "--imc", description = "Enable informed-mode-choice functionality") private boolean imc; + @CommandLine.Option(names = "--imc-pruning", description = "Plan pruning threshold. If 0 pruning is disabled", defaultValue = "0") + private double pruning; + + @CommandLine.Option(names = "--imc-strategy", description = "Mode choice strategy to use", + defaultValue = InformedModeChoiceModule.SELECT_SUBTOUR_MODE_STRATEGY) + private String strategy; + public static void main(String[] args) { MATSimApplication.execute(OpenBerlinChoiceExperiment.class, args); } @@ -47,19 +59,20 @@ protected Config prepareConfig(Config config) { InformedModeChoiceConfigGroup imcConfig = ConfigUtils.addOrGetModule(config, InformedModeChoiceConfigGroup.class); + imcConfig.setTopK(25); + imcConfig.setModes(List.of(config.subtourModeChoice().getModes())); imcConfig.setConstraintCheck(InformedModeChoiceConfigGroup.ConstraintCheck.repair); - // TODO: enable pruning - - // TODO: replace strategy - - // TODO: start imc runs - // from uncalibrated population with baseline calibration + InformedModeChoiceModule.replaceReplanningStrategy(config, "person", + DefaultPlanStrategiesModule.DefaultStrategy.SubtourModeChoice, + strategy + ); - // next, with new mode scoring - - // different number iterations x pruning thresholds/top k + if (pruning > 0) + imcConfig.setPruning("p" + pruning); + } else if (pruning > 0) { + throw new IllegalArgumentException("Pruning is only available with informed-mode-choice enabled"); } return config; @@ -102,15 +115,11 @@ protected void prepareControler(Controler controler) { .withFixedCosts(FixedCostsEstimator.DailyConstant.class, "car", "pt") .withLegEstimator(DefaultLegScoreEstimator.class, ModeOptions.ConsiderIfCarAvailable.class, "car") .withLegEstimator(DefaultLegScoreEstimator.class, ModeOptions.AlwaysAvailable.class, "pt", "walk", "bike", "ride") + .withPruner("p" + pruning, new PlanScoreThresholdPruner(pruning)) .withConstraint(RelaxedMassConservationConstraint.class); if (ConfigUtils.hasModule(controler.getConfig(), AdvancedScoringConfigGroup.class)) { - - // TODO: add pseudo random errors to estimator - // Implement pseudo trip scoring into informed mode choice - - // TODO: option for pruning - + builder.withTripScoreEstimator(PseudoRandomTripScoreEstimator.class); } controler.addOverridingModule(builder.build()); diff --git a/src/main/java/org/matsim/run/scoring/PseudoRandomTripScoreEstimator.java b/src/main/java/org/matsim/run/scoring/PseudoRandomTripScoreEstimator.java new file mode 100644 index 000000000..d2b370285 --- /dev/null +++ b/src/main/java/org/matsim/run/scoring/PseudoRandomTripScoreEstimator.java @@ -0,0 +1,24 @@ +package org.matsim.run.scoring; + +import com.google.inject.Inject; +import org.matsim.core.router.TripStructureUtils; +import org.matsim.modechoice.EstimatorContext; +import org.matsim.modechoice.estimators.TripScoreEstimator; + +/** + * Provides the pseudo random score to the estimator. + */ +public class PseudoRandomTripScoreEstimator implements TripScoreEstimator { + + private final PseudoRandomScorer scorer; + + @Inject + public PseudoRandomTripScoreEstimator(PseudoRandomScorer scorer) { + this.scorer = scorer; + } + + @Override + public double estimate(EstimatorContext context, String mainMode, TripStructureUtils.Trip trip) { + return scorer.scoreTrip(context.person.getId(), mainMode, trip); + } +}