From ecbfc4154fa020696d8713850d16a73603f8bc0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Thu, 11 Sep 2025 15:26:48 +0200 Subject: [PATCH 1/9] First changes to mode choice Bavaria --- .../org/eqasim/bavaria/RunSimulation.java | 8 ++++ .../parameters/BavariaModeParameters.java | 28 +++++++++--- .../BavariaCarUtilityEstimator.java | 14 +++++- .../estimators/BavariaPtUtilityEstimator.java | 3 ++ .../BavariaWalkUtilityEstimator.java | 45 +++++++++++++++++++ .../predictors/BavariaPersonPredictor.java | 3 +- .../variables/BavariaPersonVariables.java | 4 +- .../bavaria/scenario/RunAdaptConfig.java | 3 ++ 8 files changed, 99 insertions(+), 9 deletions(-) create mode 100644 bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaWalkUtilityEstimator.java diff --git a/bavaria/src/main/java/org/eqasim/bavaria/RunSimulation.java b/bavaria/src/main/java/org/eqasim/bavaria/RunSimulation.java index 53580d400..a9ef7d220 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/RunSimulation.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/RunSimulation.java @@ -3,6 +3,8 @@ import java.util.Collections; import java.util.Set; +import org.eqasim.bavaria.mode_choice.BavariaModeChoiceModule; +import org.eqasim.core.components.config.EqasimConfigGroup; import org.eqasim.core.scenario.validation.VehiclesValidator; import org.eqasim.core.simulation.vdf.VDFConfigGroup; import org.eqasim.core.simulation.vdf.engine.VDFEngineConfigGroup; @@ -48,6 +50,12 @@ static public void main(String[] args) throws ConfigurationException { cmd.applyConfiguration(config); VehiclesValidator.validate(config); + EqasimConfigGroup eqasimConfig = EqasimConfigGroup.get(config); + if (!eqasimConfig.getEstimators().get("walk").equals(BavariaModeChoiceModule.WALK_ESTIMATOR_NAME)) { + throw new IllegalArgumentException( + "Config needs to be use bavariaWalk for mode choice. Please define BavariaWalkUtilityEstimator in estimators for mode walk."); + } + Scenario scenario = ScenarioUtils.createScenario(config); configurator.configureScenario(scenario); ScenarioUtils.loadScenario(scenario); diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/parameters/BavariaModeParameters.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/parameters/BavariaModeParameters.java index 1af560e5e..03129d7a7 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/parameters/BavariaModeParameters.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/parameters/BavariaModeParameters.java @@ -3,6 +3,21 @@ import org.eqasim.core.simulation.mode_choice.parameters.ModeParameters; public class BavariaModeParameters extends ModeParameters { + + + public class BavariaPtParameters { + public double betaDrivingPermit_u; + public double onlyBus_u; + } + + public class BavariaCarParameters { + public double isHighIncome; + } + + public class BavariaWalkParameters { + public double isHighIncome; + } + public class BavariaCarPassengerParameters { public double alpha_u; public double betaInVehicleTravelTime_u_min; @@ -11,13 +26,12 @@ public class BavariaCarPassengerParameters { public final BavariaCarPassengerParameters carPassenger = new BavariaCarPassengerParameters(); - public class BavariaPtParameters { - public double betaDrivingPermit_u; - public double onlyBus_u; - } - public final BavariaPtParameters bavariaPt = new BavariaPtParameters(); + public final BavariaCarParameters bavariaCar = new BavariaCarParameters(); + + public final BavariaWalkParameters bavariaWalk = new BavariaWalkParameters(); + public double betaAccessTime_u_min; public static BavariaModeParameters buildDefault() { @@ -28,12 +42,13 @@ public static BavariaModeParameters buildDefault() { // Cost parameters.betaCost_u_MU = -0.310998; - parameters.lambdaCostEuclideanDistance = -0.257501; + parameters.lambdaCostEuclideanDistance = 0.0; //-0.257501; parameters.referenceEuclideanDistance_km = 4.4; // Car parameters.car.alpha_u = 0.4; // -0.201465; parameters.car.betaTravelTime_u_min = -0.042431; + parameters.bavariaCar.isHighIncome = -0.0225; // Car passenger parameters.carPassenger.alpha_u = -1.4; // -1.713201; @@ -56,6 +71,7 @@ public static BavariaModeParameters buildDefault() { // Walk parameters.walk.alpha_u = 1.8; // 1.685152; parameters.walk.betaTravelTime_u_min = -0.162285; + parameters.bavariaWalk.isHighIncome = -0.0217; return parameters; } diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaCarUtilityEstimator.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaCarUtilityEstimator.java index 81dcbbc0d..8a413b746 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaCarUtilityEstimator.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaCarUtilityEstimator.java @@ -3,9 +3,12 @@ import java.util.List; import org.eqasim.bavaria.mode_choice.parameters.BavariaModeParameters; +import org.eqasim.bavaria.mode_choice.utilities.predictors.BavariaPersonPredictor; +import org.eqasim.bavaria.mode_choice.utilities.variables.BavariaPersonVariables; 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.core.simulation.mode_choice.utilities.variables.PersonVariables; 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,22 +18,30 @@ public class BavariaCarUtilityEstimator extends CarUtilityEstimator { private final BavariaModeParameters parameters; private final CarPredictor predictor; + private final BavariaPersonPredictor personPredictor; @Inject - public BavariaCarUtilityEstimator(BavariaModeParameters parameters, CarPredictor predictor) { + public BavariaCarUtilityEstimator(BavariaModeParameters parameters, CarPredictor predictor, BavariaPersonPredictor personPredictor) { super(parameters, predictor); this.parameters = parameters; this.predictor = predictor; + this.personPredictor = personPredictor; } protected double estimateAccessEgressTimeUtility(CarVariables variables) { return parameters.betaAccessTime_u_min * variables.accessEgressTime_min; } + protected double estimateHighIncomeUtility(BavariaPersonVariables variables) { + return variables.isHighIncome ? parameters.bavariaCar.isHighIncome : 0.0; + } + + @Override public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List elements) { CarVariables variables = predictor.predictVariables(person, trip, elements); + BavariaPersonVariables personVariables = personPredictor.predictVariables(person, trip, elements); double utility = 0.0; @@ -38,6 +49,7 @@ public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List elements) { + BavariaPersonVariables personVariables = personPredictor.predictVariables(person, trip, elements); + + double utility = 0.0; + + utility += super.estimateUtility(person, trip, elements); + utility += estimateHighIncomeUtility(personVariables); + + return utility; + } +} diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/predictors/BavariaPersonPredictor.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/predictors/BavariaPersonPredictor.java index 9cc79208f..70875e1a6 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/predictors/BavariaPersonPredictor.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/predictors/BavariaPersonPredictor.java @@ -14,6 +14,7 @@ protected BavariaPersonVariables predict(Person person, DiscreteModeChoiceTrip t List elements) { boolean hasSubscription = BavariaPredictorUtils.hasSubscription(person); boolean hasDrivingPermit = BavariaPredictorUtils.hasDrivingLicense(person); - return new BavariaPersonVariables(hasSubscription, hasDrivingPermit); + boolean isHighIncome = BavariaPredictorUtils.isHighIncome(person); + return new BavariaPersonVariables(hasSubscription, hasDrivingPermit, isHighIncome); } } diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/variables/BavariaPersonVariables.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/variables/BavariaPersonVariables.java index 1608b1662..3e5e243df 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/variables/BavariaPersonVariables.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/variables/BavariaPersonVariables.java @@ -5,9 +5,11 @@ public class BavariaPersonVariables implements BaseVariables { public final boolean hasSubscription; public final boolean hasDrivingPermit; + public final boolean isHighIncome; - public BavariaPersonVariables(boolean hasSubscription, boolean hasDrivingPermit) { + public BavariaPersonVariables(boolean hasSubscription, boolean hasDrivingPermit, boolean isHighIncome) { this.hasSubscription = hasSubscription; this.hasDrivingPermit = hasDrivingPermit; + this.isHighIncome = isHighIncome; } } diff --git a/bavaria/src/main/java/org/eqasim/bavaria/scenario/RunAdaptConfig.java b/bavaria/src/main/java/org/eqasim/bavaria/scenario/RunAdaptConfig.java index e42f42552..40a316ff5 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/scenario/RunAdaptConfig.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/scenario/RunAdaptConfig.java @@ -63,8 +63,11 @@ static public void adaptConfiguration(Config config, String prefix) { eqasimConfig.setEstimator(TransportMode.car, BavariaModeChoiceModule.CAR_ESTIMATOR_NAME); eqasimConfig.setEstimator(TransportMode.pt, BavariaModeChoiceModule.PT_ESTIMATOR_NAME); + eqasimConfig.setEstimator(BavariaModeChoiceModule.BICYCLE, BavariaModeChoiceModule.BICYCLE_ESTIMATOR_NAME); eqasimConfig.setEstimator(BavariaModeChoiceModule.CAR_PASSENGER, BavariaModeChoiceModule.CAR_PASSENGER_ESTIMATOR_NAME); + eqasimConfig.setEstimator(TransportMode.walk, BavariaModeChoiceModule.WALK_ESTIMATOR_NAME); + eqasimConfig.removeEstimator(TransportMode.bike); // Discrete mode choice From ae6b15fac30897b914c0fd9e1e1915005091d244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Mon, 15 Sep 2025 16:20:41 +0200 Subject: [PATCH 2/9] Additional changes to mode choice Bavaria --- .../parameters/BavariaModeParameters.java | 87 ++++++++++++++----- .../BavariaBicycleUtilityEstimator.java | 12 +++ .../BavariaCarPassengerUtilityEstimator.java | 11 ++- .../estimators/BavariaPtUtilityEstimator.java | 40 +++++++-- .../predictors/BavariaPredictorUtils.java | 10 +++ 5 files changed, 128 insertions(+), 32 deletions(-) diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/parameters/BavariaModeParameters.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/parameters/BavariaModeParameters.java index 03129d7a7..ea30719d1 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/parameters/BavariaModeParameters.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/parameters/BavariaModeParameters.java @@ -4,34 +4,55 @@ public class BavariaModeParameters extends ModeParameters { - - public class BavariaPtParameters { - public double betaDrivingPermit_u; - public double onlyBus_u; + public class BavariaWalkParameters { + public double isHighIncome; + public double hasDrivingPermit; + public double hasPtSubscription; + public double isMunichResident; } - public class BavariaCarParameters { + public class BavariaBicycleParameters { public double isHighIncome; } - - public class BavariaWalkParameters { + + public class BavariaCarParameters { public double isHighIncome; + public double hasPtSubscription; + public double isWorkTrip; + public double isShoppingTrip; } public class BavariaCarPassengerParameters { public double alpha_u; public double betaInVehicleTravelTime_u_min; public double betaDrivingPermit_u; + public double isHighIncome; + public double isWorkTrip; + public double isShoppingTrip; + } + + public class BavariaPtParameters { + public double betaDrivingPermit_u; + public double onlyBus_u; + public double isHighIncome; + public double waitingTimeHighIncome; + public double waitingTimeMunichResident; + public double waitingTimeSubscription; + public double isWorkTrip; + public double isShoppingTrip; } - public final BavariaCarPassengerParameters carPassenger = new BavariaCarPassengerParameters(); + public final BavariaWalkParameters bavariaWalk = new BavariaWalkParameters(); - public final BavariaPtParameters bavariaPt = new BavariaPtParameters(); + public final BavariaBicycleParameters bavariaBicycle = new BavariaBicycleParameters(); public final BavariaCarParameters bavariaCar = new BavariaCarParameters(); - public final BavariaWalkParameters bavariaWalk = new BavariaWalkParameters(); + public final BavariaCarPassengerParameters bavariaCarPassenger = new BavariaCarPassengerParameters(); + public final BavariaPtParameters bavariaPt = new BavariaPtParameters(); + + public double betaAccessTime_u_min; public static BavariaModeParameters buildDefault() { @@ -45,16 +66,40 @@ public static BavariaModeParameters buildDefault() { parameters.lambdaCostEuclideanDistance = 0.0; //-0.257501; parameters.referenceEuclideanDistance_km = 4.4; + + + // Walk + parameters.walk.alpha_u = 1.8; // 1.685152; + parameters.walk.betaTravelTime_u_min = -0.162285; + parameters.bavariaWalk.isHighIncome = -0.0217; + parameters.bavariaWalk.hasDrivingPermit = -0.0319; + parameters.bavariaWalk.hasPtSubscription = 0.0175; + parameters.bavariaWalk.isMunichResident = 0.0106; + + + // Bicycle + parameters.bike.alpha_u = -0.5; // -2.927596; + parameters.bike.betaTravelTime_u_min = -0.093485; + parameters.bavariaBicycle.isHighIncome = -0.0255; + + // Car parameters.car.alpha_u = 0.4; // -0.201465; parameters.car.betaTravelTime_u_min = -0.042431; parameters.bavariaCar.isHighIncome = -0.0225; + parameters.bavariaCar.hasPtSubscription = -0.0540; + parameters.bavariaCar.isWorkTrip = 0.0682; + parameters.bavariaCar.isShoppingTrip = 0.0682; // Car passenger - parameters.carPassenger.alpha_u = -1.4; // -1.713201; - parameters.carPassenger.betaDrivingPermit_u = -0.835542; - parameters.carPassenger.betaInVehicleTravelTime_u_min = -0.069976; - + parameters.bavariaCarPassenger.alpha_u = -1.4; // -1.713201; + parameters.bavariaCarPassenger.betaDrivingPermit_u = -0.835542; + parameters.bavariaCarPassenger.betaInVehicleTravelTime_u_min = -0.069976; + parameters.bavariaCarPassenger.isHighIncome = -0.0398; + parameters.bavariaCarPassenger.isWorkTrip = 0.0210; + parameters.bavariaCarPassenger.isShoppingTrip = 0.0508; + + // PT parameters.pt.alpha_u = 0.0; parameters.pt.betaLineSwitch_u = -0.417658; @@ -63,15 +108,13 @@ public static BavariaModeParameters buildDefault() { parameters.bavariaPt.betaDrivingPermit_u = -0.531426; parameters.bavariaPt.onlyBus_u = -1.416309; + parameters.bavariaPt.isHighIncome = -0.0174; + parameters.bavariaPt.isWorkTrip = 0.0426; + parameters.bavariaPt.isShoppingTrip = 0.0441; + parameters.bavariaPt.waitingTimeHighIncome = -0.1530; + parameters.bavariaPt.waitingTimeMunichResident = 0.0991; + parameters.bavariaPt.waitingTimeSubscription = 0.4132; - // Bike - parameters.bike.alpha_u = -0.5; // -2.927596; - parameters.bike.betaTravelTime_u_min = -0.093485; - - // Walk - parameters.walk.alpha_u = 1.8; // 1.685152; - parameters.walk.betaTravelTime_u_min = -0.162285; - parameters.bavariaWalk.isHighIncome = -0.0217; return parameters; } diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaBicycleUtilityEstimator.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaBicycleUtilityEstimator.java index bc13c74fc..d741b99d2 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaBicycleUtilityEstimator.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaBicycleUtilityEstimator.java @@ -3,6 +3,8 @@ import java.util.List; import org.eqasim.bavaria.mode_choice.parameters.BavariaModeParameters; +import org.eqasim.bavaria.mode_choice.utilities.predictors.BavariaPersonPredictor; +import org.eqasim.bavaria.mode_choice.utilities.variables.BavariaPersonVariables; 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; @@ -15,23 +17,33 @@ public class BavariaBicycleUtilityEstimator extends BikeUtilityEstimator { private final BavariaModeParameters parameters; + private final BavariaPersonPredictor personPredictor; @Inject public BavariaBicycleUtilityEstimator(BavariaModeParameters parameters, PersonPredictor personPredictor, BikePredictor predictor) { super(parameters, personPredictor, predictor); this.parameters = parameters; + //this.personPredictor = personPredictor; + this.personPredictor = new BavariaPersonPredictor(); } protected double estimateAccessEgressTimeUtility(CarVariables variables) { return parameters.betaAccessTime_u_min * variables.accessEgressTime_min; } + protected double estimateHighIncomeUtility(BavariaPersonVariables variables) { + return variables.isHighIncome ? parameters.bavariaBicycle.isHighIncome : 0.0; + } + @Override public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List elements) { + BavariaPersonVariables personVariables = personPredictor.predictVariables(person, trip, elements); + double utility = 0.0; utility += super.estimateUtility(person, trip, elements); + utility += estimateHighIncomeUtility(personVariables); return utility; } diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaCarPassengerUtilityEstimator.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaCarPassengerUtilityEstimator.java index f826705c9..4e8198168 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaCarPassengerUtilityEstimator.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaCarPassengerUtilityEstimator.java @@ -28,11 +28,11 @@ public BavariaCarPassengerUtilityEstimator(BavariaModeParameters parameters, Bav } protected double estimateConstantUtility() { - return parameters.carPassenger.alpha_u; + return parameters.bavariaCarPassenger.alpha_u; } protected double estimateTravelTimeUtility(BavariaCarPassengerVariables variables) { - return parameters.carPassenger.betaInVehicleTravelTime_u_min * variables.travelTime_min; + return parameters.bavariaCarPassenger.betaInVehicleTravelTime_u_min * variables.travelTime_min; } protected double estimateAccessEgressTimeUtility(BavariaCarPassengerVariables variables) { @@ -40,7 +40,11 @@ protected double estimateAccessEgressTimeUtility(BavariaCarPassengerVariables va } protected double estimateDrivingPermit(BavariaPersonVariables variables) { - return variables.hasDrivingPermit ? parameters.carPassenger.betaDrivingPermit_u : 0.0; + return variables.hasDrivingPermit ? parameters.bavariaCarPassenger.betaDrivingPermit_u : 0.0; + } + + protected double estimaleHighIncomeUtility(BavariaPersonVariables variables) { + return variables.isHighIncome ? parameters.bavariaCarPassenger.isHighIncome : 0.0; } @Override @@ -54,6 +58,7 @@ public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List Date: Tue, 16 Sep 2025 14:40:09 +0200 Subject: [PATCH 3/9] Final changes to mode choice Bavaria draft 1 --- .../utilities/estimators/BavariaBicycleUtilityEstimator.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaBicycleUtilityEstimator.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaBicycleUtilityEstimator.java index d741b99d2..3eeafb89e 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaBicycleUtilityEstimator.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaBicycleUtilityEstimator.java @@ -17,15 +17,14 @@ public class BavariaBicycleUtilityEstimator extends BikeUtilityEstimator { private final BavariaModeParameters parameters; - private final BavariaPersonPredictor personPredictor; + //private final BavariaPersonPredictor personPredictor; @Inject public BavariaBicycleUtilityEstimator(BavariaModeParameters parameters, PersonPredictor personPredictor, BikePredictor predictor) { super(parameters, personPredictor, predictor); this.parameters = parameters; - //this.personPredictor = personPredictor; - this.personPredictor = new BavariaPersonPredictor(); + ///this.personPredictor = personPredictor; } protected double estimateAccessEgressTimeUtility(CarVariables variables) { From c3b71a106284ccad42af388e2bbe6d66c029f93b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Wed, 17 Sep 2025 08:59:28 +0200 Subject: [PATCH 4/9] Precision and correction of mode parameters --- .../org/eqasim/bavaria/RunSimulation.java | 4 +- .../mode_choice/BavariaModeChoiceModule.java | 14 ++-- .../parameters/BavariaModeParameters.java | 75 ++++++++++--------- .../BavariaBicycleUtilityEstimator.java | 8 +- .../BavariaCarPassengerUtilityEstimator.java | 10 +++ .../BavariaCarUtilityEstimator.java | 18 ++++- .../BavariaWalkUtilityEstimator.java | 15 +++- .../predictors/BavariaPersonPredictor.java | 3 +- .../variables/BavariaPersonVariables.java | 4 +- 9 files changed, 98 insertions(+), 53 deletions(-) diff --git a/bavaria/src/main/java/org/eqasim/bavaria/RunSimulation.java b/bavaria/src/main/java/org/eqasim/bavaria/RunSimulation.java index a9ef7d220..3d5bc539f 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/RunSimulation.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/RunSimulation.java @@ -53,8 +53,8 @@ static public void main(String[] args) throws ConfigurationException { EqasimConfigGroup eqasimConfig = EqasimConfigGroup.get(config); if (!eqasimConfig.getEstimators().get("walk").equals(BavariaModeChoiceModule.WALK_ESTIMATOR_NAME)) { throw new IllegalArgumentException( - "Config needs to be use bavariaWalk for mode choice. Please define BavariaWalkUtilityEstimator in estimators for mode walk."); - } + "Config needs to use bavariaWalk for mode choice. Please define BavariaWalkUtilityEstimator in estimators for mode walk."); + } Scenario scenario = ScenarioUtils.createScenario(config); configurator.configureScenario(scenario); diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/BavariaModeChoiceModule.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/BavariaModeChoiceModule.java index ef2bc12f5..ac386ee81 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/BavariaModeChoiceModule.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/BavariaModeChoiceModule.java @@ -4,12 +4,6 @@ import java.io.IOException; import java.util.List; -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.parameters.ModeParameters; -import org.eqasim.core.simulation.mode_choice.tour_finder.ActivityTourFinderWithExcludedActivities; -import org.eqasim.core.simulation.mode_choice.utilities.estimators.BikeUtilityEstimator; import org.eqasim.bavaria.mode_choice.costs.BavariaCarCostModel; import org.eqasim.bavaria.mode_choice.costs.BavariaPtCostModel; import org.eqasim.bavaria.mode_choice.parameters.BavariaCostParameters; @@ -18,9 +12,15 @@ import org.eqasim.bavaria.mode_choice.utilities.estimators.BavariaCarPassengerUtilityEstimator; import org.eqasim.bavaria.mode_choice.utilities.estimators.BavariaCarUtilityEstimator; import org.eqasim.bavaria.mode_choice.utilities.estimators.BavariaPtUtilityEstimator; +import org.eqasim.bavaria.mode_choice.utilities.estimators.BavariaWalkUtilityEstimator; import org.eqasim.bavaria.mode_choice.utilities.predictors.BavariaCarPassengerPredictor; import org.eqasim.bavaria.mode_choice.utilities.predictors.BavariaPersonPredictor; import org.eqasim.bavaria.mode_choice.utilities.predictors.BavariaPtPredictor; +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.parameters.ModeParameters; +import org.eqasim.core.simulation.mode_choice.tour_finder.ActivityTourFinderWithExcludedActivities; 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; @@ -42,6 +42,7 @@ public class BavariaModeChoiceModule extends AbstractEqasimExtension { public static final String CAR_PASSENGER_ESTIMATOR_NAME = "BavariaCarPassengerUtilityEstimator"; public static final String BICYCLE_ESTIMATOR_NAME = "BavariaBicycleUtilityEstimator"; public static final String PT_ESTIMATOR_NAME = "BavariaPtUtilityEstimator"; + public static final String WALK_ESTIMATOR_NAME = "BavariaWalkUtilityEstimator"; static public final String CAR_PASSENGER = "car_passenger"; static public final String BICYCLE = "bicycle"; @@ -67,6 +68,7 @@ protected void installEqasimExtension() { bindUtilityEstimator(BICYCLE_ESTIMATOR_NAME).to(BavariaBicycleUtilityEstimator.class); bindUtilityEstimator(CAR_PASSENGER_ESTIMATOR_NAME).to(BavariaCarPassengerUtilityEstimator.class); bindUtilityEstimator(PT_ESTIMATOR_NAME).to(BavariaPtUtilityEstimator.class); + bindUtilityEstimator(WALK_ESTIMATOR_NAME).to(BavariaWalkUtilityEstimator.class); bind(ModeParameters.class).to(BavariaModeParameters.class); diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/parameters/BavariaModeParameters.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/parameters/BavariaModeParameters.java index ea30719d1..8fb74c402 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/parameters/BavariaModeParameters.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/parameters/BavariaModeParameters.java @@ -38,6 +38,7 @@ public class BavariaPtParameters { public double waitingTimeHighIncome; public double waitingTimeMunichResident; public double waitingTimeSubscription; + public double waitingTimeShopping; public double isWorkTrip; public double isShoppingTrip; } @@ -59,61 +60,63 @@ public static BavariaModeParameters buildDefault() { BavariaModeParameters parameters = new BavariaModeParameters(); // Access - parameters.betaAccessTime_u_min = -0.031239; + // not specifically estimated for Bavaria, using values from walk.betaTravelTime_u_min + parameters.betaAccessTime_u_min = -0.0450421005231951; // -0.031239; // Cost - parameters.betaCost_u_MU = -0.310998; + parameters.betaCost_u_MU = -0.0448921788117033; // -0.310998; parameters.lambdaCostEuclideanDistance = 0.0; //-0.257501; parameters.referenceEuclideanDistance_km = 4.4; // Walk - parameters.walk.alpha_u = 1.8; // 1.685152; - parameters.walk.betaTravelTime_u_min = -0.162285; - parameters.bavariaWalk.isHighIncome = -0.0217; - parameters.bavariaWalk.hasDrivingPermit = -0.0319; - parameters.bavariaWalk.hasPtSubscription = 0.0175; - parameters.bavariaWalk.isMunichResident = 0.0106; + parameters.walk.alpha_u = 0.774228551231712; // 1.685152; + parameters.walk.betaTravelTime_u_min = -0.0695442805909274; // -0.162285; + parameters.bavariaWalk.isHighIncome = -0.0217295300225373; + parameters.bavariaWalk.hasDrivingPermit = -0.0318551303397705; + parameters.bavariaWalk.hasPtSubscription = 0.0174505657228756; + parameters.bavariaWalk.isMunichResident = 0.0105573744916928; // Bicycle - parameters.bike.alpha_u = -0.5; // -2.927596; - parameters.bike.betaTravelTime_u_min = -0.093485; - parameters.bavariaBicycle.isHighIncome = -0.0255; + parameters.bike.alpha_u = 0.318089528187347; // -2.927596; + parameters.bike.betaTravelTime_u_min = -0.085880877435606; // -0.093485; + parameters.bavariaBicycle.isHighIncome = -0.0255287460190827; // Car - parameters.car.alpha_u = 0.4; // -0.201465; - parameters.car.betaTravelTime_u_min = -0.042431; - parameters.bavariaCar.isHighIncome = -0.0225; - parameters.bavariaCar.hasPtSubscription = -0.0540; - parameters.bavariaCar.isWorkTrip = 0.0682; - parameters.bavariaCar.isShoppingTrip = 0.0682; + parameters.car.alpha_u = 0.0; // -0.201465; + parameters.car.betaTravelTime_u_min = -0.0756368247750132; // -0.042431; + parameters.bavariaCar.isHighIncome = -0.0224982297973797; + parameters.bavariaCar.hasPtSubscription = -0.0539508519243061; + parameters.bavariaCar.isWorkTrip = 0.043746300263639; + parameters.bavariaCar.isShoppingTrip = 0.0681864158380864; // Car passenger - parameters.bavariaCarPassenger.alpha_u = -1.4; // -1.713201; - parameters.bavariaCarPassenger.betaDrivingPermit_u = -0.835542; - parameters.bavariaCarPassenger.betaInVehicleTravelTime_u_min = -0.069976; - parameters.bavariaCarPassenger.isHighIncome = -0.0398; - parameters.bavariaCarPassenger.isWorkTrip = 0.0210; - parameters.bavariaCarPassenger.isShoppingTrip = 0.0508; + parameters.bavariaCarPassenger.alpha_u = -2.22497369171908; // -1.713201; + parameters.bavariaCarPassenger.betaDrivingPermit_u = 0.0; // -0.835542; + parameters.bavariaCarPassenger.betaInVehicleTravelTime_u_min = -0.065198856305705; // -0.069976; + parameters.bavariaCarPassenger.isHighIncome = -0.0398473945616337; + parameters.bavariaCarPassenger.isWorkTrip = 0.0209967096068355; + parameters.bavariaCarPassenger.isShoppingTrip = 0.0508046089649204; // PT - parameters.pt.alpha_u = 0.0; - parameters.pt.betaLineSwitch_u = -0.417658; - parameters.pt.betaInVehicleTime_u_min = -0.025501; - parameters.pt.betaWaitingTime_u_min = -0.021801; - - parameters.bavariaPt.betaDrivingPermit_u = -0.531426; - parameters.bavariaPt.onlyBus_u = -1.416309; - parameters.bavariaPt.isHighIncome = -0.0174; - parameters.bavariaPt.isWorkTrip = 0.0426; - parameters.bavariaPt.isShoppingTrip = 0.0441; - parameters.bavariaPt.waitingTimeHighIncome = -0.1530; - parameters.bavariaPt.waitingTimeMunichResident = 0.0991; - parameters.bavariaPt.waitingTimeSubscription = 0.4132; + parameters.pt.alpha_u = -0.284650026405347; // 0.0; + parameters.pt.betaLineSwitch_u = -0.625046612374831; // -0.417658; + parameters.pt.betaInVehicleTime_u_min = -0.0450421005231951; // -0.025501; + parameters.pt.betaWaitingTime_u_min = -0.41123926919253; // -0.021801; + + parameters.bavariaPt.betaDrivingPermit_u = 0.0; // -0.531426; + parameters.bavariaPt.onlyBus_u = 0.0; // -1.416309; + parameters.bavariaPt.isHighIncome = -0.0173904643343145; + parameters.bavariaPt.isWorkTrip = 0.0425817408468503; + parameters.bavariaPt.isShoppingTrip = 0.0441399147197244; + parameters.bavariaPt.waitingTimeShopping = -0.105687502807207; + parameters.bavariaPt.waitingTimeHighIncome = -0.152965571520264; + parameters.bavariaPt.waitingTimeMunichResident = 0.0990869975359573; + parameters.bavariaPt.waitingTimeSubscription = 0.413200821337636; return parameters; diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaBicycleUtilityEstimator.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaBicycleUtilityEstimator.java index 3eeafb89e..185debd40 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaBicycleUtilityEstimator.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaBicycleUtilityEstimator.java @@ -17,14 +17,14 @@ public class BavariaBicycleUtilityEstimator extends BikeUtilityEstimator { private final BavariaModeParameters parameters; - //private final BavariaPersonPredictor personPredictor; + private final BavariaPersonPredictor bavariaPersonPredictor; @Inject - public BavariaBicycleUtilityEstimator(BavariaModeParameters parameters, PersonPredictor personPredictor, + public BavariaBicycleUtilityEstimator(BavariaModeParameters parameters, PersonPredictor personPredictor, BavariaPersonPredictor bavariaPersonPredictor, BikePredictor predictor) { super(parameters, personPredictor, predictor); this.parameters = parameters; - ///this.personPredictor = personPredictor; + this.bavariaPersonPredictor = bavariaPersonPredictor; } protected double estimateAccessEgressTimeUtility(CarVariables variables) { @@ -37,7 +37,7 @@ protected double estimateHighIncomeUtility(BavariaPersonVariables variables) { @Override public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List elements) { - BavariaPersonVariables personVariables = personPredictor.predictVariables(person, trip, elements); + BavariaPersonVariables personVariables = bavariaPersonPredictor.predictVariables(person, trip, elements); double utility = 0.0; diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaCarPassengerUtilityEstimator.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaCarPassengerUtilityEstimator.java index 4e8198168..91d724a5c 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaCarPassengerUtilityEstimator.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/utilities/estimators/BavariaCarPassengerUtilityEstimator.java @@ -47,6 +47,14 @@ protected double estimaleHighIncomeUtility(BavariaPersonVariables variables) { return variables.isHighIncome ? parameters.bavariaCarPassenger.isHighIncome : 0.0; } + protected double estimateWorkPurposeUtility(DiscreteModeChoiceTrip trip) { + return trip.getDestinationActivity().getType().equals("work") ? parameters.bavariaCarPassenger.isWorkTrip : 0.0; + } + + protected double estimateShoppingPurposeUtility(DiscreteModeChoiceTrip trip) { + return trip.getDestinationActivity().getType().equals("shop") ? parameters.bavariaCarPassenger.isShoppingTrip : 0.0; + } + @Override public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List elements) { BavariaCarPassengerVariables variables = predictor.predictVariables(person, trip, elements); @@ -59,6 +67,8 @@ public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List elements) { @@ -44,12 +55,15 @@ public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List elements) { @@ -39,6 +49,9 @@ public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List Date: Thu, 25 Sep 2025 15:19:05 +0200 Subject: [PATCH 5/9] added files for running simulation --- .gitignore | 2 + .../bavaria/RunSimulationsMultipleSeeds.java | 189 ++++++++++++++ .../eqasim/bavaria/SimulationRunnerBase.java | 244 ++++++++++++++++++ simulation_bavaria.sbatch | 33 +++ 4 files changed, 468 insertions(+) create mode 100644 bavaria/src/main/java/org/eqasim/bavaria/RunSimulationsMultipleSeeds.java create mode 100644 bavaria/src/main/java/org/eqasim/bavaria/SimulationRunnerBase.java create mode 100644 simulation_bavaria.sbatch diff --git a/.gitignore b/.gitignore index 8b2072c1b..6725bbd5d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,11 @@ .project .settings .vscode +.history target dependency-reduced-pom.xml *.iml *.idea simulation_output .vscode +._* diff --git a/bavaria/src/main/java/org/eqasim/bavaria/RunSimulationsMultipleSeeds.java b/bavaria/src/main/java/org/eqasim/bavaria/RunSimulationsMultipleSeeds.java new file mode 100644 index 000000000..f97e90c65 --- /dev/null +++ b/bavaria/src/main/java/org/eqasim/bavaria/RunSimulationsMultipleSeeds.java @@ -0,0 +1,189 @@ +package org.eqasim.bavaria; + +import java.io.File; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.file.*; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +/** + * Runs multiple MATSim simulations for Munich using different random seeds, supporting parallel execution and automated output management. + * + * The class parses command line arguments to configure the number of seeds, thread count, and memory allocation. + * It sets up the necessary directories for Munich, manages concurrent simulation runs using a thread pool, and ensures that output directories are prepared and cleaned as needed. + * + * Example usage: + * nohup java -cp bavaria/target/bavaria-1.5.0.jar org.eqasim.bavaria.RunSimulationsMultipleSeeds > output.log 2>&1 & + * nohup java -cp bavaria/target/bavaria-1.5.0.jar org.eqasim.bavaria.RunSimulationsMultipleSeeds --seeds 3 --threads 12 --memory 60 > output.log 2>&1 & + * + * Note: After making changes to this class, recompile the project with: + * mvn clean package -Pstandalone --projects bavaria --also-make -DskipTests=true + */ + +public class RunSimulationsMultipleSeeds extends SimulationRunnerBase { + private static final Logger LOGGER = Logger.getLogger(RunSimulationsMultipleSeeds.class.getName()); + + static public void main(String[] args) throws Exception { + Config config; + try { + config = parseConfig(args); + } catch (IllegalArgumentException e) { + LOGGER.severe(e.getMessage()); + printUsage(); + System.exit(1); + return; // Never reached, but needed for compiler + } + + LOGGER.info("Running simulation with configuration: " + config); + + // Configuration settings + String configPath = "munich_config.xml"; + String workingDirectory = "bavaria/data/munich/"; + + LOGGER.info("Starting simulation with the following settings:"); + LOGGER.info("Configuration file: " + configPath); + LOGGER.info("Working directory: " + workingDirectory); + + // Create a fixed thread pool with specified number of threads + ExecutorService executor = Executors.newFixedThreadPool(config.threads); + LOGGER.info("Created thread pool with " + config.threads + " threads"); + + final String networkFile = "munich_network.xml.gz"; + LOGGER.info("Using network file: " + networkFile); + + final int currentSeed = config.numSeeds; + final String seedOutputDirectory = "bavaria/data/munich/output/seed_" + currentSeed + "/"; + LOGGER.info("Output for seed " + currentSeed + " will be written to: " + seedOutputDirectory); + + // Check if the output file exists for the current seed + boolean seedSimulationRanSuccessfully = checkIfFileExists(seedOutputDirectory, "output_events.xml.gz"); + LOGGER.info("Checking if output exists for seed " + currentSeed + ": " + seedSimulationRanSuccessfully); + + if (!seedSimulationRanSuccessfully) { + try { + if (outputDirectoryExists(seedOutputDirectory)) { + createAndEmptyDirectory(seedOutputDirectory); + LOGGER.info("Emptied output directory while preserving log files: " + seedOutputDirectory); + } else { + Files.createDirectories(Paths.get(seedOutputDirectory)); + LOGGER.info("Created output directory: " + seedOutputDirectory); + } + + // Submit task for the current seed + executor.submit(() -> { + LOGGER.info("Starting simulation task for: " + networkFile + " with seed " + currentSeed); + try { + runSimulation(configPath, networkFile, seedOutputDirectory, workingDirectory, args, currentSeed, + config.threads, config.threads, config.memory, true); + LOGGER.info("Completed simulation for: " + networkFile + " with seed " + currentSeed); + // If you want to keep only the three files output_links.csv.gz, output_events.xml.gz, and eqasim_trips.csv (for memory reasons), uncomment the following line. + // deleteUnwantedFiles(seedOutputDirectory); + // LOGGER.info("Deleted unwanted files for: " + networkFile + " with seed " + currentSeed); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + LOGGER.log(Level.SEVERE, "Simulation interrupted for: " + networkFile + " with seed " + currentSeed, e); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, "Error in simulation for: " + networkFile + " with seed " + currentSeed, e); + } + }); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Failed to setup output directory: " + seedOutputDirectory, e); + throw e; + } + } else { + LOGGER.info("Skipping simulation for seed " + currentSeed + " - output already exists in: " + seedOutputDirectory); + } + + // Shutdown the executor + executor.shutdown(); + try { + if (!executor.awaitTermination(300, TimeUnit.HOURS)) { + executor.shutdownNow(); + if (!executor.awaitTermination(360, TimeUnit.SECONDS)) { + LOGGER.severe("Executor did not terminate properly"); + } + } + } catch (InterruptedException ie) { + executor.shutdownNow(); + Thread.currentThread().interrupt(); + LOGGER.log(Level.SEVERE, "Executor was interrupted", ie); + } + LOGGER.info("All simulations completed"); + } + + /** + * Print usage instructions + */ + private static void printUsage() { + LOGGER.severe("Usage: java -cp bavaria/target/bavaria-1.5.0.jar org.eqasim.bavaria.RunSimulationsMultipleSeeds " + + "[--seeds ] [--threads ] " + + "[--memory ]"); + } + + /** + * Configuration class to hold all simulation parameters + */ + private static class Config { + int numSeeds = 3; // Default to 3 seeds + int threads = 12; // Default to 12 threads + int memory = 120; // Default to 60GB + + @Override + public String toString() { + return String.format("Config{numSeeds=%d, threads=%d, memory=%dGB}", + numSeeds, threads, memory); + } + } + + /** + * Parse and validate command line arguments + * @param args Command line arguments + * @return Config object with validated parameters + * @throws IllegalArgumentException if required parameters are missing or invalid + */ + private static Config parseConfig(String[] args) { + Config config = new Config(); + + for (int i = 0; i < args.length; i++) { + if (args[i].equals("--seeds") && i + 1 < args.length) { + try { + config.numSeeds = Integer.parseInt(args[i + 1]); + if (config.numSeeds < 1) { + throw new NumberFormatException("Number of seeds must be positive"); + } + i++; // Skip the next argument + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Invalid number of seeds. Please provide a positive integer."); + } + } else if (args[i].equals("--threads") && i + 1 < args.length) { + try { + config.threads = Integer.parseInt(args[i + 1]); + if (config.threads < 1) { + throw new NumberFormatException("Number of threads must be positive"); + } + i++; // Skip the next argument + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Invalid number of threads. Please provide a positive integer."); + } + } else if (args[i].equals("--memory") && i + 1 < args.length) { + try { + config.memory = Integer.parseInt(args[i + 1]); + if (config.memory < 1) { + throw new NumberFormatException("Memory allocation must be positive"); + } + i++; // Skip the next argument + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Invalid memory allocation. Please provide a positive integer."); + } + } + } + return config; + } +} \ No newline at end of file diff --git a/bavaria/src/main/java/org/eqasim/bavaria/SimulationRunnerBase.java b/bavaria/src/main/java/org/eqasim/bavaria/SimulationRunnerBase.java new file mode 100644 index 000000000..2dea7c406 --- /dev/null +++ b/bavaria/src/main/java/org/eqasim/bavaria/SimulationRunnerBase.java @@ -0,0 +1,244 @@ +package org.eqasim.bavaria; + +import java.io.IOException; +import java.nio.file.*; +import java.util.concurrent.*; +import java.util.logging.*; + +import java.io.File; +import java.io.IOException; +import java.nio.file.*; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +/** + * This class contains helper functions for running simulations. + */ +public abstract class SimulationRunnerBase { + protected static final Logger LOGGER = Logger.getLogger(SimulationRunnerBase.class.getName()); + + /** + * Runs the MATSim simulation with a fixed random seed (1) for the different scenarios (not the base case). + */ + protected static void runSimulation(final String configPath, final String networkFile, final String outputDirectory, + final String workingDirectory, final String[] args, + final int numberOfThreads, + final int numberOfThreadsQSim, + final int memoryAllocation) throws Exception { + runSimulation(configPath, networkFile, outputDirectory, workingDirectory, args,1, numberOfThreads, numberOfThreadsQSim, memoryAllocation, false); + } + + /** + * Runs the MATSim simulation with the given configuration path and output directory. This is the main method, calling the class "RunSimulation". It can be called with different random seeds as for the base case, or for the scenarios. + * + * @param configPath The path to the configuration file. + * @param networkFile The network file to use for the simulation. + * @param outputDirectory The directory where output files will be stored. + * @param workingDirectory The working directory. + * @param args Command line arguments. + * @throws Exception if an error occurs during the simulation setup or execution. + */ + protected static void runSimulation(final String configPath, final String networkFile, final String outputDirectory, + final String workingDirectory, final String[] args, + final int randomSeed, + final int numberOfThreads, + final int numberOfThreadsQSim, + final int memoryAllocation, + final boolean isForBaseCase) throws Exception { + + String fullConfigPath = Paths.get(workingDirectory, configPath).toString(); + + final List arguments = new ArrayList<>(Arrays.asList( + "java", + "-Xms" + String.valueOf(memoryAllocation) + "g", + "-Xmx" + String.valueOf(memoryAllocation) + "g", + "-cp", + "bavaria/target/bavaria-1.5.0.jar", + "org.eqasim.bavaria.RunSimulation", + "--config:global.numberOfThreads", String.valueOf(numberOfThreads), + "--config:qsim.numberOfThreads", String.valueOf(numberOfThreadsQSim), + "--config:global.randomSeed", String.valueOf(randomSeed), + "--config:network.inputNetworkFile", networkFile, + "--config:controler.outputDirectory", outputDirectory, + "--config-path", fullConfigPath + )); + + System.out.println("Arguments for simulation:"); + for (String argument : arguments) { + System.out.println(argument); + } + File logFile = null ; + File errorLogFile = null; + if (isForBaseCase) { + logFile = new File("simulation_" + networkFile.replace("_network.xml.gz", "") + "_seed_" + randomSeed + ".log"); + errorLogFile = new File("simulation_" + networkFile.replace("_network.xml.gz", "") + "_seed_" + randomSeed + ".error.log"); + } else { + // for scenarios + String[] networkFileParts = networkFile.split("/"); + String fileName = networkFileParts[networkFileParts.length - 1]; + String[] fileNameParts = fileName.split("_"); + String city = networkFileParts[networkFileParts.length - 4]; + String primary = fileNameParts[3]; + String nValue = fileNameParts[4]; + String sValue = fileNameParts[5].replace(".xml.gz", ""); + String logFileName = "simulation_" + city + "_" + primary + "_" + nValue + "_" + sValue + ".log"; + logFile = new File(logFileName); + errorLogFile = new File("simulation_" + city + "_" + primary + "_" + nValue + "_" + sValue + ".error.log"); + } + System.out.println("Log file: " + logFile); + System.out.println("Error log file: " + errorLogFile); + + Process process = new ProcessBuilder(arguments) + .redirectOutput(logFile) + .redirectError(errorLogFile) + .start(); + System.out.println("Started process: " + outputDirectory); + + boolean interrupted = false; + try { + boolean finished = process.waitFor(3000, TimeUnit.HOURS); // Increase wait time + if (!finished) { + process.destroy(); // destroy process if it times out + throw new InterruptedException("Simulation process timed out: " + networkFile); + } + int exitValue = process.exitValue(); + if (exitValue != 0) { + throw new IOException("Simulation process failed with exit code " + exitValue + ": " + networkFile); + } + } catch (InterruptedException e) { + interrupted = true; + process.destroy(); // ensure process is destroyed if interrupted + throw e; // rethrow the exception to be handled in the calling method + } finally { + if (interrupted) { + Thread.currentThread().interrupt(); + } + } + LOGGER.info("Completed simulation for: " + networkFile); + } + + protected static void createAndEmptyDirectory(String directory) throws IOException { + Path dirPath = Paths.get(directory); + if (!Files.exists(dirPath)) { + Files.createDirectories(dirPath); + } else if (Files.isDirectory(dirPath)) { + try (DirectoryStream stream = Files.newDirectoryStream(dirPath)) { + for (Path entry : stream) { + String fileName = entry.getFileName().toString(); + // Preserve log files and essential output files + if (!fileName.equals("output_links.csv.gz")) { + deleteRecursively(entry); + } + } + } + } else { + throw new IOException("The path specified is not a directory: " + directory); + } + } + + protected static boolean checkIfFileExists(String directory, String fileName) { + Path dirPath = Paths.get(directory); + Path filePath = dirPath.resolve(fileName); + boolean exists = Files.exists(filePath) && !Files.isDirectory(filePath); + LOGGER.info("Checking if file exists: " + filePath + " - " + exists); + return exists; + } + + protected static Map> getNetworkFiles(String city, String directoryPath) { + File mainDirectory = new File(directoryPath); + File[] subDirs = mainDirectory.listFiles(File::isDirectory); + + if (subDirs == null) { + System.out.println("The specified directory does not exist or is not a directory."); + return Map.of(); + } + + return Arrays.stream(subDirs) + .collect(Collectors.toMap( + File::getName, + subDir -> { + File[] filesList = subDir.listFiles((dir, name) -> name.endsWith(".xml.gz")); + List xmlGzFiles = new ArrayList<>(); + if (filesList != null) { + for (File file : filesList) { + if (file.isFile()) { + xmlGzFiles.add(file.getName()); + } + } + // Sort the list of file names + Collections.sort(xmlGzFiles); + } + return xmlGzFiles; + } + )); + } + + + protected static boolean outputDirectoryExists(String outputDirectory) { + File dir = new File(outputDirectory); + boolean exists = dir.exists() && dir.isDirectory(); + LOGGER.info("Checking if output directory exists: " + outputDirectory + " - " + exists); + return exists; + } + + protected static void deleteUnwantedFiles(String outputDirectory) throws IOException { + Path dir = Paths.get(outputDirectory); + if (!Files.exists(dir)) { + LOGGER.warning("Output directory does not exist: " + outputDirectory); + return; + } + + try (DirectoryStream stream = Files.newDirectoryStream(dir)) { + for (Path path : stream) { + if (Files.isDirectory(path)) { + LOGGER.info("Deleting directory: " + path); + deleteDirectoryRecursively(path); + } else { + String fileName = path.getFileName().toString(); + if (!fileName.equals("output_links.csv.gz") + && !fileName.equals("output_events.xml.gz") + && !fileName.equals("eqasim_trips.csv")) { + Files.delete(path); + LOGGER.info("Deleted file: " + path); + } else { + LOGGER.info("Skipping file: " + path); + } + } + } + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error deleting files in directory: " + outputDirectory, e); + } + } + + protected static void deleteDirectoryRecursively(Path directory) throws IOException { + try (DirectoryStream stream = Files.newDirectoryStream(directory)) { + for (Path entry : stream) { + if (Files.isDirectory(entry)) { + deleteDirectoryRecursively(entry); + } else { + Files.delete(entry); + LOGGER.info("Deleted file: " + entry); + } + } + } + Files.delete(directory); + LOGGER.info("Deleted directory: " + directory); + } + + protected static void deleteRecursively(Path path) throws IOException { + if (Files.isDirectory(path)) { + try (DirectoryStream stream = Files.newDirectoryStream(path)) { + for (Path entry : stream) { + deleteRecursively(entry); + } + } + } + Files.delete(path); + } +} + diff --git a/simulation_bavaria.sbatch b/simulation_bavaria.sbatch new file mode 100644 index 000000000..708a09f32 --- /dev/null +++ b/simulation_bavaria.sbatch @@ -0,0 +1,33 @@ +#!/bin/bash + +#SBATCH -J simulation_bavaria_job + +# Output and error files +#SBATCH --output=simulation_bavaria_output_%j.log +#SBATCH --error=simulation_bavaria_error_%j.log + +#SBATCH --nodes=1 +#SBATCH --ntasks-per-node=1 +#SBATCH --cpus-per-task=12 +#SBATCH --mem=80GB +#SBATCH --time=00:30:00 + +# Account and partition +#SBATCH --account=pn39mu +#SBATCH --partition=test + +# Notification and type +#SBATCH --mail-type=BEGIN,END +#SBATCH --mail-user=elena.natterer@tum.de +#SBATCH --get-user-env + +# Set up of execution environment +#SBATCH --export=none + +#export HOME=/dss/dsshome1/06/ge49wav3 +export FONTCONFIG_PATH=$HOME/test_java_font_4u/fonts +export FONTCONFIG_FILE=$HOME/test_java_font_4u/fonts/fonts.conf +export FC_FONT_PATH=$HOME/test_java_font_4u/fonts + +# Run the Java program with full arguments +java -cp bavaria/target/bavaria-1.5.0.jar org.eqasim.bavaria.RunSimulationsMultipleSeeds --seeds 3 --threads 12 --memory 80 From 49e760edffa1f69055c58e95d17a8e24849cb94e Mon Sep 17 00:00:00 2001 From: Elena Natterer Date: Fri, 26 Sep 2025 12:38:02 +0200 Subject: [PATCH 6/9] added data files and log files to gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 6725bbd5d..8983b709a 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ dependency-reduced-pom.xml simulation_output .vscode ._* +bavaria/data/* +nohup.out From eeec3967efb0f9f7b0e042b1ac5ec49c09c392bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Thu, 30 Oct 2025 17:13:55 +0100 Subject: [PATCH 7/9] Calibration finished: New parameters set in BavariaModeParameters.java --- .../parameters/BavariaModeParameters.java | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/parameters/BavariaModeParameters.java b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/parameters/BavariaModeParameters.java index 8fb74c402..bd55e3b1a 100644 --- a/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/parameters/BavariaModeParameters.java +++ b/bavaria/src/main/java/org/eqasim/bavaria/mode_choice/parameters/BavariaModeParameters.java @@ -61,18 +61,18 @@ public static BavariaModeParameters buildDefault() { // Access // not specifically estimated for Bavaria, using values from walk.betaTravelTime_u_min - parameters.betaAccessTime_u_min = -0.0450421005231951; // -0.031239; + parameters.betaAccessTime_u_min = -0.0450421005231951; // IdF -0.031239; // Cost - parameters.betaCost_u_MU = -0.0448921788117033; // -0.310998; - parameters.lambdaCostEuclideanDistance = 0.0; //-0.257501; + parameters.betaCost_u_MU = -0.0448921788117033; // IdF -0.310998; + parameters.lambdaCostEuclideanDistance = 0.0; // IdF -0.257501; parameters.referenceEuclideanDistance_km = 4.4; // Walk - parameters.walk.alpha_u = 0.774228551231712; // 1.685152; - parameters.walk.betaTravelTime_u_min = -0.0695442805909274; // -0.162285; + parameters.walk.alpha_u = -0.1; // uncalibrated 0.774228551231712; IdF 1.685152; + parameters.walk.betaTravelTime_u_min = -0.0695442805909274; // IdF -0.162285; parameters.bavariaWalk.isHighIncome = -0.0217295300225373; parameters.bavariaWalk.hasDrivingPermit = -0.0318551303397705; parameters.bavariaWalk.hasPtSubscription = 0.0174505657228756; @@ -80,36 +80,36 @@ public static BavariaModeParameters buildDefault() { // Bicycle - parameters.bike.alpha_u = 0.318089528187347; // -2.927596; - parameters.bike.betaTravelTime_u_min = -0.085880877435606; // -0.093485; + parameters.bike.alpha_u = -1.2; // uncalibrated 0.318089528187347; IdF -2.927596; + parameters.bike.betaTravelTime_u_min = -0.085880877435606; // IdF -0.093485; parameters.bavariaBicycle.isHighIncome = -0.0255287460190827; // Car - parameters.car.alpha_u = 0.0; // -0.201465; - parameters.car.betaTravelTime_u_min = -0.0756368247750132; // -0.042431; + parameters.car.alpha_u = 0.0; // IdF -0.201465; + parameters.car.betaTravelTime_u_min = -0.0756368247750132; // IdF -0.042431; parameters.bavariaCar.isHighIncome = -0.0224982297973797; parameters.bavariaCar.hasPtSubscription = -0.0539508519243061; parameters.bavariaCar.isWorkTrip = 0.043746300263639; parameters.bavariaCar.isShoppingTrip = 0.0681864158380864; // Car passenger - parameters.bavariaCarPassenger.alpha_u = -2.22497369171908; // -1.713201; - parameters.bavariaCarPassenger.betaDrivingPermit_u = 0.0; // -0.835542; - parameters.bavariaCarPassenger.betaInVehicleTravelTime_u_min = -0.065198856305705; // -0.069976; + parameters.bavariaCarPassenger.alpha_u = -1.75; // uncalibrated -2.22497369171908; IdF -1.713201; + parameters.bavariaCarPassenger.betaDrivingPermit_u = 0.0; // IdF -0.835542; + parameters.bavariaCarPassenger.betaInVehicleTravelTime_u_min = -0.1; // uncalibrated -0.065198856305705; IdF -0.069976; parameters.bavariaCarPassenger.isHighIncome = -0.0398473945616337; parameters.bavariaCarPassenger.isWorkTrip = 0.0209967096068355; parameters.bavariaCarPassenger.isShoppingTrip = 0.0508046089649204; // PT - parameters.pt.alpha_u = -0.284650026405347; // 0.0; - parameters.pt.betaLineSwitch_u = -0.625046612374831; // -0.417658; - parameters.pt.betaInVehicleTime_u_min = -0.0450421005231951; // -0.025501; - parameters.pt.betaWaitingTime_u_min = -0.41123926919253; // -0.021801; + parameters.pt.alpha_u = -0.36; // uncalibrated -0.284650026405347; IdF 0.0; + parameters.pt.betaLineSwitch_u = -0.625046612374831; // IdF -0.417658; + parameters.pt.betaInVehicleTime_u_min = -0.03603368; // uncalibrated -0.0450421005231951; -IdF 0.025501; + parameters.pt.betaWaitingTime_u_min = -0.41123926919253; // IdF -0.021801; - parameters.bavariaPt.betaDrivingPermit_u = 0.0; // -0.531426; - parameters.bavariaPt.onlyBus_u = 0.0; // -1.416309; + parameters.bavariaPt.betaDrivingPermit_u = 0.0; // IdF -0.531426; + parameters.bavariaPt.onlyBus_u = 0.0; // IdF -1.416309; parameters.bavariaPt.isHighIncome = -0.0173904643343145; parameters.bavariaPt.isWorkTrip = 0.0425817408468503; parameters.bavariaPt.isShoppingTrip = 0.0441399147197244; From 9843972a863747d8eac2ca1384391bf610587c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Thu, 30 Oct 2025 19:31:33 +0100 Subject: [PATCH 8/9] Adapting README, adding config_munich_calibrated.xml and example for slurm script --- README.md | 110 ++++- config_munich_calibrated.xml | 908 +++++++++++++++++++++++++++++++++++ slurm_matsim_run_example.txt | 25 + 3 files changed, 1042 insertions(+), 1 deletion(-) create mode 100644 config_munich_calibrated.xml create mode 100644 slurm_matsim_run_example.txt diff --git a/README.md b/README.md index 93a614450..535858352 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,112 @@ -# eqasim-java + +# How to run a MATSim simulation + +## 🚀 Running the MATSim Simulation + +This repo on the LRZ gitlab uses a pre-configured setup from eqasim's simulation repository. + +## ✅ Prerequisites + +1. Make sure you’ve completed all steps for generating the synthetic population. You find examples for the population synthesis output files on the internal drives: [\\10.152.34.30\Austausch\MATSim Populations]](\\10.152.34.30\Austausch\MATSim Populations) +2. Additional configuration details are available here: +👉 [https://github.com/eqasim-org/bavaria/blob/development-minga/docs/simulation.md](https://github.com/eqasim-org/bavaria/blob/development-minga/docs/simulation.md) + +--- + +### 1️⃣ Clone the Simulation Repository + +Use this repository and branch: + +- **Repository:** + 🔗 [https://gitlab.lrz.de/tum-vt/minga-eqasim-simulation](https://gitlab.lrz.de/tum-vt/minga-eqasim-simulation) + +- **Branch:** `bavaria-mode-choice` + 🔗 [https://gitlab.lrz.de/tum-vt/minga-eqasim-simulation/tree/bavaria-mode-choice](https://gitlab.lrz.de/tum-vt/minga-eqasim-simulation/tree/bavaria-mode-choice) + +Clone and check out the correct branch: + +```bash +git clone https://gitlab.lrz.de/tum-vt/minga-eqasim-simulation.git +cd eqasim-java +git checkout bavaria-mode-choice +``` + +--- + +### 2️⃣ (Optional) Create Your Own Branch Based on `bavaria-mode-choice` + +If you want to make changes or run your own experiments: + +```bash +git checkout -b my-example-experiment +git push -u origin my-example-experiment +``` + +This creates your own branch based on `bavaria-mode-choice` and sets up tracking so that future pushes and pulls work seamlessly. + +--- + +### 3️⃣ Prepare the `data` Folder + +In the `bavaria` module, create a `data` folder, containing the folder `munich` and copy your synthetic population and network files there: + +```bash +mkdir -p bavaria/data/munich +``` +Copy into this folder all files created in the synthetic population, such as the config, network file, etc. Only xml files are required! csv files are outputs of the MATSim simulation and are not used as inputs for the simulation. + +Ensure that you use a `config.xml` in which the eqasim:raptor parameters are set as follows: +``` + + + + + + + + + + +``` +You can use the config file that is used for calibration: `config_munich_calibrated.xml` from this repository. + +--- + +### 4️⃣ Run the Simulation + +First, build the project: +```bash +mvn clean package -Pstandalone --projects bavaria --also-make -DskipTests=true +``` + +This will generate a `bavaria-1.5.0.jar` file in the `bavaria/target` directory. + +To run a single simulation, use: + +```bash +nohup java -Xmx12G -cp bavaria/target/bavaria-1.5.0.jar org.eqasim.bavaria.RunSimulation --config-path bavaria/data/munich_0.1/munich_config.xml &> simulation_output.log & +``` +If you are running the simulation on a cluster or machine with larger memory resources, consider increasing the Java heap space, e.g., by setting -Xmx120G. + +If you want to run simulations for multiple random seeds, use the `RunSimulationsMultipleSeeds`, where you can specify the number of seeds, threads, and memory: +```bash +nohup java -cp bavaria/target/bavaria-1.5.0.jar org.eqasim.bavaria.RunSimulationsMultipleSeeds --seeds 3 --threads 12 --memory 60 > output.log 2>&1 & +``` + +This command works for all downsampled population sizes. +There’s no need to change the command based on population size — just ensure the corresponding population file is correctly referenced in the config. + +If you want to run MATSim on the LRZ cluster (e.g., cm4_tiny), you need to ask Peter for an account. After setting up your account, you can do the following steps to run the simulation: +1. Go to Windows PowerShell (or similar) and use the command `ssh @cool.hpc.lrz.de` to login. +2. Use the command `sbatch slurm_matsim_run_example.txt`. This file is part of this repo and can be copied. +3. `squeue -M cm4` tells you if your job is queued. +There are some restrictions on the LRZ cluster like the maximum of submitted jobs (currently 4), number of kernels etc. Find details to the LRZ cluster here: [https://doku.lrz.de/linux-cluster-10745672.html](https://doku.lrz.de/linux-cluster-10745672.html). + +In the `slurm_matsim_run_example.txt`file, there are some arguments for the mode choice parameter setting. These are **not** required since they are already correctly set in the `BavariaModeParameters.java` file. + + + +# eqasim-java [from the original readme] ![eqasim](docs/top.png "eqasim") diff --git a/config_munich_calibrated.xml b/config_munich_calibrated.xml new file mode 100644 index 000000000..6aa2410ff --- /dev/null +++ b/config_munich_calibrated.xml @@ -0,0 +1,908 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/slurm_matsim_run_example.txt b/slurm_matsim_run_example.txt new file mode 100644 index 000000000..b1fe705bc --- /dev/null +++ b/slurm_matsim_run_example.txt @@ -0,0 +1,25 @@ +#!/bin/bash +#SBATCH -J calibrated # Job name (max 10 characters!) +#SBATCH -D /dss/dsshome1/0B/go68qak2/minga-eqasim-simulation +#SBATCH --mem=200G # Memory +#SBATCH --clusters=cm4 +#SBATCH --partition=cm4_tiny +#SBATCH --qos=cm4_tiny +#SBATCH --nodes=1 +#SBATCH --tasks-per-node=4 +#SBATCH --cpus-per-task=10 # Optional: how many cores +#SBATCH --time=08:00:00 # Time limit (hh:mm:ss) +#SBATCH --mail-user=your.name@tum.de # REQUIRED: your email address +#SBATCH --mail-type=BEGIN,END,FAIL # Send email when job ends or fails +#SBATCH --output=/dss/dsshome1/0B/go68qak2/minga-eqasim-simulation/simulation_bavaria_output_%j.log +#SBATCH --error=/dss/dsshome1/0B/go68qak2/simulation_bavaria_error_%j.log +#SBATCH --export=NONE # Recommended: clean environment +#SBATCH --get-user-env + +# Load modules +module load slurm_setup +module load openjdk/21.0.3_9 + +# Run your job +# You have to change the paths +srun java -cp /dss/dsshome1/0B/go68qak2/minga-eqasim-simulation/bavaria/target/bavaria-1.5.0.jar org.eqasim.bavaria.RunSimulation --config-path /dss/dsshome1/0B/go68qak2/minga-eqasim-simulation/bavaria/data/munich/munich_0.01/munich_config_calibrated.xml --use-vdf true --mode-choice-parameter:walk.alpha_u -0.1 --mode-choice-parameter:bike.alpha_u -1.2 --mode-choice-parameter:bavariaCarPassenger.alpha_u -1.75 --mode-choice-parameter:pt.alpha_u -0.36 --mode-choice-parameter:bavariaCarPassenger.betaInVehicleTravelTime_u_min -0.1 --mode-choice-parameter:pt.betaInVehicleTime_u_min -0.03603368 \ No newline at end of file From e2970fdc0d89713f2f37a492edece1f4c35ae077 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Thu, 30 Oct 2025 19:35:46 +0100 Subject: [PATCH 9/9] small changes to README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 535858352..fa1b05f22 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ This repo on the LRZ gitlab uses a pre-configured setup from eqasim's simulation ## ✅ Prerequisites -1. Make sure you’ve completed all steps for generating the synthetic population. You find examples for the population synthesis output files on the internal drives: [\\10.152.34.30\Austausch\MATSim Populations]](\\10.152.34.30\Austausch\MATSim Populations) +1. Make sure you’ve completed all steps for generating the synthetic population. You find examples for the population synthesis output files on the internal drives: `\\10.152.34.30\Austausch\MATSim Populations` 2. Additional configuration details are available here: 👉 [https://github.com/eqasim-org/bavaria/blob/development-minga/docs/simulation.md](https://github.com/eqasim-org/bavaria/blob/development-minga/docs/simulation.md)