From fda4ac74dd6153533e964bcdbb6c3f07b219a4e8 Mon Sep 17 00:00:00 2001 From: rakow Date: Fri, 7 Jun 2024 19:56:25 +0200 Subject: [PATCH] improve reference person matching --- Makefile | 10 ++++- .../population/AssignReferencePopulation.java | 45 +++++++++++-------- .../population/InitLocationChoice.java | 6 +++ .../prepare/population/PlanBuilder.java | 4 +- 4 files changed, 43 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index 9a9629d0..4fddd401 100644 --- a/Makefile +++ b/Makefile @@ -155,9 +155,17 @@ $p/berlin-static-$V-25pct.plans.xml.gz: $p/berlin-only-$V-25pct.plans.xml.gz $p/ $(sc) prepare lookup-regiostar --input $@ --output $@ --xls $(germany)/RegioStaR-Referenzdateien.xlsx -$p/berlin-activities-$V-25pct.plans.xml.gz: $p/berlin-static-$V-25pct.plans.xml.gz +$p/berlin-activities-$V-25pct.plans.xml.gz: $p/berlin-static-$V-25pct.plans.xml.gz $p/berlin-$V-facilities.xml.gz $p/berlin-$V-network.xml.gz $(sc) prepare activity-sampling --seed 1 --input $< --output $@ --persons src/main/python/table-persons.csv --activities src/main/python/table-activities.csv + $(sc) prepare assign-reference-population --population $@ --output $@\ + --persons src/main/python/table-persons.csv\ + --activities src/main/python/table-activities.csv\ + --shp $(germany)/../matsim-berlin/data/SrV/zones/zones.shp\ + --shp-crs $(CRS)\ + --facilities $(word 2,$^)\ + --network $(word 3,$^)\ + $p/berlin-initial-$V-25pct.plans.xml.gz: $p/berlin-activities-$V-25pct.plans.xml.gz $p/berlin-$V-facilities.xml.gz $p/berlin-$V-network.xml.gz $(sc) prepare init-location-choice\ --input $<\ diff --git a/src/main/java/org/matsim/prepare/population/AssignReferencePopulation.java b/src/main/java/org/matsim/prepare/population/AssignReferencePopulation.java index 6507a91d..a468698d 100644 --- a/src/main/java/org/matsim/prepare/population/AssignReferencePopulation.java +++ b/src/main/java/org/matsim/prepare/population/AssignReferencePopulation.java @@ -92,6 +92,7 @@ public Integer call() throws Exception { RunActivitySampling sampling = new RunActivitySampling(persons, planBuilder.getActivities(), population.getFactory(), 1); int i = 0; + outer: for (Map.Entry e : ProgressBar.wrap(persons, "Assigning reference population")) { CSVRecord p = e.getValue(); @@ -112,31 +113,37 @@ public Integer call() throws Exception { if (refPersons == null) continue; - Person person = persons.matchEntry(e.getValue(), refPersons, rnd); - // No persons matched - if (person == null) - continue; + // try matching several persons in case it fails + for (int j = 0; j < 10; j++) { + + Person person = persons.matchEntry(e.getValue(), refPersons, rnd); + + // No persons matched + if (person == null) + continue outer; - // Create the base daily plan (without locations) - Coord homeCoord = Attributes.getHomeCoord(person); - Plan plan = sampling.createPlan(homeCoord, e.getKey()); + // Create the base daily plan (without locations) + Coord homeCoord = Attributes.getHomeCoord(person); + Plan plan = sampling.createPlan(homeCoord, e.getKey()); - boolean success = planBuilder.assignLocationsFromZones(e.getKey(), plan, homeCoord); + boolean success = planBuilder.assignLocationsFromZones(e.getKey(), plan, homeCoord); - if (success) { - sampling.copyAttributes(p, person); - person.getAttributes().putAttribute(Attributes.REF_WEIGHT, p.get("p_weight")); - person.removePlan(person.getSelectedPlan()); - person.addPlan(plan); - person.setSelectedPlan(plan); + if (success) { + sampling.copyAttributes(p, person); + person.getAttributes().putAttribute(Attributes.REF_WEIGHT, p.get("p_weight")); + person.removePlan(person.getSelectedPlan()); + person.addPlan(plan); + person.setSelectedPlan(plan); - String refModes = TripStructureUtils.getLegs(plan).stream().map(Leg::getMode).collect(Collectors.joining("-")); - person.getAttributes().putAttribute(Attributes.REF_MODES, refModes); + String refModes = TripStructureUtils.getLegs(plan).stream().map(Leg::getMode).collect(Collectors.joining("-")); + person.getAttributes().putAttribute(Attributes.REF_MODES, refModes); - // remove person that have been used as reference - refPersons.remove(person); - i++; + // remove person that have been used as reference + refPersons.remove(person); + i++; + break; + } } } diff --git a/src/main/java/org/matsim/prepare/population/InitLocationChoice.java b/src/main/java/org/matsim/prepare/population/InitLocationChoice.java index 2f4b2bb5..e8b58f03 100644 --- a/src/main/java/org/matsim/prepare/population/InitLocationChoice.java +++ b/src/main/java/org/matsim/prepare/population/InitLocationChoice.java @@ -195,6 +195,12 @@ public void run(Person person) { Coord homeCoord = Attributes.getHomeCoord(person); + // Reference persons are not assigned locations + if (person.getAttributes().getAttribute(Attributes.REF_MODES) != null) { + pb.step(); + return; + } + // Activities that only occur on one place per person Map fixedLocations = new HashMap<>(); diff --git a/src/main/java/org/matsim/prepare/population/PlanBuilder.java b/src/main/java/org/matsim/prepare/population/PlanBuilder.java index fdbfa0ef..5265750e 100644 --- a/src/main/java/org/matsim/prepare/population/PlanBuilder.java +++ b/src/main/java/org/matsim/prepare/population/PlanBuilder.java @@ -287,8 +287,8 @@ private List sampleLocation(List> locations, Doub double total = dists.doubleStream().sum() / (locations.size() - 1); double perActErr = err / (locations.size() - 1); - // Allow deviation of 500m or 5% - if (perActErr > Math.max(500, total * 0.05)) + // threshold for deviation + if (perActErr > Math.max(300, total * 0.03)) return null; return best;