From 541dada4ba5508d29cef8426925c6bf0dd6d59ab Mon Sep 17 00:00:00 2001 From: cllorca1 Date: Tue, 3 Dec 2019 14:24:48 +0100 Subject: [PATCH] adapts new commute mode choice to use case Kagawa --- ...eCommuteModeChoiceHousingStrategyImpl.java | 284 ++++++++++++++++++ .../de/tum/bgu/msm/run/ModelBuilderTak.java | 13 +- .../LongCommutePenaltyModelBuilderTak.java | 10 +- ...LongCommutePenaltytHousingStrategyTak.java | 65 ++-- .../OneCarPolicyModelBuilderTak.java | 12 +- 5 files changed, 326 insertions(+), 58 deletions(-) create mode 100644 siloCore/src/main/java/de/tum/bgu/msm/models/relocation/moves/SimpleCommuteModeChoiceHousingStrategyImpl.java 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 new file mode 100644 index 000000000..2d42f739a --- /dev/null +++ b/siloCore/src/main/java/de/tum/bgu/msm/models/relocation/moves/SimpleCommuteModeChoiceHousingStrategyImpl.java @@ -0,0 +1,284 @@ +package de.tum.bgu.msm.models.relocation.moves; + +import de.tum.bgu.msm.container.DataContainer; +import de.tum.bgu.msm.data.Region; +import de.tum.bgu.msm.data.Zone; +import de.tum.bgu.msm.data.accessibility.Accessibility; +import de.tum.bgu.msm.data.accessibility.CommutingTimeProbability; +import de.tum.bgu.msm.data.dwelling.Dwelling; +import de.tum.bgu.msm.data.dwelling.RealEstateDataManager; +import de.tum.bgu.msm.data.dwelling.RealEstateDataManagerImpl; +import de.tum.bgu.msm.data.geo.GeoData; +import de.tum.bgu.msm.data.household.Household; +import de.tum.bgu.msm.data.household.HouseholdType; +import de.tum.bgu.msm.data.household.HouseholdUtil; +import de.tum.bgu.msm.data.household.IncomeCategory; +import de.tum.bgu.msm.data.job.Job; +import de.tum.bgu.msm.data.job.JobDataManager; +import de.tum.bgu.msm.data.person.Occupation; +import de.tum.bgu.msm.data.person.Person; +import de.tum.bgu.msm.data.travelTimes.TravelTimes; +import de.tum.bgu.msm.models.modeChoice.CommuteModeChoice; +import de.tum.bgu.msm.models.modeChoice.CommuteModeChoiceMapping; +import de.tum.bgu.msm.models.modeChoice.SimpleCommuteModeChoice; +import de.tum.bgu.msm.properties.Properties; +import de.tum.bgu.msm.util.matrices.IndexedDoubleMatrix1D; +import de.tum.bgu.msm.utils.SiloUtil; +import org.apache.log4j.Logger; +import org.matsim.api.core.v01.TransportMode; + +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; + +import static de.tum.bgu.msm.data.dwelling.RealEstateUtils.RENT_CATEGORIES; + +public class SimpleCommuteModeChoiceHousingStrategyImpl implements HousingStrategy { + + private final static Logger logger = Logger.getLogger(SimpleCommuteModeChoiceHousingStrategyImpl.class); + + private enum Normalizer { + /** + * Use share of empty dwellings to calculate attraction of region + */ + SHARE_VAC_DD, + /** + * Multiply utility of every region by number of vacant dwellings + * to steer households towards available dwellings + * use number of vacant dwellings to calculate attraction of region + */ + VAC_DD, + DAMPENED_VAC_RATE, + POPULATION, + POWER_OF_POPULATION + } + + private static final Normalizer NORMALIZER = Normalizer.VAC_DD; + + private final Properties properties; + + private IndexedDoubleMatrix1D hhByRegion; + + private final DataContainer dataContainer; + private final RealEstateDataManager realEstateDataManager; + private final GeoData geoData; + private final TravelTimes travelTimes; + private final Accessibility accessibility; + + private final CommuteModeChoice commuteModeChoice; + + private final DwellingUtilityStrategy dwellingUtilityStrategy; + private final DwellingProbabilityStrategy dwellingProbabilityStrategy; + + private final RegionUtilityStrategy regionUtilityStrategy; + private final RegionProbabilityStrategy regionProbabilityStrategy; + + private EnumMap> utilityByIncomeByRegion = new EnumMap<>(IncomeCategory.class); + + public SimpleCommuteModeChoiceHousingStrategyImpl(DataContainer dataContainer, + Properties properties, + TravelTimes travelTimes, + DwellingUtilityStrategy dwellingUtilityStrategy, + DwellingProbabilityStrategy dwellingProbabilityStrategy, + RegionUtilityStrategy regionUtilityStrategy, RegionProbabilityStrategy regionProbabilityStrategy) { + this.dataContainer = dataContainer; + geoData = dataContainer.getGeoData(); + this.properties = properties; + this.travelTimes = travelTimes; + accessibility = dataContainer.getAccessibility(); + commuteModeChoice = new SimpleCommuteModeChoice(dataContainer, properties, SiloUtil.provideNewRandom()); + this.dwellingUtilityStrategy = dwellingUtilityStrategy; + this.dwellingProbabilityStrategy = dwellingProbabilityStrategy; + this.regionUtilityStrategy = regionUtilityStrategy; + this.realEstateDataManager = dataContainer.getRealEstateDataManager(); + this.regionProbabilityStrategy = regionProbabilityStrategy; + } + + + @Override + public void setup() { + hhByRegion = new IndexedDoubleMatrix1D(geoData.getRegions().values()); + calculateShareOfForeignersByZoneAndRegion(); + } + + @Override + public boolean isHouseholdEligibleToLiveHere(Household household, Dwelling dd) { + return true; + } + + @Override + public double calculateHousingUtility(Household hh, Dwelling dwelling) { + if(dwelling == null) { + logger.warn("Household " + hh.getId() + " has no dwelling. Setting housing satisfaction to 0"); + return 0; + } + double ddQualityUtility = convertQualityToUtility(dwelling.getQuality()); + double ddSizeUtility = convertAreaToUtility(dwelling.getBedrooms()); + double ddAutoAccessibilityUtility = convertAccessToUtility(accessibility.getAutoAccessibilityForZone(geoData.getZones().get(dwelling.getZoneId()))); + double transitAccessibilityUtility = convertAccessToUtility(accessibility.getTransitAccessibilityForZone(geoData.getZones().get(dwelling.getZoneId()))); + HouseholdType ht = hh.getHouseholdType(); + double ddPriceUtility = convertPriceToUtility(dwelling.getPrice(), ht.getIncomeCategory()); + + double workDistanceUtility = 1; + + CommuteModeChoiceMapping commuteModeChoiceMapping = commuteModeChoice.assignCommuteModeChoice(dwelling, travelTimes, hh); + + for (Person pp : hh.getPersons().values()) { + if (pp.getOccupation() == Occupation.EMPLOYED && pp.getJobId() != -2) { + + workDistanceUtility *= commuteModeChoiceMapping.getMode(pp).utility; + + } + } + return dwellingUtilityStrategy.calculateSelectDwellingUtility(ht, ddSizeUtility, ddPriceUtility, + ddQualityUtility, ddAutoAccessibilityUtility, + transitAccessibilityUtility, workDistanceUtility); + } + + @Override + public double calculateSelectDwellingProbability(double util) { + return dwellingProbabilityStrategy.calculateSelectDwellingProbability(util); + } + + @Override + public double calculateSelectRegionProbability(double util) { + return regionProbabilityStrategy.calculateSelectRegionProbability(util); + } + + @Override + public void prepareYear() { + calculateShareOfForeignersByZoneAndRegion(); + calculateRegionalUtilities(); + } + + @Override + public double calculateRegionalUtility(Household household, Region region) { + double thisRegionFactor = 1; + CommuteModeChoiceMapping commuteModeChoiceMapping = commuteModeChoice.assignRegionalCommuteModeChoice(region, travelTimes, household); + + for (Person pp : household.getPersons().values()) { + if (pp.getOccupation() == Occupation.EMPLOYED && pp.getJobId() != -2) { + thisRegionFactor *= commuteModeChoiceMapping.getMode(pp).utility; + } + } + + double util = utilityByIncomeByRegion.get(household.getHouseholdType().getIncomeCategory()).get(region.getId()) * thisRegionFactor; + return normalize(region, util); + } + + @Override + public HousingStrategy duplicate() { + TravelTimes ttCopy = travelTimes.duplicate(); + SimpleCommuteModeChoiceHousingStrategyImpl strategy = new SimpleCommuteModeChoiceHousingStrategyImpl(dataContainer, properties, ttCopy, + dwellingUtilityStrategy, dwellingProbabilityStrategy, regionUtilityStrategy, regionProbabilityStrategy); + strategy.hhByRegion = hhByRegion; + strategy.utilityByIncomeByRegion = utilityByIncomeByRegion; + return strategy; + } + + private void calculateShareOfForeignersByZoneAndRegion() { + final IndexedDoubleMatrix1D hhByZone = new IndexedDoubleMatrix1D(geoData.getZones().values()); + hhByRegion.assign(0); + for (Household hh : dataContainer.getHouseholdDataManager().getHouseholds()) { + int zone; + Dwelling dwelling = dataContainer.getRealEstateDataManager().getDwelling(hh.getDwellingId()); + if (dwelling != null) { + zone = dwelling.getZoneId(); + } else { + logger.warn("Household " + hh.getId() + " refers to non-existing dwelling " + + hh.getDwellingId() + ". Should not happen!"); + continue; + } + final int region = geoData.getZones().get(zone).getRegion().getId(); + hhByZone.setIndexed(zone, hhByZone.getIndexed(zone) + 1); + hhByRegion.setIndexed(region, hhByRegion.getIndexed(region) + 1); + + } + } + + private void calculateRegionalUtilities() { + logger.info("Calculating regional utilities"); + final Map rentsByRegion = dataContainer.getRealEstateDataManager().calculateRegionalPrices(); + for (IncomeCategory incomeCategory : IncomeCategory.values()) { + Map utilityByRegion = new HashMap<>(); + for (Region region : geoData.getRegions().values()) { + final int averageRegionalRent = rentsByRegion.get(region.getId()).intValue(); + final float regAcc = (float) convertAccessToUtility(accessibility.getRegionalAccessibility(region)); + float priceUtil = (float) convertPriceToUtility(averageRegionalRent, incomeCategory); + double value = regionUtilityStrategy.calculateSelectRegionProbability(incomeCategory, + priceUtil, regAcc, 0); + switch (NORMALIZER) { + case POPULATION: + value *= hhByRegion.getIndexed(region.getId()); + break; + case POWER_OF_POPULATION: + value *= Math.pow(hhByRegion.getIndexed(region.getId()), 0.5); + break; + default: + //do nothing. + } + utilityByRegion.put(region.getId(), + value); + } + + utilityByIncomeByRegion.put(incomeCategory, utilityByRegion); + } + + } + + private double normalize(Region region, double baseUtil) { + switch (NORMALIZER) { + case VAC_DD: { + return baseUtil * realEstateDataManager.getNumberOfVacantDDinRegion(region.getId()); + } + case DAMPENED_VAC_RATE: { + int key = region.getId(); + double x = (double) realEstateDataManager.getNumberOfVacantDDinRegion(key) / + (double) realEstateDataManager.getNumberOfVacantDDinRegion(key) * 100d; // % vacancy + double y = 1.4186E-03 * Math.pow(x, 3) - 6.7846E-02 * Math.pow(x, 2) + 1.0292 * x + 4.5485E-03; + y = Math.min(5d, y); // % vacancy assumed to be ready to move in + if (realEstateDataManager.getNumberOfVacantDDinRegion(key) < 1) { + return 0.; + } + return baseUtil * (y / 100d * realEstateDataManager.getNumberOfVacantDDinRegion(key)); + + } + case POPULATION: { + //Is already included in the base util + return baseUtil; + } + case POWER_OF_POPULATION: { + //Is already included in the base util + return baseUtil; + } + default: + return baseUtil; + } + } + + private double convertPriceToUtility(int price, IncomeCategory incCategory) { + + Map shares = dataContainer.getRealEstateDataManager().getRentPaymentsForIncomeGroup(incCategory); + // 25 rent categories are defined as , see RealEstateDataManager + int priceCategory = (int) (price / 200f); + priceCategory = Math.min(priceCategory, RENT_CATEGORIES); + double util = 0; + for (int i = 0; i <= priceCategory; i++) { + util += shares.get(i); + } + // invert utility, as lower price has higher utility + return Math.max(0, 1.f - util); + } + + private double convertQualityToUtility(int quality) { + return (float) quality / (float) properties.main.qualityLevels; + } + + private double convertAreaToUtility(int area) { + return (float) area / (float) RealEstateDataManagerImpl.largestNoBedrooms; + } + + private double convertAccessToUtility(double accessibility) { + return accessibility / 100f; + } +} diff --git a/useCases/kagawa/src/main/java/de/tum/bgu/msm/run/ModelBuilderTak.java b/useCases/kagawa/src/main/java/de/tum/bgu/msm/run/ModelBuilderTak.java index e9a1914b5..2ff661185 100644 --- a/useCases/kagawa/src/main/java/de/tum/bgu/msm/run/ModelBuilderTak.java +++ b/useCases/kagawa/src/main/java/de/tum/bgu/msm/run/ModelBuilderTak.java @@ -5,10 +5,7 @@ import de.tum.bgu.msm.data.dwelling.DwellingFactory; import de.tum.bgu.msm.data.household.HouseholdFactory; import de.tum.bgu.msm.data.person.PersonFactory; -import de.tum.bgu.msm.matsim.MatsimScenarioAssembler; -import de.tum.bgu.msm.matsim.MatsimTransportModel; -import de.tum.bgu.msm.matsim.SimpleMatsimScenarioAssembler; -import de.tum.bgu.msm.matsim.ZoneConnectorManager; +import de.tum.bgu.msm.matsim.*; import de.tum.bgu.msm.mito.MitoMatsimScenarioAssembler; import de.tum.bgu.msm.models.autoOwnership.CreateCarOwnershipModel; import de.tum.bgu.msm.models.carOwnership.CreateCarOwnershipTak; @@ -39,6 +36,9 @@ 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.modeChoice.CommuteModeChoiceMapping; +import de.tum.bgu.msm.models.modeChoice.SimpleCommuteModeChoice; 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; @@ -72,7 +72,7 @@ public static ModelContainer getTakModels(DataContainer dataContainer, Propertie MovesModelImpl movesModel = new MovesModelImpl( dataContainer, properties, new DefaultMovesStrategy(), - new CarAndTransitHousingStrategyImpl(dataContainer, + new SimpleCommuteModeChoiceHousingStrategyImpl(dataContainer, properties, dataContainer.getTravelTimes(), new DwellingUtilityStrategyImpl(), new DefaultDwellingProbabilityStrategy(), new RegionUtilityStrategyImpl(), new RegionProbabilityStrategyImpl()), SiloUtil.provideNewRandom()); @@ -122,7 +122,8 @@ dataContainer, properties, new DefaultMovesStrategy(), ZoneConnectorManager.ZoneConnectorMethod.RANDOM, scenarioAssembler); break; case MATSIM: - scenarioAssembler = new SimpleMatsimScenarioAssembler(dataContainer, properties); + CommuteModeChoice simpleCommuteModeChoice = new SimpleCommuteModeChoice(dataContainer, properties, SiloUtil.provideNewRandom()); + scenarioAssembler = new SimpleCommuteModeChoiceMatsimScenarioAssembler(dataContainer, properties, simpleCommuteModeChoice); transportModel = new MatsimTransportModel(dataContainer, config, properties, null, ZoneConnectorManager.ZoneConnectorMethod.RANDOM, scenarioAssembler); break; diff --git a/useCases/kagawa/src/main/java/de/tum/bgu/msm/scenarios/longCommutePenalty/LongCommutePenaltyModelBuilderTak.java b/useCases/kagawa/src/main/java/de/tum/bgu/msm/scenarios/longCommutePenalty/LongCommutePenaltyModelBuilderTak.java index d055edcf8..e102738d5 100644 --- a/useCases/kagawa/src/main/java/de/tum/bgu/msm/scenarios/longCommutePenalty/LongCommutePenaltyModelBuilderTak.java +++ b/useCases/kagawa/src/main/java/de/tum/bgu/msm/scenarios/longCommutePenalty/LongCommutePenaltyModelBuilderTak.java @@ -5,10 +5,7 @@ import de.tum.bgu.msm.data.dwelling.DwellingFactory; import de.tum.bgu.msm.data.household.HouseholdFactory; import de.tum.bgu.msm.data.person.PersonFactory; -import de.tum.bgu.msm.matsim.MatsimScenarioAssembler; -import de.tum.bgu.msm.matsim.MatsimTransportModel; -import de.tum.bgu.msm.matsim.SimpleMatsimScenarioAssembler; -import de.tum.bgu.msm.matsim.ZoneConnectorManager; +import de.tum.bgu.msm.matsim.*; import de.tum.bgu.msm.mito.MitoMatsimScenarioAssembler; import de.tum.bgu.msm.models.autoOwnership.CreateCarOwnershipModel; import de.tum.bgu.msm.models.carOwnership.CreateCarOwnershipStrategyTakImpl; @@ -39,6 +36,8 @@ 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.modeChoice.SimpleCommuteModeChoice; 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; @@ -123,7 +122,8 @@ dataContainer, properties, new DefaultMovesStrategy(), ZoneConnectorManager.ZoneConnectorMethod.RANDOM, scenarioAssembler); break; case MATSIM: - scenarioAssembler = new SimpleMatsimScenarioAssembler(dataContainer, properties); + CommuteModeChoice simpleCommuteModeChoice = new SimpleCommuteModeChoice(dataContainer, properties, SiloUtil.provideNewRandom()); + scenarioAssembler = new SimpleCommuteModeChoiceMatsimScenarioAssembler(dataContainer, properties, simpleCommuteModeChoice); transportModel = new MatsimTransportModel(dataContainer, config, properties, null, ZoneConnectorManager.ZoneConnectorMethod.RANDOM, scenarioAssembler); break; diff --git a/useCases/kagawa/src/main/java/de/tum/bgu/msm/scenarios/longCommutePenalty/LongCommutePenaltytHousingStrategyTak.java b/useCases/kagawa/src/main/java/de/tum/bgu/msm/scenarios/longCommutePenalty/LongCommutePenaltytHousingStrategyTak.java index 181ea4109..b77c326a6 100644 --- a/useCases/kagawa/src/main/java/de/tum/bgu/msm/scenarios/longCommutePenalty/LongCommutePenaltytHousingStrategyTak.java +++ b/useCases/kagawa/src/main/java/de/tum/bgu/msm/scenarios/longCommutePenalty/LongCommutePenaltytHousingStrategyTak.java @@ -18,9 +18,13 @@ import de.tum.bgu.msm.data.person.Occupation; import de.tum.bgu.msm.data.person.Person; import de.tum.bgu.msm.data.travelTimes.TravelTimes; +import de.tum.bgu.msm.models.modeChoice.CommuteModeChoice; +import de.tum.bgu.msm.models.modeChoice.CommuteModeChoiceMapping; +import de.tum.bgu.msm.models.modeChoice.SimpleCommuteModeChoice; import de.tum.bgu.msm.models.relocation.moves.*; import de.tum.bgu.msm.properties.Properties; import de.tum.bgu.msm.util.matrices.IndexedDoubleMatrix1D; +import de.tum.bgu.msm.utils.SiloUtil; import org.apache.log4j.Logger; import org.matsim.api.core.v01.TransportMode; @@ -56,6 +60,7 @@ private enum Normalizer{ private static final int PENALTY_EUR = 200; private final int TIME_THRESHOLD_M = 25; + private final double UTILITY_THRESHOLD = Math.exp(-0.2 * 25); private final Properties properties; @@ -66,7 +71,7 @@ private enum Normalizer{ private final GeoData geoData; private final TravelTimes travelTimes; private final Accessibility accessibility; - private final CommutingTimeProbability commutingTimeProbability; + private final CommuteModeChoice commuteModeChoice; private final DwellingUtilityStrategy dwellingUtilityStrategy; private final DwellingProbabilityStrategy dwellingProbabilityStrategy; @@ -87,7 +92,7 @@ protected LongCommutePenaltytHousingStrategyTak(DataContainer dataContainer, this.properties = properties; this.travelTimes = travelTimes; accessibility = dataContainer.getAccessibility(); - commutingTimeProbability = dataContainer.getCommutingTimeProbability(); + commuteModeChoice = new SimpleCommuteModeChoice(dataContainer, properties, SiloUtil.provideNewRandom()); this.dwellingUtilityStrategy = dwellingUtilityStrategy; this.dwellingProbabilityStrategy = dwellingProbabilityStrategy; this.regionUtilityStrategy = regionUtilityStrategy; @@ -127,28 +132,19 @@ public double calculateHousingUtility(Household hh, Dwelling dwelling) { int penaltiesForThisDwelling = 0; double travelCostUtility = 1; //do not have effect at the moment; - double factorForThisZone; - JobDataManager jobDataManager = dataContainer.getJobDataManager(); + + double workDistanceUtility = 1; - for (Person pp: hh.getPersons().values()) { - if (pp.getOccupation() == Occupation.EMPLOYED && pp.getJobId() != -2) { - final Job job = jobDataManager.getJobFromId(pp.getJobId()); - int ptTime = (int) travelTimes.getTravelTime(dwelling, job, properties.transportModel.peakHour_s, TransportMode.pt); - int carTime = (int) travelTimes.getTravelTime(dwelling, job, properties.transportModel.peakHour_s, TransportMode.car); + CommuteModeChoiceMapping commuteModeChoiceMapping = commuteModeChoice.assignCommuteModeChoice(dwelling, travelTimes, hh); + - if(carTime > TIME_THRESHOLD_M){ + for (Person pp : hh.getPersons().values()) { + if (pp.getOccupation() == Occupation.EMPLOYED && pp.getJobId() != -2) { + double thisWorkerUtility = commuteModeChoiceMapping.getMode(pp).utility; + workDistanceUtility *= thisWorkerUtility; + if (thisWorkerUtility < UTILITY_THRESHOLD){ penaltiesForThisDwelling += PENALTY_EUR; } - if(carToWorkersRatio == 0.) { - factorForThisZone = commutingTimeProbability.getCommutingTimeProbability(Math.max(1, ptTime)); - } else if( carToWorkersRatio == 1.) { - factorForThisZone = commutingTimeProbability.getCommutingTimeProbability(Math.max(1, carTime)); - } else { - double factorCar = commutingTimeProbability.getCommutingTimeProbability(Math.max(1, carTime)); - double factorPt = commutingTimeProbability.getCommutingTimeProbability(Math.max(1, ptTime)); - factorForThisZone= factorCar * carToWorkersRatio + (1 - carToWorkersRatio) * factorPt; - } - workDistanceUtility *= factorForThisZone; } } @@ -181,32 +177,19 @@ public double calculateRegionalUtility(Household household, Region region) { int penaltyToThisHouseholdAndRegion = 0; - double carToWorkersRatio = Math.min(1., ((double) household.getAutos() / HouseholdUtil.getNumberOfWorkers(household))); - double thisRegionFactor = 1; - for (Person pp: household.getPersons().values()) { + CommuteModeChoiceMapping commuteModeChoiceMapping = commuteModeChoice.assignRegionalCommuteModeChoice(region, travelTimes, household); + + for (Person pp : household.getPersons().values()) { if (pp.getOccupation() == Occupation.EMPLOYED && pp.getJobId() != -2) { - final Job job = jobDataManager.getJobFromId(pp.getJobId()); - if(job != null) { - Zone workZone = geoData.getZones().get(job.getZoneId()); - int ptTime = (int) travelTimes.getTravelTimeFromRegion(region, workZone, properties.transportModel.peakHour_s, TransportMode.pt); - int carTime = (int) travelTimes.getTravelTimeFromRegion(region, workZone,properties.transportModel.peakHour_s, TransportMode.car); - if(carTime > TIME_THRESHOLD_M){ - penaltyToThisHouseholdAndRegion += PENALTY_EUR; - } - if(carToWorkersRatio <= 0.) { - thisRegionFactor = commutingTimeProbability.getCommutingTimeProbability(Math.max(1, ptTime)); - } else if( carToWorkersRatio >= 1.) { - thisRegionFactor = commutingTimeProbability.getCommutingTimeProbability(Math.max(1, carTime)); - } else { - double factorCar = commutingTimeProbability.getCommutingTimeProbability(Math.max(1, carTime)); - double factorPt = commutingTimeProbability.getCommutingTimeProbability(Math.max(1, ptTime)); - - thisRegionFactor= factorCar * carToWorkersRatio + (1 - carToWorkersRatio) * factorPt; - } + double thisWorkerUtility = commuteModeChoiceMapping.getMode(pp).utility; + thisRegionFactor *= thisWorkerUtility; + if (thisWorkerUtility < UTILITY_THRESHOLD){ + penaltyToThisHouseholdAndRegion += PENALTY_EUR; } } } + double util; if (penaltyToThisHouseholdAndRegion == 0){ util = utilityByIncomeByRegion.get(household.getHouseholdType().getIncomeCategory()).get(region.getId()) * thisRegionFactor; diff --git a/useCases/kagawa/src/main/java/de/tum/bgu/msm/scenarios/oneCarPolicy/OneCarPolicyModelBuilderTak.java b/useCases/kagawa/src/main/java/de/tum/bgu/msm/scenarios/oneCarPolicy/OneCarPolicyModelBuilderTak.java index 5b9e773b2..168cc46cb 100644 --- a/useCases/kagawa/src/main/java/de/tum/bgu/msm/scenarios/oneCarPolicy/OneCarPolicyModelBuilderTak.java +++ b/useCases/kagawa/src/main/java/de/tum/bgu/msm/scenarios/oneCarPolicy/OneCarPolicyModelBuilderTak.java @@ -5,10 +5,7 @@ import de.tum.bgu.msm.data.dwelling.DwellingFactory; import de.tum.bgu.msm.data.household.HouseholdFactory; import de.tum.bgu.msm.data.person.PersonFactory; -import de.tum.bgu.msm.matsim.MatsimScenarioAssembler; -import de.tum.bgu.msm.matsim.MatsimTransportModel; -import de.tum.bgu.msm.matsim.SimpleMatsimScenarioAssembler; -import de.tum.bgu.msm.matsim.ZoneConnectorManager; +import de.tum.bgu.msm.matsim.*; import de.tum.bgu.msm.mito.MitoMatsimScenarioAssembler; import de.tum.bgu.msm.models.autoOwnership.CreateCarOwnershipModel; import de.tum.bgu.msm.models.carOwnership.CreateCarOwnershipStrategyTakImpl; @@ -38,6 +35,8 @@ 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.modeChoice.SimpleCommuteModeChoice; 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; @@ -71,7 +70,7 @@ public static ModelContainer getTakModels(DataContainer dataContainer, Propertie MovesModelImpl movesModel = new MovesModelImpl( dataContainer, properties, new DefaultMovesStrategy(), - new CarAndTransitHousingStrategyImpl(dataContainer, + new SimpleCommuteModeChoiceHousingStrategyImpl(dataContainer, properties, dataContainer.getTravelTimes(), new DwellingUtilityStrategyImpl(), new DefaultDwellingProbabilityStrategy(), new RegionUtilityStrategyImpl(), new RegionProbabilityStrategyImpl()), SiloUtil.provideNewRandom()); @@ -121,7 +120,8 @@ dataContainer, properties, new DefaultMovesStrategy(), ZoneConnectorManager.ZoneConnectorMethod.RANDOM, scenarioAssembler); break; case MATSIM: - scenarioAssembler = new SimpleMatsimScenarioAssembler(dataContainer, properties); + CommuteModeChoice simpleCommuteModeChoice = new SimpleCommuteModeChoice(dataContainer, properties, SiloUtil.provideNewRandom()); + scenarioAssembler = new SimpleCommuteModeChoiceMatsimScenarioAssembler(dataContainer, properties, simpleCommuteModeChoice); transportModel = new MatsimTransportModel(dataContainer, config, properties, null, ZoneConnectorManager.ZoneConnectorMethod.RANDOM, scenarioAssembler); break;