From 50dac357be357fa648708ba66e3fa41d88efad70 Mon Sep 17 00:00:00 2001 From: Kai Nagel Date: Wed, 24 Jun 2026 16:57:48 +0200 Subject: [PATCH 01/12] add comments --- .../bgu/msm/data/accessibility/CommutingTimeProbability.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/siloCore/src/main/java/de/tum/bgu/msm/data/accessibility/CommutingTimeProbability.java b/siloCore/src/main/java/de/tum/bgu/msm/data/accessibility/CommutingTimeProbability.java index b75454c94..adfde8aae 100644 --- a/siloCore/src/main/java/de/tum/bgu/msm/data/accessibility/CommutingTimeProbability.java +++ b/siloCore/src/main/java/de/tum/bgu/msm/data/accessibility/CommutingTimeProbability.java @@ -3,5 +3,10 @@ import de.tum.bgu.msm.models.ModelUpdateListener; public interface CommutingTimeProbability extends ModelUpdateListener { + /** + * @param minutes + * @param mode + * @return Presumably, this returns a (non-normalized) weight and not a (normalized) probability. + */ float getCommutingTimeProbability(int minutes, String mode); } From 0dea79fd63e142aebbbb40d205aa1434c83ce847 Mon Sep 17 00:00:00 2001 From: Kai Nagel Date: Wed, 24 Jun 2026 16:57:58 +0200 Subject: [PATCH 02/12] add comments --- useCases/fabiland/src/main/java/run/DataBuilderFabiland.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/useCases/fabiland/src/main/java/run/DataBuilderFabiland.java b/useCases/fabiland/src/main/java/run/DataBuilderFabiland.java index 8ac07a4c6..8767e815b 100644 --- a/useCases/fabiland/src/main/java/run/DataBuilderFabiland.java +++ b/useCases/fabiland/src/main/java/run/DataBuilderFabiland.java @@ -52,9 +52,11 @@ public static DataContainer buildDataContainer(Properties properties, Config con } CommutingTimeProbability commutingTimeProbability = new OnTheFlyCommutingTimeProbability(); + // (This returns Math.exp(beta * minutes)). //TODO: revise this! new JobType(properties.jobData.jobTypes); + // (this is indeed quite odd ... uses a constructor to initialize some static variables.) RealEstateDataManager realEstateManager = new RealEstateDataManagerImpl( new SandboxDwellingTypes(), From 9e76923c9289dc8d6fff8cdf5a02a33c68e4a78b Mon Sep 17 00:00:00 2001 From: Kai Nagel Date: Wed, 24 Jun 2026 16:58:16 +0200 Subject: [PATCH 03/12] replace implementations by interfaces --- .../models/realEstate/demolition/DemolitionModelImpl.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/siloCore/src/main/java/de/tum/bgu/msm/models/realEstate/demolition/DemolitionModelImpl.java b/siloCore/src/main/java/de/tum/bgu/msm/models/realEstate/demolition/DemolitionModelImpl.java index 6687e62d3..b68e3f5c5 100644 --- a/siloCore/src/main/java/de/tum/bgu/msm/models/realEstate/demolition/DemolitionModelImpl.java +++ b/siloCore/src/main/java/de/tum/bgu/msm/models/realEstate/demolition/DemolitionModelImpl.java @@ -7,6 +7,7 @@ import de.tum.bgu.msm.events.impls.realEstate.DemolitionEvent; import de.tum.bgu.msm.models.AbstractModel; import de.tum.bgu.msm.models.relocation.migration.InOutMigration; +import de.tum.bgu.msm.models.relocation.moves.MovesModel; import de.tum.bgu.msm.models.relocation.moves.MovesModelImpl; import de.tum.bgu.msm.properties.Properties; import de.tum.bgu.msm.utils.SiloUtil; @@ -28,14 +29,14 @@ public class DemolitionModelImpl extends AbstractModel implements DemolitionMode private final static Logger logger = LogManager.getLogger(DemolitionModelImpl.class); - private final MovesModelImpl moves; + private final MovesModel moves; private final InOutMigration inOutMigration; private final DemolitionStrategy strategy; private int currentYear = -1; private int forcedOutmigrationByDemolition; - public DemolitionModelImpl(DataContainer dataContainer, MovesModelImpl moves, + public DemolitionModelImpl(DataContainer dataContainer, MovesModel moves, InOutMigration inOutMigration, Properties properties, DemolitionStrategy strategy, Random rnd) { super(dataContainer, properties, rnd); From 6de0fbd920d53e60a164dca107c97f68b611b31c Mon Sep 17 00:00:00 2001 From: Kai Nagel Date: Wed, 24 Jun 2026 16:58:46 +0200 Subject: [PATCH 04/12] add comments; replace implementations by interfaces --- .../main/java/run/ModelBuilderFabiland.java | 93 +++++++++++++++---- 1 file changed, 77 insertions(+), 16 deletions(-) diff --git a/useCases/fabiland/src/main/java/run/ModelBuilderFabiland.java b/useCases/fabiland/src/main/java/run/ModelBuilderFabiland.java index a555c8186..80e7ad1b5 100644 --- a/useCases/fabiland/src/main/java/run/ModelBuilderFabiland.java +++ b/useCases/fabiland/src/main/java/run/ModelBuilderFabiland.java @@ -8,6 +8,7 @@ import de.tum.bgu.msm.data.person.PersonFactory; import de.tum.bgu.msm.matsim.*; import de.tum.bgu.msm.models.autoOwnership.CreateCarOwnershipModel; +import de.tum.bgu.msm.models.demography.birth.BirthModel; import de.tum.bgu.msm.models.demography.birth.BirthModelImpl; import de.tum.bgu.msm.models.demography.birth.DefaultBirthStrategy; import de.tum.bgu.msm.models.demography.birthday.BirthdayModel; @@ -33,6 +34,7 @@ import de.tum.bgu.msm.models.demography.marriage.MarriageModelImpl; import de.tum.bgu.msm.models.jobmography.JobMarketUpdate; import de.tum.bgu.msm.models.jobmography.JobMarketUpdateImpl; +import de.tum.bgu.msm.models.modeChoice.CommuteModeChoice; import de.tum.bgu.msm.models.realEstate.construction.*; import de.tum.bgu.msm.models.realEstate.demolition.DefaultDemolitionStrategy; import de.tum.bgu.msm.models.realEstate.demolition.DemolitionModel; @@ -68,30 +70,84 @@ public static ModelContainer getModelContainer(DataContainer dataContainer, Prop HouseholdFactory hhFactory = dataContainer.getHouseholdDataManager().getHouseholdFactory(); DwellingFactory ddFactory = dataContainer.getRealEstateDataManager().getDwellingFactory(); - final BirthModelImpl birthModel = new BirthModelImpl(dataContainer, ppFactory, properties, new DefaultBirthStrategy(), SiloUtil.provideNewRandom()); + final BirthModel birthModel = new BirthModelImpl(dataContainer, ppFactory, properties, new DefaultBirthStrategy(), SiloUtil.provideNewRandom()); BirthdayModel birthdayModel = new BirthdayModelImpl(dataContainer, properties, SiloUtil.provideNewRandom()); DeathModel deathModel = new DeathModelImpl(dataContainer, properties, new DefaultDeathStrategy(), SiloUtil.provideNewRandom()); - MovesModelImpl movesModel = new MovesModelImpl( - dataContainer, properties, - new DefaultMovesStrategy(), - new SimpleCommuteModeChoiceHousingStrategyImpl(dataContainer, - properties, - dataContainer.getTravelTimes(), - new DwellingUtilityStrategyImpl(), - new DefaultDwellingProbabilityStrategy(), - new RegionUtilityStrategyImpl(), - new RegionProbabilityStrategyImpl() , - new SimpleMatsimCommuteModeChoice(dataContainer, properties, SiloUtil.provideNewRandom()) - ), SiloUtil.provideNewRandom()); + MovesModel movesModel; + { + + final DwellingUtilityStrategy dwellingUtilityStrategy = new DwellingUtilityStrategyImpl(); + // (This is something like + // [alpha * sizeUtility + beta * autoAccessibilityUtility + gamma * transitAccessibilityUtility + (1.0 - alpha - beta - gamma) * qualityUtility]^delta * priceUtl^eps * workDistanceUtl^{1-delta-eps} + // That is, some kind of Cobbs Douglas function with contributions + // * workDistanceUtil + // * priceUtl + // * a weighted sum of sizeUtl, autoAccUtl, transitAccUtl, qualityUtl. + // All of the params depend on income and hh size, and are given for corresponding categories. + // ) + + final DwellingProbabilityStrategy dwellingProbabilityStrategy = new DefaultDwellingProbabilityStrategy(); + // (is just exp(beta*util); should be called "weight" instead of "probability" since it is not normalized. kai, apr'26) + + final RegionUtilityStrategy regionUtilityStrategy = new RegionUtilityStrategyImpl(); + // (This is something like (1 - alpha) * price + alpha * accessibility, with alpha depending on the income category.) + + final RegionProbabilityStrategy regionProbabilityStrategy = new RegionProbabilityStrategyImpl(); + //( same as DefaultDwellingProbabilityStrategy, see above. kai, apr'26) + + final CommuteModeChoice commuteModeChoice1 = new SimpleMatsimCommuteModeChoice( dataContainer, properties, SiloUtil.provideNewRandom() ); + // (there is a comment in SimpleCommuteModeChoiceHousingStrategyImpl that the constructor should actually work w/o providing the CommuteChoiceModel. It then provides + // CommuteModeChoice internally, as SimpleCommuteModeChoice. That model looks similar; presumably some of the lookups (e.g. travel time) used to have different arguments. + // kai, apr'26) + // (I think that the existing implementations do the following: compute the logit probas for car and pt if car is an option; then go from HH member with largest car + // proba down and select car with logit proba as long as another car is available in the HH.) + // (yy this implies, as long as nothing else comes in, that moves consider new residencies under the assumption that they will not change the number of vehicles) + + final HousingStrategy housingStrategy = new SimpleCommuteModeChoiceHousingStrategyImpl( dataContainer, + properties, + dataContainer.getTravelTimes(), + dwellingUtilityStrategy, + dwellingProbabilityStrategy, + regionUtilityStrategy, + regionProbabilityStrategy, + commuteModeChoice1 + ); + /// (If I see this right, this is computing the necessary inputs to {@link DwellingUtilityStrategy} using all the other dependencies, and then computing the dwelling + /// probabilities using the {@link DwellingUtilityStrategy}. + + final MovesStrategy movesStrategy = new DefaultMovesStrategy(); + // (This says that the moving proba is 1 - 1/(1+0.03 * Math.exp(10*(householdSatisfaction - currentDwellingUtility))) + + movesModel = new MovesModelImpl( dataContainer, properties, movesStrategy, housingStrategy, SiloUtil.provideNewRandom() ); + } + // (Overall, I think that life events are not explicitly triggering a move. They will, however, shift the respective utilities, and so a move becomes more probable.) + + // (For our own issue, which (only) is to "age" the population, this seems like a lot of overhead. On the other hand, it is not immediately clear how else this should be + // resolved; location choice needs to be something like logit based on location utility. What might end up being a bit of a problem is (commute) mode choice ... we would + // need to say that maybe the commute mode choice to make a residence decision is based on what is defined above, but the final mode choice may be different once people + // optimize into their new environment. kai, apr'26) + + // (Also, the MatsimScenarioAssembler takes the commute mode from the Silo mode choice model (although I am not sure that it will give the same results are for housing + // choice, since the random numbers are different--????). Evidently, we can override this in MATSim. Clearly, this will be two models pull into different directions. + // Unfortunately, I fail to see how we calibrade mode choice on the MATSim side if we rely on upstream mode choice. Maybe possible in principle, but will not be sensitive + // to (the details of) many transport policies. kai, apr'26) + + // (As we have known for some time now, this is two competing modelling paradigms: mode (and time) choice as part of the DTA vs mode (and time?) choice as part of the + // upstream model. Rolf seems to have been a proponent of the former. However, from a MATSim side and MATSim research side, this is not something we can continue since we + // have experience with mode choice in MATSim but not in upstream models, and this is also a path that we do not want to take (would need to be done by someone else). + // We should consider to re-code the commute mode choice for our purposes, i.e. always allow for car and pt during housing search, using income-dependent utilities and + // fixed costs for cars (and pt), etc., and then sort out the actual choice later. However, this may end up not so different from the current approach, so why not leave + // the current approach in place, but change as follows: Only if a silo person has moved residency or job, then we use the mode choice from silo as an initial suggestion; + // otherwise we keep the plan (including mode) from previous iterations. -- Such an approach would make a lot of sense anyways; it was already encoded as "hot start" in + // both matsim-urbansim couplings (by KN and by TN); and it would be far enough downstream of SILO, i.e. only in the adapter class. -- A bit disappointing that 20 year + // later we are not any further here. :-( kai, apr'26) CreateCarOwnershipModel carOwnershipModel = new FabilandCarOwnership(); - DivorceModel divorceModel = new DivorceModelImpl( - dataContainer, movesModel, carOwnershipModel, hhFactory, - properties, new DefaultDivorceStrategy(), SiloUtil.provideNewRandom()); + DivorceModel divorceModel = new DivorceModelImpl( dataContainer, movesModel, carOwnershipModel, hhFactory, properties, new DefaultDivorceStrategy(), SiloUtil.provideNewRandom()); DriversLicenseModel driversLicenseModel = new DriversLicenseModelImpl(dataContainer, properties, new DefaultDriversLicenseStrategy(), SiloUtil.provideNewRandom()); @@ -137,7 +193,12 @@ public static ModelContainer getModelContainer(DataContainer dataContainer, Prop // SimpleCommuteModeChoice commuteModeChoice = new SimpleCommuteModeChoice(dataContainer, properties, SiloUtil.provideNewRandom()); SimpleMatsimCommuteModeChoice commuteModeChoice = new SimpleMatsimCommuteModeChoice(dataContainer, properties, SiloUtil.provideNewRandom()); // (yyyy is also instantiated above. why not re-use?) + // --> fails the regression test. Which is no wonder, since it changes the random number sequence. + scenarioAssembler = new SimpleCommuteModeChoiceMatsimScenarioAssembler(dataContainer, properties, commuteModeChoice, HandlingOfRandomness.localInstanceFromMatsimWithAlwaysSameSeed); + // yyyyyy the above needs to be re-coded from a MATSim perspective ... i.e. (1) select the same agents, and (2) take the mode "suggestion" from silo only if home or + // job location has changed, otherwise keep existing plan with existing mode. kai, apr'26 + transportModel = new MatsimTransportModel(dataContainer, config, properties, scenarioAssembler, matsimData); break; case NONE: From fd47558e37523d5f9d1aef462db8700f31e5fc76 Mon Sep 17 00:00:00 2001 From: Kai Nagel Date: Wed, 24 Jun 2026 16:59:04 +0200 Subject: [PATCH 05/12] add comments --- useCases/fabiland/src/main/java/run/RunFabiland.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/useCases/fabiland/src/main/java/run/RunFabiland.java b/useCases/fabiland/src/main/java/run/RunFabiland.java index 1fd3c331a..ebe039970 100644 --- a/useCases/fabiland/src/main/java/run/RunFabiland.java +++ b/useCases/fabiland/src/main/java/run/RunFabiland.java @@ -23,8 +23,7 @@ public class RunFabiland { private final static Logger logger = LogManager.getLogger(RunFabiland.class); public static void main(String[] args) { - // yyyy This does not run out of the box. Presumably, it needs an argument. Could you please add a comment that explains to make this here run? Thanks ... kai, jun'23 - // yyyyyy Also, there should be a regression test running this method. kai, jun'23 + // see regression test Properties properties = SiloUtil.siloInitialization(args[0]); From 50236edcabe63102bba0b7344641c8c98b15a242 Mon Sep 17 00:00:00 2001 From: Kai Nagel Date: Wed, 24 Jun 2026 16:59:15 +0200 Subject: [PATCH 06/12] add comments --- .../moves/SimpleCommuteModeChoiceHousingStrategyImpl.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/siloCore/src/main/java/de/tum/bgu/msm/models/relocation/moves/SimpleCommuteModeChoiceHousingStrategyImpl.java b/siloCore/src/main/java/de/tum/bgu/msm/models/relocation/moves/SimpleCommuteModeChoiceHousingStrategyImpl.java index 48a4b16b0..bf1ccbe54 100644 --- a/siloCore/src/main/java/de/tum/bgu/msm/models/relocation/moves/SimpleCommuteModeChoiceHousingStrategyImpl.java +++ b/siloCore/src/main/java/de/tum/bgu/msm/models/relocation/moves/SimpleCommuteModeChoiceHousingStrategyImpl.java @@ -27,7 +27,10 @@ import static de.tum.bgu.msm.data.dwelling.RealEstateUtils.RENT_CATEGORIES; -public class SimpleCommuteModeChoiceHousingStrategyImpl implements HousingStrategy { +public class SimpleCommuteModeChoiceHousingStrategyImpl implements HousingStrategy { + // this used to be without . Which, in consequence, violated the generics contract. The only place where this is + // used is isHouseholdEligibleToLiveHere(Household household, Dwelling dd) below, which means that the present implementation + // used the hardcoded "Dwelling" type. So we can as well specify it. kai, jun'26 private final static Logger logger = LogManager.getLogger(SimpleCommuteModeChoiceHousingStrategyImpl.class); From c9c0b51d5c1486f879063a466f6f6e6a11f94b6d Mon Sep 17 00:00:00 2001 From: Kai Nagel Date: Wed, 24 Jun 2026 16:59:40 +0200 Subject: [PATCH 07/12] rename a variable --- .../SimpleCommuteModeChoiceMatsimScenarioAssembler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/matsim2silo/src/main/java/de/tum/bgu/msm/matsim/SimpleCommuteModeChoiceMatsimScenarioAssembler.java b/extensions/matsim2silo/src/main/java/de/tum/bgu/msm/matsim/SimpleCommuteModeChoiceMatsimScenarioAssembler.java index bff93bf65..5da1888cd 100644 --- a/extensions/matsim2silo/src/main/java/de/tum/bgu/msm/matsim/SimpleCommuteModeChoiceMatsimScenarioAssembler.java +++ b/extensions/matsim2silo/src/main/java/de/tum/bgu/msm/matsim/SimpleCommuteModeChoiceMatsimScenarioAssembler.java @@ -119,8 +119,8 @@ public Scenario assembleScenario(Config matsimConfig, int year, TravelTimes trav PopulationFactory pf = matsimPopulation.getFactory(); - final int noHHAUtos = (int) household.getVehicles().stream().filter( vv -> vv.getType().equals( VehicleType.CAR ) ).count(); - org.matsim.api.core.v01.population.Person matsimAlterEgo = SiloMatsimUtils.createMatsimAlterEgo(pf, person, noHHAUtos ); + final int nHhCars = (int) household.getVehicles().stream().filter( vv -> vv.getType().equals( VehicleType.CAR ) ).count(); + org.matsim.api.core.v01.population.Person matsimAlterEgo = SiloMatsimUtils.createMatsimAlterEgo(pf, person, nHhCars ); matsimPopulation.addPerson(matsimAlterEgo); Dwelling dwelling = realEstateDataManager.getDwelling(household.getDwellingId()); From 029a438707198c5dfa340759273516314f28e40b Mon Sep 17 00:00:00 2001 From: Kai Nagel Date: Wed, 24 Jun 2026 17:00:37 +0200 Subject: [PATCH 08/12] add comments; add a static import --- .../matsim/SimpleMatsimCommuteModeChoice.java | 50 +++++++++++-------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/extensions/matsim2silo/src/main/java/de/tum/bgu/msm/matsim/SimpleMatsimCommuteModeChoice.java b/extensions/matsim2silo/src/main/java/de/tum/bgu/msm/matsim/SimpleMatsimCommuteModeChoice.java index e4c748414..079ce9ae2 100644 --- a/extensions/matsim2silo/src/main/java/de/tum/bgu/msm/matsim/SimpleMatsimCommuteModeChoice.java +++ b/extensions/matsim2silo/src/main/java/de/tum/bgu/msm/matsim/SimpleMatsimCommuteModeChoice.java @@ -21,6 +21,8 @@ import java.util.*; +import static org.matsim.api.core.v01.TransportMode.*; + /** * Copy of SimpleCommuteModeChoice, but with person in argument of travel time request */ @@ -32,8 +34,7 @@ public class SimpleMatsimCommuteModeChoice implements CommuteModeChoice { private final GeoData geoData; private final Random random; - public SimpleMatsimCommuteModeChoice(DataContainer dataContainer, - Properties properties, Random random) { + public SimpleMatsimCommuteModeChoice(DataContainer dataContainer, Properties properties, Random random) { this.properties = properties; this.commutingTimeProbability = dataContainer.getCommutingTimeProbability(); this.jobDataManager = dataContainer.getJobDataManager(); @@ -50,25 +51,27 @@ public CommuteModeChoiceMapping assignCommuteModeChoice(Location from, TravelTim Map> commuteModesByPerson = new LinkedHashMap<>(); TreeMap personByProbability = new TreeMap<>(); + // I think that the following assigns, for each member of the hh, logit probabilities based on travel time for pt and, if available, car. for (Person pp : household.getPersons().values()) { if (pp.getOccupation() == Occupation.EMPLOYED && pp.getJobId() != -2) { + // (yy what is encoded by "-2"?) Job job = jobDataManager.getJobFromId(pp.getJobId()); // TODO clean up the following line - int ptMinutes = (int) ((MatsimTravelTimesAndCosts) travelTimes).getTravelTime(from, job, job.getStartTimeInSeconds().orElse((int) properties.transportModel.peakHour_s), TransportMode.pt, pp); - double ptUtility = commutingTimeProbability.getCommutingTimeProbability(ptMinutes, TransportMode.pt); + int ptMinutes = (int) ((MatsimTravelTimesAndCosts) travelTimes).getTravelTime(from, job, job.getStartTimeInSeconds().orElse((int) properties.transportModel.peakHour_s), pt, pp); + double ptUtility = commutingTimeProbability.getCommutingTimeProbability(ptMinutes, pt); if (!pp.hasDriverLicense() || (int) household.getVehicles().stream().filter(vv -> vv.getType().equals(VehicleType.CAR)).count() == 0) { - CommuteModeChoiceMapping.CommuteMode ptCommuteMode = new CommuteModeChoiceMapping.CommuteMode(TransportMode.pt, ptUtility); + CommuteModeChoiceMapping.CommuteMode ptCommuteMode = new CommuteModeChoiceMapping.CommuteMode( pt, ptUtility); commuteModeChoiceMapping.assignMode(ptCommuteMode, pp); } else { // TODO clean up the following line - int carMinutes = (int) ((MatsimTravelTimesAndCosts) travelTimes).getTravelTime(from, job, job.getStartTimeInSeconds().orElse((int) properties.transportModel.peakHour_s), TransportMode.car, pp); - double carUtility = commutingTimeProbability.getCommutingTimeProbability(carMinutes, TransportMode.car); + int carMinutes = (int) ((MatsimTravelTimesAndCosts) travelTimes).getTravelTime(from, job, job.getStartTimeInSeconds().orElse((int) properties.transportModel.peakHour_s), car, pp); + double carUtility = commutingTimeProbability.getCommutingTimeProbability(carMinutes, car); Map utilityByMode = new LinkedHashMap<>(); - utilityByMode.put(TransportMode.car, carUtility); - utilityByMode.put(TransportMode.pt, ptUtility); + utilityByMode.put( car, carUtility ); + utilityByMode.put( pt, ptUtility ); commuteModesByPerson.put(pp.getId(), utilityByMode); double probabilityAsKey; if (carUtility == 0 && ptUtility == 0) { @@ -78,6 +81,8 @@ public CommuteModeChoiceMapping assignCommuteModeChoice(Location from, TravelTim } while (personByProbability.containsKey(probabilityAsKey)) { //more than one hh member has exactly the same probability, so it would be replaced in the treemap + // (forcing the carMinutes to (int) much increases the risk that this happens!! kai, apr'26) + // (random.nextDouble() is quite large to alleviate this problem. kai, apr'26) probabilityAsKey += random.nextDouble(); } personByProbability.put(probabilityAsKey, pp); @@ -87,17 +92,18 @@ public CommuteModeChoiceMapping assignCommuteModeChoice(Location from, TravelTim int counter = (int) household.getVehicles().stream().filter(vv -> vv.getType().equals(VehicleType.CAR)).count(); + // The following goes through the hh members in decreasing proba, and assigns car with the logit proba as long as cars are available in the HH: for (Map.Entry personForProbability : personByProbability.descendingMap().entrySet()) { Person person = personForProbability.getValue(); CommuteModeChoiceMapping.CommuteMode commuteMode; if (counter == 0) { - commuteMode = new CommuteModeChoiceMapping.CommuteMode(TransportMode.pt, commuteModesByPerson.get(person.getId()).get(TransportMode.pt)); + commuteMode = new CommuteModeChoiceMapping.CommuteMode( pt, commuteModesByPerson.get(person.getId() ).get( pt )); } else { if (random.nextDouble() < personForProbability.getKey()) { - commuteMode = new CommuteModeChoiceMapping.CommuteMode(TransportMode.car, commuteModesByPerson.get(person.getId()).get(TransportMode.car)); + commuteMode = new CommuteModeChoiceMapping.CommuteMode( car, commuteModesByPerson.get(person.getId() ).get( car )); counter--; } else { - commuteMode = new CommuteModeChoiceMapping.CommuteMode(TransportMode.pt, commuteModesByPerson.get(person.getId()).get(TransportMode.pt)); + commuteMode = new CommuteModeChoiceMapping.CommuteMode( pt, commuteModesByPerson.get(person.getId() ).get( pt )); } } commuteModeChoiceMapping.assignMode(commuteMode, person); @@ -122,18 +128,18 @@ public CommuteModeChoiceMapping assignRegionalCommuteModeChoice(Region region, T Zone jobZone = geoData.getZones().get(job.getZoneId()); - int ptMinutes = (int) travelTimes.getTravelTimeFromRegion(region, jobZone, job.getStartTimeInSeconds().orElse((int) properties.transportModel.peakHour_s), TransportMode.pt); - double ptUtility = commutingTimeProbability.getCommutingTimeProbability(ptMinutes, TransportMode.pt); + int ptMinutes = (int) travelTimes.getTravelTimeFromRegion(region, jobZone, job.getStartTimeInSeconds().orElse((int) properties.transportModel.peakHour_s), pt); + double ptUtility = commutingTimeProbability.getCommutingTimeProbability(ptMinutes, pt); if (!pp.hasDriverLicense() || (int) household.getVehicles().stream().filter(vv -> vv.getType().equals(VehicleType.CAR)).count() == 0) { - CommuteModeChoiceMapping.CommuteMode ptCommuteMode = new CommuteModeChoiceMapping.CommuteMode(TransportMode.pt, ptUtility); + CommuteModeChoiceMapping.CommuteMode ptCommuteMode = new CommuteModeChoiceMapping.CommuteMode( pt, ptUtility); commuteModeChoiceMapping.assignMode(ptCommuteMode, pp); } else { - int carMinutes = (int) travelTimes.getTravelTimeFromRegion(region, jobZone, job.getStartTimeInSeconds().orElse((int) properties.transportModel.peakHour_s), TransportMode.car); - double carUtility = commutingTimeProbability.getCommutingTimeProbability(carMinutes, TransportMode.car); + int carMinutes = (int) travelTimes.getTravelTimeFromRegion(region, jobZone, job.getStartTimeInSeconds().orElse((int) properties.transportModel.peakHour_s), car); + double carUtility = commutingTimeProbability.getCommutingTimeProbability(carMinutes, car); Map utilityByMode = new LinkedHashMap<>(); - utilityByMode.put(TransportMode.car, carUtility); - utilityByMode.put(TransportMode.pt, ptUtility); + utilityByMode.put( car, carUtility ); + utilityByMode.put( pt, ptUtility ); commuteModesByPerson.put(pp.getId(), utilityByMode); double probabilityAsKey; if (carUtility == 0 && ptUtility == 0) { @@ -156,13 +162,13 @@ public CommuteModeChoiceMapping assignRegionalCommuteModeChoice(Region region, T Person person = personForProbability.getValue(); CommuteModeChoiceMapping.CommuteMode commuteMode; if (counter == 0) { - commuteMode = new CommuteModeChoiceMapping.CommuteMode(TransportMode.pt, commuteModesByPerson.get(person.getId()).get(TransportMode.pt)); + commuteMode = new CommuteModeChoiceMapping.CommuteMode( pt, commuteModesByPerson.get(person.getId() ).get( pt )); } else { if (random.nextDouble() < personForProbability.getKey()) { - commuteMode = new CommuteModeChoiceMapping.CommuteMode(TransportMode.car, commuteModesByPerson.get(person.getId()).get(TransportMode.car)); + commuteMode = new CommuteModeChoiceMapping.CommuteMode( car, commuteModesByPerson.get(person.getId() ).get( car )); counter--; } else { - commuteMode = new CommuteModeChoiceMapping.CommuteMode(TransportMode.pt, commuteModesByPerson.get(person.getId()).get(TransportMode.pt)); + commuteMode = new CommuteModeChoiceMapping.CommuteMode( pt, commuteModesByPerson.get(person.getId() ).get( pt )); } } commuteModeChoiceMapping.assignMode(commuteMode, person); From 73ed6b22c2f7846daec4019d56ac117b9661d4d2 Mon Sep 17 00:00:00 2001 From: Kai Nagel Date: Wed, 24 Jun 2026 17:01:19 +0200 Subject: [PATCH 09/12] attempt at simplified version --- .../run/ModelBuilderFabilandSimplified.java | 224 ++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 useCases/fabiland/src/main/java/run/ModelBuilderFabilandSimplified.java diff --git a/useCases/fabiland/src/main/java/run/ModelBuilderFabilandSimplified.java b/useCases/fabiland/src/main/java/run/ModelBuilderFabilandSimplified.java new file mode 100644 index 000000000..cbb222918 --- /dev/null +++ b/useCases/fabiland/src/main/java/run/ModelBuilderFabilandSimplified.java @@ -0,0 +1,224 @@ +package run; + +import de.tum.bgu.msm.container.DataContainer; +import de.tum.bgu.msm.container.ModelContainer; +import de.tum.bgu.msm.data.Region; +import de.tum.bgu.msm.data.dwelling.Dwelling; +import de.tum.bgu.msm.data.dwelling.DwellingFactory; +import de.tum.bgu.msm.data.household.Household; +import de.tum.bgu.msm.data.household.HouseholdFactory; +import de.tum.bgu.msm.data.person.PersonFactory; +import de.tum.bgu.msm.events.impls.household.MoveEvent; +import de.tum.bgu.msm.matsim.*; +import de.tum.bgu.msm.models.autoOwnership.CreateCarOwnershipModel; +import de.tum.bgu.msm.models.demography.birth.BirthModel; +import de.tum.bgu.msm.models.demography.birth.BirthModelImpl; +import de.tum.bgu.msm.models.demography.birth.DefaultBirthStrategy; +import de.tum.bgu.msm.models.demography.birthday.BirthdayModel; +import de.tum.bgu.msm.models.demography.birthday.BirthdayModelImpl; +import de.tum.bgu.msm.models.demography.death.DeathModel; +import de.tum.bgu.msm.models.demography.death.DeathModelImpl; +import de.tum.bgu.msm.models.demography.death.DefaultDeathStrategy; +import de.tum.bgu.msm.models.demography.divorce.DefaultDivorceStrategy; +import de.tum.bgu.msm.models.demography.divorce.DivorceModel; +import de.tum.bgu.msm.models.demography.divorce.DivorceModelImpl; +import de.tum.bgu.msm.models.demography.driversLicense.DefaultDriversLicenseStrategy; +import de.tum.bgu.msm.models.demography.driversLicense.DriversLicenseModel; +import de.tum.bgu.msm.models.demography.driversLicense.DriversLicenseModelImpl; +import de.tum.bgu.msm.models.demography.education.EducationModel; +import de.tum.bgu.msm.models.demography.education.EducationModelImpl; +import de.tum.bgu.msm.models.demography.employment.EmploymentModel; +import de.tum.bgu.msm.models.demography.employment.EmploymentModelImpl; +import de.tum.bgu.msm.models.demography.leaveParentalHousehold.DefaultLeaveParentalHouseholdStrategy; +import de.tum.bgu.msm.models.demography.leaveParentalHousehold.LeaveParentHhModel; +import de.tum.bgu.msm.models.demography.leaveParentalHousehold.LeaveParentHhModelImpl; +import de.tum.bgu.msm.models.demography.marriage.DefaultMarriageStrategy; +import de.tum.bgu.msm.models.demography.marriage.MarriageModel; +import de.tum.bgu.msm.models.demography.marriage.MarriageModelImpl; +import de.tum.bgu.msm.models.jobmography.JobMarketUpdate; +import de.tum.bgu.msm.models.jobmography.JobMarketUpdateImpl; +import de.tum.bgu.msm.models.realEstate.construction.*; +import de.tum.bgu.msm.models.realEstate.demolition.DefaultDemolitionStrategy; +import de.tum.bgu.msm.models.realEstate.demolition.DemolitionModel; +import de.tum.bgu.msm.models.realEstate.demolition.DemolitionModelImpl; +import de.tum.bgu.msm.models.realEstate.pricing.DefaultPricingStrategy; +import de.tum.bgu.msm.models.realEstate.pricing.PricingModel; +import de.tum.bgu.msm.models.realEstate.pricing.PricingModelImpl; +import de.tum.bgu.msm.models.realEstate.renovation.DefaultRenovationStrategy; +import de.tum.bgu.msm.models.realEstate.renovation.RenovationModel; +import de.tum.bgu.msm.models.realEstate.renovation.RenovationModelImpl; +import de.tum.bgu.msm.models.relocation.migration.InOutMigration; +import de.tum.bgu.msm.models.relocation.migration.InOutMigrationImpl; +import de.tum.bgu.msm.models.relocation.moves.*; +import de.tum.bgu.msm.models.transportModel.TransportModel; +import de.tum.bgu.msm.properties.Properties; +import de.tum.bgu.msm.utils.SiloUtil; +import models.FabilandConstructionLocationStrategy; +import org.matsim.api.core.v01.Scenario; +import org.matsim.core.config.Config; +import org.matsim.core.scenario.ScenarioUtils; + +import java.util.Collection; +import java.util.Random; + +import static de.tum.bgu.msm.matsim.SimpleCommuteModeChoiceMatsimScenarioAssembler.HandlingOfRandomness; + +public class ModelBuilderFabilandSimplified{ + + public static ModelContainer getModelContainer(DataContainer dataContainer, Properties properties, Config config) { + + final PersonFactory ppFactory = dataContainer.getHouseholdDataManager().getPersonFactory(); + final HouseholdFactory hhFactory = dataContainer.getHouseholdDataManager().getHouseholdFactory(); + final DwellingFactory ddFactory = dataContainer.getRealEstateDataManager().getDwellingFactory(); + + final BirthModel birthModel = new BirthModelImpl(dataContainer, ppFactory, properties, new DefaultBirthStrategy(), SiloUtil.provideNewRandom()); + + final BirthdayModel birthdayModel = new BirthdayModelImpl(dataContainer, properties, SiloUtil.provideNewRandom()); + + final DeathModel deathModel = new DeathModelImpl(dataContainer, properties, new DefaultDeathStrategy(), SiloUtil.provideNewRandom()); + + final HousingStrategy housingStrategy = new SimpleCommuteModeChoiceHousingStrategyImpl( dataContainer, + properties, + dataContainer.getTravelTimes(), + new DwellingUtilityStrategyImpl(), + utl -> Math.exp(0.5*utl) , + new RegionUtilityStrategyImpl(), + utl -> Math.exp(0.5*utl) , + new SimpleMatsimCommuteModeChoice( dataContainer, properties, SiloUtil.provideNewRandom() ) + ); + + final HousingStrategy housingStrategy2 = new HousingStrategy(){ + @Override public void setup(){ + // probably ok to do nothing + } + @Override public void prepareYear(){ + // probably ok to do nothing + } + + @Override public boolean isHouseholdEligibleToLiveHere( Household household, Dwelling dd ){ + return true; + } + + @Override public double calculateHousingUtility( Household hh, Dwelling dwelling ){ + return 1.; + } + @Override public double calculateSelectDwellingProbability( double util ){ + return Math.exp( 0.5 * util ); + } + + @Override public double calculateRegionalUtility( Household household, Region region ){ + return 1.; + } + @Override public double calculateSelectRegionProbability( double util ){ + return Math.exp( 0.5 * util ); + } + + @Override public HousingStrategy duplicate(){ + throw new RuntimeException( "not implemented" ); + } + }; + // (( Ich weiss nicht, warum die utilities offen gelegt werden, weil sie eigentlich nur über die proba functions (die ja oben im + // ctor stehen) angesprochen werden. Vllt könnten die protected sein, dann würde das noch schmaler werden. + // (--> nein, geht nicht, wird an wenigen Stellen auch ausserhalb verwendet. (Da werden die Nutzen aufsummiert; das könnte + // man vllt auch per "ln" aus den probas reverse engineeren. Aber so viel design change wollen wir vllt nicht.) )) + + final MovesModel movesModel = new MovesModelImpl( dataContainer, properties, new DefaultMovesStrategy(), housingStrategy, SiloUtil.provideNewRandom()); + + final MovesModel movesModel2 = new AbstractMovesModel( dataContainer, properties, SiloUtil.provideNewRandom() ) { + @Override public Collection getEventsForCurrentYear( int year ){ + throw new RuntimeException( "not implemented" ); + } + @Override public boolean handleEvent( MoveEvent event ){ + throw new RuntimeException( "not implemented" ); + } + @Override public int searchForNewDwelling( Household household ){ + return -1; // means no dwelling was found + } + }; + + final CreateCarOwnershipModel carOwnershipModel = new FabilandCarOwnership(); + + final DivorceModel divorceModel = new DivorceModelImpl( + dataContainer, movesModel, carOwnershipModel, hhFactory, + properties, new DefaultDivorceStrategy(), SiloUtil.provideNewRandom()); + + final DriversLicenseModel driversLicenseModel = new DriversLicenseModelImpl(dataContainer, properties, new DefaultDriversLicenseStrategy(), SiloUtil.provideNewRandom()); + + final EducationModel educationModel = new EducationModelImpl(dataContainer, properties, SiloUtil.provideNewRandom()); + + final EmploymentModel employmentModel = new EmploymentModelImpl(dataContainer, properties, SiloUtil.provideNewRandom()); + + final LeaveParentHhModel leaveParentsModel = new LeaveParentHhModelImpl(dataContainer, movesModel, + carOwnershipModel, hhFactory, properties, new DefaultLeaveParentalHouseholdStrategy(), SiloUtil.provideNewRandom()); + + final JobMarketUpdate jobMarketUpdateModel = new JobMarketUpdateImpl(dataContainer, properties, SiloUtil.provideNewRandom()); + +// ConstructionModel construction = new ConstructionModelImpl(dataContainer, ddFactory, +// properties, new FabilandConstructionLocationStrategy(), new DefaultConstructionDemandStrategy(), SiloUtil.provideNewRandom()); + + final PricingModel pricing = new PricingModelImpl(dataContainer, properties, new DefaultPricingStrategy(), SiloUtil.provideNewRandom()); + +// RenovationModel renovation = new RenovationModelImpl(dataContainer, properties, new DefaultRenovationStrategy(), SiloUtil.provideNewRandom()); + + final ConstructionOverwrite constructionOverwrite = new ConstructionOverwriteImpl(dataContainer, ddFactory, properties, SiloUtil.provideNewRandom()); + + final InOutMigration inOutMigration = new InOutMigrationImpl(dataContainer, employmentModel, movesModel, + carOwnershipModel, driversLicenseModel, properties, SiloUtil.provideNewRandom()); + +// DemolitionModel demolition = new DemolitionModelImpl(dataContainer, movesModel, +// inOutMigration, properties, new DefaultDemolitionStrategy(), SiloUtil.provideNewRandom()); + + final MarriageModel marriageModel = new MarriageModelImpl(dataContainer, movesModel, inOutMigration, + carOwnershipModel, hhFactory, properties, new DefaultMarriageStrategy(), SiloUtil.provideNewRandom()); + + TransportModel transportModel; + MatsimScenarioAssembler scenarioAssembler; + + MatsimData matsimData = null; + if (config != null) { + final Scenario scenario = ScenarioUtils.loadScenario(config); + matsimData = new MatsimData(config, properties, ZoneConnectorManagerImpl.ZoneConnectorMethod.WEIGHTED_BY_POPULATION, dataContainer, scenario.getNetwork(), scenario.getTransitSchedule()); + } + switch (properties.transportModel.transportModelIdentifier) { + case MATSIM: +// SimpleCommuteModeChoice commuteModeChoice = new SimpleCommuteModeChoice(dataContainer, properties, SiloUtil.provideNewRandom()); + SimpleMatsimCommuteModeChoice commuteModeChoice = new SimpleMatsimCommuteModeChoice(dataContainer, properties, SiloUtil.provideNewRandom()); + scenarioAssembler = new SimpleCommuteModeChoiceMatsimScenarioAssembler(dataContainer, properties, commuteModeChoice, HandlingOfRandomness.localInstanceFromMatsimWithAlwaysSameSeed); + transportModel = new MatsimTransportModel(dataContainer, config, properties, scenarioAssembler, matsimData); + break; + case NONE: + default: + transportModel = null; + } + + final ModelContainer modelContainer = new ModelContainer( + birthModel, birthdayModel, + deathModel, marriageModel, + divorceModel, driversLicenseModel, + educationModel, employmentModel, + leaveParentsModel, jobMarketUpdateModel, + null, null, pricing, null, + constructionOverwrite, inOutMigration, movesModel, transportModel); + + return modelContainer; + } + + private static class FabilandCarOwnership implements CreateCarOwnershipModel { + + private final Random random; + + FabilandCarOwnership() { + this.random = SiloUtil.provideNewRandom(); + } + + @Override + public void run() { + + } + + @Override + public void simulateCarOwnership(Household hh) { + hh.setAutos(random.nextInt(3)+1); + } + } +} From ff31fc7c71e5ed15db7ad80a2e847e0e4b7a24a4 Mon Sep 17 00:00:00 2001 From: Kai Nagel Date: Thu, 25 Jun 2026 10:26:23 +0200 Subject: [PATCH 10/12] simplified version --- .../de/tum/bgu/msm/matsim/MatsimData.java | 48 ++++------- .../run/ModelBuilderFabilandSimplified.java | 85 ++++++------------- 2 files changed, 45 insertions(+), 88 deletions(-) diff --git a/extensions/matsim2silo/src/main/java/de/tum/bgu/msm/matsim/MatsimData.java b/extensions/matsim2silo/src/main/java/de/tum/bgu/msm/matsim/MatsimData.java index 19965bc06..5337a044b 100644 --- a/extensions/matsim2silo/src/main/java/de/tum/bgu/msm/matsim/MatsimData.java +++ b/extensions/matsim2silo/src/main/java/de/tum/bgu/msm/matsim/MatsimData.java @@ -74,21 +74,15 @@ public MatsimData(Config config, Properties properties, ZoneConnectorManagerImpl int threads = properties.main.numberOfThreads; final Collection zones = dataContainer.getGeoData().getZones().values(); - ZoneConnectorManager zoneConnectorManager; - switch (method) { - case RANDOM: - zoneConnectorManager = ZoneConnectorManagerImpl.createRandomZoneConnectors(zones, NUMBER_OF_CALC_POINTS); - break; - case WEIGHTED_BY_POPULATION: - zoneConnectorManager = ZoneConnectorManagerImpl.createWeightedZoneConnectors(zones, - dataContainer.getRealEstateDataManager(), - dataContainer.getHouseholdDataManager()); - break; - default: - throw new RuntimeException("No valid zone connector method defined!"); - } - - ConfigUtils.setVspDefaults(config); // Needs to be done before config becomes locked for those changes + ZoneConnectorManager zoneConnectorManager = switch( method ){ + case RANDOM -> ZoneConnectorManagerImpl.createRandomZoneConnectors( zones, NUMBER_OF_CALC_POINTS ); + case WEIGHTED_BY_POPULATION -> ZoneConnectorManagerImpl.createWeightedZoneConnectors( zones, + dataContainer.getRealEstateDataManager(), + dataContainer.getHouseholdDataManager() ); + default -> throw new RuntimeException( "No valid zone connector method defined!" ); + }; + + ConfigUtils.setVspDefaults(config); // Needs to be done before config becomes locked for those changes this.raptorParameters = RaptorUtils.createParameters(config); this.nThreads = threads; this.zoneConnectorManager = zoneConnectorManager; @@ -106,21 +100,15 @@ public MatsimData(Config config, Properties properties, ZoneConnectorManagerImpl int threads = properties.main.numberOfThreads; final Collection zones = dataContainer.getGeoData().getZones().values(); - ZoneConnectorManager zoneConnectorManager; - switch (method) { - case RANDOM: - zoneConnectorManager = ZoneConnectorManagerImpl.createRandomZoneConnectors(zones, NUMBER_OF_CALC_POINTS); - break; - case WEIGHTED_BY_POPULATION: - zoneConnectorManager = ZoneConnectorManagerImpl.createWeightedZoneConnectors(zones, - dataContainer.getRealEstateDataManager(), - dataContainer.getHouseholdDataManager()); - break; - default: - throw new RuntimeException("No valid zone connector method defined!"); - } - - ConfigUtils.setVspDefaults(config); // Needs to be done before config becomes locked for those changes + ZoneConnectorManager zoneConnectorManager = switch( method ){ + case RANDOM -> ZoneConnectorManagerImpl.createRandomZoneConnectors( zones, NUMBER_OF_CALC_POINTS ); + case WEIGHTED_BY_POPULATION -> ZoneConnectorManagerImpl.createWeightedZoneConnectors( zones, + dataContainer.getRealEstateDataManager(), + dataContainer.getHouseholdDataManager() ); + default -> throw new RuntimeException( "No valid zone connector method defined!" ); + }; + + ConfigUtils.setVspDefaults(config); // Needs to be done before config becomes locked for those changes this.nThreads = threads; this.zoneConnectorManager = zoneConnectorManager; filterNetwork(network); diff --git a/useCases/fabiland/src/main/java/run/ModelBuilderFabilandSimplified.java b/useCases/fabiland/src/main/java/run/ModelBuilderFabilandSimplified.java index cbb222918..5a29bc9d8 100644 --- a/useCases/fabiland/src/main/java/run/ModelBuilderFabilandSimplified.java +++ b/useCases/fabiland/src/main/java/run/ModelBuilderFabilandSimplified.java @@ -59,9 +59,11 @@ import org.matsim.core.scenario.ScenarioUtils; import java.util.Collection; +import java.util.Collections; import java.util.Random; import static de.tum.bgu.msm.matsim.SimpleCommuteModeChoiceMatsimScenarioAssembler.HandlingOfRandomness; +import static de.tum.bgu.msm.matsim.ZoneConnectorManagerImpl.*; public class ModelBuilderFabilandSimplified{ @@ -77,72 +79,44 @@ public static ModelContainer getModelContainer(DataContainer dataContainer, Prop final DeathModel deathModel = new DeathModelImpl(dataContainer, properties, new DefaultDeathStrategy(), SiloUtil.provideNewRandom()); - final HousingStrategy housingStrategy = new SimpleCommuteModeChoiceHousingStrategyImpl( dataContainer, - properties, - dataContainer.getTravelTimes(), - new DwellingUtilityStrategyImpl(), - utl -> Math.exp(0.5*utl) , - new RegionUtilityStrategyImpl(), - utl -> Math.exp(0.5*utl) , - new SimpleMatsimCommuteModeChoice( dataContainer, properties, SiloUtil.provideNewRandom() ) - ); - - final HousingStrategy housingStrategy2 = new HousingStrategy(){ - @Override public void setup(){ - // probably ok to do nothing - } - @Override public void prepareYear(){ - // probably ok to do nothing - } - - @Override public boolean isHouseholdEligibleToLiveHere( Household household, Dwelling dd ){ - return true; - } - - @Override public double calculateHousingUtility( Household hh, Dwelling dwelling ){ - return 1.; + final MovesModel movesModel = new MovesModel(){ + @Override public int searchForNewDwelling( Household household ){ + return -1; // means no dwelling was found } - @Override public double calculateSelectDwellingProbability( double util ){ - return Math.exp( 0.5 * util ); + @Override public void moveHousehold( Household hh, int idOldDD, int idNewDD ){ + // do nothing } - - @Override public double calculateRegionalUtility( Household household, Region region ){ - return 1.; + @Override public Collection getEventsForCurrentYear( int year ){ + return Collections.emptyList(); } - @Override public double calculateSelectRegionProbability( double util ){ - return Math.exp( 0.5 * util ); + @Override public boolean handleEvent( MoveEvent event ){ + // this should not happen. Maybe test? + // If this is needed, one cold use MovesModelImpl as a delegate and then go from there. + return false; } - - @Override public HousingStrategy duplicate(){ - throw new RuntimeException( "not implemented" ); + @Override public void setup(){ + // do nothing } - }; - // (( Ich weiss nicht, warum die utilities offen gelegt werden, weil sie eigentlich nur über die proba functions (die ja oben im - // ctor stehen) angesprochen werden. Vllt könnten die protected sein, dann würde das noch schmaler werden. - // (--> nein, geht nicht, wird an wenigen Stellen auch ausserhalb verwendet. (Da werden die Nutzen aufsummiert; das könnte - // man vllt auch per "ln" aus den probas reverse engineeren. Aber so viel design change wollen wir vllt nicht.) )) - - final MovesModel movesModel = new MovesModelImpl( dataContainer, properties, new DefaultMovesStrategy(), housingStrategy, SiloUtil.provideNewRandom()); - - final MovesModel movesModel2 = new AbstractMovesModel( dataContainer, properties, SiloUtil.provideNewRandom() ) { - @Override public Collection getEventsForCurrentYear( int year ){ - throw new RuntimeException( "not implemented" ); + @Override public void prepareYear( int year ){ + // do nothing } - @Override public boolean handleEvent( MoveEvent event ){ - throw new RuntimeException( "not implemented" ); + @Override public void endYear( int year ){ + // do nothing } - @Override public int searchForNewDwelling( Household household ){ - return -1; // means no dwelling was found + @Override public void endSimulation(){ + // do nothing } }; final CreateCarOwnershipModel carOwnershipModel = new FabilandCarOwnership(); + // yy (for VSP purposes, car ownership could also be done by matsim) final DivorceModel divorceModel = new DivorceModelImpl( dataContainer, movesModel, carOwnershipModel, hhFactory, properties, new DefaultDivorceStrategy(), SiloUtil.provideNewRandom()); final DriversLicenseModel driversLicenseModel = new DriversLicenseModelImpl(dataContainer, properties, new DefaultDriversLicenseStrategy(), SiloUtil.provideNewRandom()); + // yy for VSP purposes, this might not be needed final EducationModel educationModel = new EducationModelImpl(dataContainer, properties, SiloUtil.provideNewRandom()); @@ -153,21 +127,13 @@ public static ModelContainer getModelContainer(DataContainer dataContainer, Prop final JobMarketUpdate jobMarketUpdateModel = new JobMarketUpdateImpl(dataContainer, properties, SiloUtil.provideNewRandom()); -// ConstructionModel construction = new ConstructionModelImpl(dataContainer, ddFactory, -// properties, new FabilandConstructionLocationStrategy(), new DefaultConstructionDemandStrategy(), SiloUtil.provideNewRandom()); - final PricingModel pricing = new PricingModelImpl(dataContainer, properties, new DefaultPricingStrategy(), SiloUtil.provideNewRandom()); -// RenovationModel renovation = new RenovationModelImpl(dataContainer, properties, new DefaultRenovationStrategy(), SiloUtil.provideNewRandom()); - final ConstructionOverwrite constructionOverwrite = new ConstructionOverwriteImpl(dataContainer, ddFactory, properties, SiloUtil.provideNewRandom()); final InOutMigration inOutMigration = new InOutMigrationImpl(dataContainer, employmentModel, movesModel, carOwnershipModel, driversLicenseModel, properties, SiloUtil.provideNewRandom()); -// DemolitionModel demolition = new DemolitionModelImpl(dataContainer, movesModel, -// inOutMigration, properties, new DefaultDemolitionStrategy(), SiloUtil.provideNewRandom()); - final MarriageModel marriageModel = new MarriageModelImpl(dataContainer, movesModel, inOutMigration, carOwnershipModel, hhFactory, properties, new DefaultMarriageStrategy(), SiloUtil.provideNewRandom()); @@ -177,12 +143,15 @@ public static ModelContainer getModelContainer(DataContainer dataContainer, Prop MatsimData matsimData = null; if (config != null) { final Scenario scenario = ScenarioUtils.loadScenario(config); - matsimData = new MatsimData(config, properties, ZoneConnectorManagerImpl.ZoneConnectorMethod.WEIGHTED_BY_POPULATION, dataContainer, scenario.getNetwork(), scenario.getTransitSchedule()); + matsimData = new MatsimData(config, properties, ZoneConnectorMethod.WEIGHTED_BY_POPULATION, dataContainer, scenario.getNetwork(), scenario.getTransitSchedule()); + // (only the constructor is deprecated) } switch (properties.transportModel.transportModelIdentifier) { case MATSIM: // SimpleCommuteModeChoice commuteModeChoice = new SimpleCommuteModeChoice(dataContainer, properties, SiloUtil.provideNewRandom()); SimpleMatsimCommuteModeChoice commuteModeChoice = new SimpleMatsimCommuteModeChoice(dataContainer, properties, SiloUtil.provideNewRandom()); + // (for VSP purposes, this might not be needed) + scenarioAssembler = new SimpleCommuteModeChoiceMatsimScenarioAssembler(dataContainer, properties, commuteModeChoice, HandlingOfRandomness.localInstanceFromMatsimWithAlwaysSameSeed); transportModel = new MatsimTransportModel(dataContainer, config, properties, scenarioAssembler, matsimData); break; From 0f08fb8fb12dd897f0fec7386cddb4f996b5e8b9 Mon Sep 17 00:00:00 2001 From: Kai Nagel Date: Thu, 25 Jun 2026 10:27:00 +0200 Subject: [PATCH 11/12] indentation --- .../de/tum/bgu/msm/matsim/MatsimData.java | 268 +++++++++--------- 1 file changed, 134 insertions(+), 134 deletions(-) diff --git a/extensions/matsim2silo/src/main/java/de/tum/bgu/msm/matsim/MatsimData.java b/extensions/matsim2silo/src/main/java/de/tum/bgu/msm/matsim/MatsimData.java index 5337a044b..ce3331d87 100644 --- a/extensions/matsim2silo/src/main/java/de/tum/bgu/msm/matsim/MatsimData.java +++ b/extensions/matsim2silo/src/main/java/de/tum/bgu/msm/matsim/MatsimData.java @@ -33,26 +33,26 @@ public final class MatsimData { private MutableScenario scenario; private LeastCostPathCalculatorFactory leastCostPathCalculatorFactory; - private final LeastCostPathCalculatorFactory multiNodeFactory = new FastMultiNodeDijkstraFactory(true); + private final LeastCostPathCalculatorFactory multiNodeFactory = new FastMultiNodeDijkstraFactory(true); - private SwissRailRaptorData raptorData; - private SwissRailRaptorData raptorDataOneToAll; + private SwissRailRaptorData raptorData; + private SwissRailRaptorData raptorDataOneToAll; - private final int nThreads; + private final int nThreads; private Network carNetwork; - private Network ptNetwork; + private Network ptNetwork; private RaptorParameters raptorParameters; - private DefaultRaptorParametersForPerson parametersForPerson; - private LeastCostRaptorRouteSelector routeSelector; - private DefaultRaptorStopFinder defaultRaptorStopFinder; + private DefaultRaptorParametersForPerson parametersForPerson; + private LeastCostRaptorRouteSelector routeSelector; + private DefaultRaptorStopFinder defaultRaptorStopFinder; - private TravelDisutility travelDisutility; - private TravelTime travelTime; + private TravelDisutility travelDisutility; + private TravelTime travelTime; - private final ZoneConnectorManager zoneConnectorManager; - private final static int NUMBER_OF_CALC_POINTS = 1; + private final ZoneConnectorManager zoneConnectorManager; + private final static int NUMBER_OF_CALC_POINTS = 1; // yyyyyy The TripRouter needs the vehicles container to work properly. This is provided to the TripRouter via the Scenario. In consequence, we need to maintain a somewhat // consistent scenario. @@ -68,132 +68,132 @@ public MatsimData( Properties properties, ZoneConnectorManager.ZoneConnectorMeth * @deprecated -- use {@link MatsimData#MatsimData(Properties, ZoneConnectorManager.ZoneConnectorMethod, DataContainer, MutableScenario)} */ @Deprecated - public MatsimData(Config config, Properties properties, ZoneConnectorManagerImpl.ZoneConnectorMethod method, DataContainer dataContainer, Network network, TransitSchedule schedule) { + public MatsimData(Config config, Properties properties, ZoneConnectorManagerImpl.ZoneConnectorMethod method, DataContainer dataContainer, Network network, TransitSchedule schedule) { this.scenario = ScenarioUtils.createMutableScenario( config ); this.scenario.setTransitSchedule( schedule ); - int threads = properties.main.numberOfThreads; - final Collection zones = dataContainer.getGeoData().getZones().values(); - ZoneConnectorManager zoneConnectorManager = switch( method ){ - case RANDOM -> ZoneConnectorManagerImpl.createRandomZoneConnectors( zones, NUMBER_OF_CALC_POINTS ); - case WEIGHTED_BY_POPULATION -> ZoneConnectorManagerImpl.createWeightedZoneConnectors( zones, - dataContainer.getRealEstateDataManager(), - dataContainer.getHouseholdDataManager() ); - default -> throw new RuntimeException( "No valid zone connector method defined!" ); - }; + int threads = properties.main.numberOfThreads; + final Collection zones = dataContainer.getGeoData().getZones().values(); + ZoneConnectorManager zoneConnectorManager = switch( method ){ + case RANDOM -> ZoneConnectorManagerImpl.createRandomZoneConnectors( zones, NUMBER_OF_CALC_POINTS ); + case WEIGHTED_BY_POPULATION -> ZoneConnectorManagerImpl.createWeightedZoneConnectors( zones, + dataContainer.getRealEstateDataManager(), + dataContainer.getHouseholdDataManager() ); + default -> throw new RuntimeException( "No valid zone connector method defined!" ); + }; ConfigUtils.setVspDefaults(config); // Needs to be done before config becomes locked for those changes this.raptorParameters = RaptorUtils.createParameters(config); - this.nThreads = threads; + this.nThreads = threads; this.zoneConnectorManager = zoneConnectorManager; - filterNetwork(network); - } + filterNetwork(network); + } /** * @deprecated -- use {@link MatsimData#MatsimData(Properties, ZoneConnectorManager.ZoneConnectorMethod, DataContainer, MutableScenario)} */ @Deprecated - public MatsimData(Config config, Properties properties, ZoneConnectorManagerImpl.ZoneConnectorMethod method, DataContainer dataContainer, Network network) { + public MatsimData(Config config, Properties properties, ZoneConnectorManagerImpl.ZoneConnectorMethod method, DataContainer dataContainer, Network network) { this.scenario = ScenarioUtils.createMutableScenario( config ); // yyyyyy MatsimData needs the scenario, everything else is stupid. kai - int threads = properties.main.numberOfThreads; - final Collection zones = dataContainer.getGeoData().getZones().values(); - ZoneConnectorManager zoneConnectorManager = switch( method ){ - case RANDOM -> ZoneConnectorManagerImpl.createRandomZoneConnectors( zones, NUMBER_OF_CALC_POINTS ); - case WEIGHTED_BY_POPULATION -> ZoneConnectorManagerImpl.createWeightedZoneConnectors( zones, - dataContainer.getRealEstateDataManager(), - dataContainer.getHouseholdDataManager() ); - default -> throw new RuntimeException( "No valid zone connector method defined!" ); - }; + int threads = properties.main.numberOfThreads; + final Collection zones = dataContainer.getGeoData().getZones().values(); + ZoneConnectorManager zoneConnectorManager = switch( method ){ + case RANDOM -> ZoneConnectorManagerImpl.createRandomZoneConnectors( zones, NUMBER_OF_CALC_POINTS ); + case WEIGHTED_BY_POPULATION -> ZoneConnectorManagerImpl.createWeightedZoneConnectors( zones, + dataContainer.getRealEstateDataManager(), + dataContainer.getHouseholdDataManager() ); + default -> throw new RuntimeException( "No valid zone connector method defined!" ); + }; ConfigUtils.setVspDefaults(config); // Needs to be done before config becomes locked for those changes this.nThreads = threads; this.zoneConnectorManager = zoneConnectorManager; - filterNetwork(network); - } + filterNetwork(network); + } /** * @deprecated -- use {@link MatsimData#MatsimData(Properties, ZoneConnectorManager.ZoneConnectorMethod, DataContainer, MutableScenario)} */ @Deprecated - public MatsimData(Config config, int threads,Network network, TransitSchedule schedule, ZoneConnectorManager zoneConnectorManager) { + public MatsimData(Config config, int threads,Network network, TransitSchedule schedule, ZoneConnectorManager zoneConnectorManager) { this.scenario = ScenarioUtils.createMutableScenario( config ); this.scenario.setTransitSchedule( schedule ); - ConfigUtils.setVspDefaults(config); // Needs to be done before config becomes locked for those changes + ConfigUtils.setVspDefaults(config); // Needs to be done before config becomes locked for those changes this.raptorParameters = RaptorUtils.createParameters(config); - this.nThreads = threads; + this.nThreads = threads; this.zoneConnectorManager = zoneConnectorManager; - filterNetwork(network); - } + filterNetwork(network); + } - public void filterNetwork(Network network) { - TransportModeNetworkFilter filter = new TransportModeNetworkFilter(network); + public void filterNetwork(Network network) { + TransportModeNetworkFilter filter = new TransportModeNetworkFilter(network); - Set car = Sets.newHashSet(TransportMode.car); - Set pt = Sets.newHashSet(TransportMode.pt, TransportMode.train, "bus", - "artificial", "subway", "tram", "rail"); + Set car = Sets.newHashSet(TransportMode.car); + Set pt = Sets.newHashSet(TransportMode.pt, TransportMode.train, "bus", + "artificial", "subway", "tram", "rail"); - Network carNetwork = NetworkUtils.createNetwork(); - filter.filter(carNetwork, car); + Network carNetwork = NetworkUtils.createNetwork(); + filter.filter(carNetwork, car); - Network ptNetwork = NetworkUtils.createNetwork(); - filter.filter(ptNetwork, pt); + Network ptNetwork = NetworkUtils.createNetwork(); + filter.filter(ptNetwork, pt); - this.carNetwork = carNetwork; - this.ptNetwork = ptNetwork; - } + this.carNetwork = carNetwork; + this.ptNetwork = ptNetwork; + } - ZoneConnectorManager getZoneConnectorManager() { - return zoneConnectorManager; - } + ZoneConnectorManager getZoneConnectorManager() { + return zoneConnectorManager; + } - public Network getCarNetwork() { - return carNetwork; - } + public Network getCarNetwork() { + return carNetwork; + } // Network getPtNetwork() { // return ptNetwork; // } // never used - public void update(TravelDisutility travelDisutility, TravelTime travelTime) { - this.travelDisutility = travelDisutility; - this.travelTime = travelTime; + public void update(TravelDisutility travelDisutility, TravelTime travelTime) { + this.travelDisutility = travelDisutility; + this.travelTime = travelTime; - this.leastCostPathCalculatorFactory = new AStarLandmarksFactory(nThreads); + this.leastCostPathCalculatorFactory = new AStarLandmarksFactory(nThreads); - if ( this.scenario.getConfig().transit().isUseTransit() && this.scenario.getTransitSchedule() != null) { - RaptorStaticConfig raptorConfig = RaptorUtils.createStaticConfig( this.scenario.getConfig() ); - Vehicles ptVehicles = null; - OccupancyData occupancyData = null; - raptorData = SwissRailRaptorData.create( this.scenario.getTransitSchedule(), ptVehicles, raptorConfig, ptNetwork, occupancyData ); + if ( this.scenario.getConfig().transit().isUseTransit() && this.scenario.getTransitSchedule() != null) { + RaptorStaticConfig raptorConfig = RaptorUtils.createStaticConfig( this.scenario.getConfig() ); + Vehicles ptVehicles = null; + OccupancyData occupancyData = null; + raptorData = SwissRailRaptorData.create( this.scenario.getTransitSchedule(), ptVehicles, raptorConfig, ptNetwork, occupancyData ); - RaptorStaticConfig raptorConfigOneToAll = RaptorUtils.createStaticConfig( this.scenario.getConfig() ); - raptorConfigOneToAll.setOptimization(RaptorStaticConfig.RaptorOptimization.OneToAllRouting); - raptorDataOneToAll = SwissRailRaptorData.create( this.scenario.getTransitSchedule(), ptVehicles, raptorConfig, ptNetwork, occupancyData ); + RaptorStaticConfig raptorConfigOneToAll = RaptorUtils.createStaticConfig( this.scenario.getConfig() ); + raptorConfigOneToAll.setOptimization(RaptorStaticConfig.RaptorOptimization.OneToAllRouting); + raptorDataOneToAll = SwissRailRaptorData.create( this.scenario.getTransitSchedule(), ptVehicles, raptorConfig, ptNetwork, occupancyData ); - parametersForPerson = new DefaultRaptorParametersForPerson( this.scenario.getConfig() ); - defaultRaptorStopFinder = new DefaultRaptorStopFinder( + parametersForPerson = new DefaultRaptorParametersForPerson( this.scenario.getConfig() ); + defaultRaptorStopFinder = new DefaultRaptorStopFinder( this.scenario.getConfig(), - new DefaultRaptorIntermodalAccessEgress(), - null); - routeSelector = new LeastCostRaptorRouteSelector(); - } - } - - MultiNodePathCalculator createMultiNodePathCalculator() { - return (MultiNodePathCalculator) multiNodeFactory.createPathCalculator(carNetwork, travelDisutility, travelTime); - } - - MultiNodePathCalculator createFreeSpeedMultiNodePathCalculator() { - FreespeedTravelTimeAndDisutility freespeed = new FreespeedTravelTimeAndDisutility( this.scenario.getConfig().scoring()); - return (MultiNodePathCalculator) multiNodeFactory.createPathCalculator(carNetwork, freespeed, freespeed); - } - - TripRouter createTripRouter() { + new DefaultRaptorIntermodalAccessEgress(), + null); + routeSelector = new LeastCostRaptorRouteSelector(); + } + } + + MultiNodePathCalculator createMultiNodePathCalculator() { + return (MultiNodePathCalculator) multiNodeFactory.createPathCalculator(carNetwork, travelDisutility, travelTime); + } + + MultiNodePathCalculator createFreeSpeedMultiNodePathCalculator() { + FreespeedTravelTimeAndDisutility freespeed = new FreespeedTravelTimeAndDisutility( this.scenario.getConfig().scoring()); + return (MultiNodePathCalculator) multiNodeFactory.createPathCalculator(carNetwork, freespeed, freespeed); + } + + TripRouter createTripRouter() { // Scenario scenario = ScenarioUtils.loadScenario(config); com.google.inject.Injector injector = Injector.createMinimalMatsimInjector( this.scenario.getConfig(), scenario ); @@ -234,52 +234,52 @@ TripRouter createTripRouter() { // bd.setRoutingModule(TransportMode.car, carRoutingModule); // bd.setRoutingModule(TransportMode.pt, ptRoutingModule); // return bd.build(); - } - - SwissRailRaptor createSwissRailRaptor(RaptorStaticConfig.RaptorOptimization optimitzaion) { - - - switch (optimitzaion) { - case OneToAllRouting: - return new SwissRailRaptor(raptorDataOneToAll, parametersForPerson, routeSelector, defaultRaptorStopFinder, - new DefaultRaptorInVehicleCostCalculator(), new DefaultRaptorTransferCostCalculator()); - case OneToOneRouting: - return new SwissRailRaptor(raptorData, parametersForPerson, routeSelector, defaultRaptorStopFinder, - new DefaultRaptorInVehicleCostCalculator(), new DefaultRaptorTransferCostCalculator()); - default: - throw new RuntimeException("Unrecognized raptor optimization!"); - } - } - - LeastCostPathCalculator createLeastCostPathCalculator() { - return leastCostPathCalculatorFactory.createPathCalculator(carNetwork, travelDisutility, travelTime); - } - - RoutingModule getTeleportationRouter(String mode) { - Scenario scenario = ScenarioUtils.loadScenario( this.scenario.getConfig() ); - return DefaultRoutingModules.createTeleportationRouter( + } + + SwissRailRaptor createSwissRailRaptor(RaptorStaticConfig.RaptorOptimization optimitzaion) { + + + switch (optimitzaion) { + case OneToAllRouting: + return new SwissRailRaptor(raptorDataOneToAll, parametersForPerson, routeSelector, defaultRaptorStopFinder, + new DefaultRaptorInVehicleCostCalculator(), new DefaultRaptorTransferCostCalculator()); + case OneToOneRouting: + return new SwissRailRaptor(raptorData, parametersForPerson, routeSelector, defaultRaptorStopFinder, + new DefaultRaptorInVehicleCostCalculator(), new DefaultRaptorTransferCostCalculator()); + default: + throw new RuntimeException("Unrecognized raptor optimization!"); + } + } + + LeastCostPathCalculator createLeastCostPathCalculator() { + return leastCostPathCalculatorFactory.createPathCalculator(carNetwork, travelDisutility, travelTime); + } + + RoutingModule getTeleportationRouter(String mode) { + Scenario scenario = ScenarioUtils.loadScenario( this.scenario.getConfig() ); + return DefaultRoutingModules.createTeleportationRouter( // mode, PopulationUtils.getFactory(), config.plansCalcRoute().getOrCreateModeRoutingParams(mode)); - mode, scenario, this.scenario.getConfig().routing().getModeRoutingParams().get(mode ) ); - } - - SwissRailRaptorData getRaptorData(RaptorStaticConfig.RaptorOptimization optimization) { - switch (optimization) { - case OneToAllRouting: - return raptorDataOneToAll; - case OneToOneRouting: - return raptorData; - default: - throw new RuntimeException("Unrecognized raptor optimization!"); - } - } - - RaptorParameters getRaptorParameters() { - return raptorParameters; - } - - public void updateMatsimPopulation(Population matsimPopulation) { + mode, scenario, this.scenario.getConfig().routing().getModeRoutingParams().get(mode ) ); + } + + SwissRailRaptorData getRaptorData(RaptorStaticConfig.RaptorOptimization optimization) { + switch (optimization) { + case OneToAllRouting: + return raptorDataOneToAll; + case OneToOneRouting: + return raptorData; + default: + throw new RuntimeException("Unrecognized raptor optimization!"); + } + } + + RaptorParameters getRaptorParameters() { + return raptorParameters; + } + + public void updateMatsimPopulation(Population matsimPopulation) { this.scenario.setPopulation( matsimPopulation ); - } + } // public void updateMatsimVehicles( Vehicles vehicles ) { // this.scenario.setVehicles( vehicles ); // } From cfa8c9105718293229fc483d9d24b0aca49376d9 Mon Sep 17 00:00:00 2001 From: Kai Nagel Date: Thu, 25 Jun 2026 10:43:28 +0200 Subject: [PATCH 12/12] small changes --- .../java/de/tum/bgu/msm/matsim/MatsimData.java | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/extensions/matsim2silo/src/main/java/de/tum/bgu/msm/matsim/MatsimData.java b/extensions/matsim2silo/src/main/java/de/tum/bgu/msm/matsim/MatsimData.java index ce3331d87..b47549239 100644 --- a/extensions/matsim2silo/src/main/java/de/tum/bgu/msm/matsim/MatsimData.java +++ b/extensions/matsim2silo/src/main/java/de/tum/bgu/msm/matsim/MatsimData.java @@ -154,11 +154,6 @@ public Network getCarNetwork() { return carNetwork; } -// Network getPtNetwork() { -// return ptNetwork; -// } - // never used - public void update(TravelDisutility travelDisutility, TravelTime travelTime) { this.travelDisutility = travelDisutility; this.travelTime = travelTime; @@ -251,9 +246,10 @@ SwissRailRaptor createSwissRailRaptor(RaptorStaticConfig.RaptorOptimization opti } } - LeastCostPathCalculator createLeastCostPathCalculator() { - return leastCostPathCalculatorFactory.createPathCalculator(carNetwork, travelDisutility, travelTime); - } +// LeastCostPathCalculator createLeastCostPathCalculator() { +// return leastCostPathCalculatorFactory.createPathCalculator(carNetwork, travelDisutility, travelTime); +// } + // never used RoutingModule getTeleportationRouter(String mode) { Scenario scenario = ScenarioUtils.loadScenario( this.scenario.getConfig() ); @@ -284,6 +280,7 @@ public void updateMatsimPopulation(Population matsimPopulation) { // this.scenario.setVehicles( vehicles ); // } // yyyyyy forgotten method in matsim api :-( + // added here: https://github.com/matsim-org/matsim-libs/pull/5034 . Uncomment once available. kai, jun'26 // === only pure getters below here @@ -296,9 +293,5 @@ public Scenario getScenario(){ public Population getMatsimPopulation() { return this.scenario.getPopulation(); } -// public TransitSchedule getSchedule() { -// // where is this needed? The router is plugged together in the present class ... -// return this.scenario.getTransitSchedule(); -// } }