From 62f50d80dab02b260c36bbe84071a863b77fa375 Mon Sep 17 00:00:00 2001 From: Andreas Neumann Date: Thu, 21 Sep 2023 16:25:27 +0200 Subject: [PATCH 1/9] added plan inheritance stats --- .../dvrp/vrpagent/VrpAgentQueryHelper.java | 30 +++++ .../distributed/plans/PlanGenome.java | 18 +++ .../population/PlanWithCachedJointPlan.java | 18 +++ .../matsim/api/core/v01/population/Plan.java | 12 ++ .../controler/ControlerDefaultsModule.java | 2 + .../org/matsim/core/population/PlanImpl.java | 31 +++++ .../core/population/PopulationUtils.java | 30 +++++ .../replanning/GenericPlanStrategyImpl.java | 7 ++ .../inheritance/PlanInheritanceModule.java | 115 ++++++++++++++++++ .../inheritance/PlanInheritanceRecord.java | 21 ++++ .../PlanInheritanceRecordWriter.java | 74 +++++++++++ 11 files changed, 358 insertions(+) create mode 100644 matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java create mode 100644 matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecord.java create mode 100644 matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecordWriter.java diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/vrpagent/VrpAgentQueryHelper.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/vrpagent/VrpAgentQueryHelper.java index abdcc4521b3..64e15ad5036 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/vrpagent/VrpAgentQueryHelper.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/vrpagent/VrpAgentQueryHelper.java @@ -158,6 +158,36 @@ public String getType() { public void setType(String type) { throw new UnsupportedOperationException(); } + + @Override + public int getIterationCreated() { + throw new UnsupportedOperationException(); + } + + @Override + public void setIterationCreated(int iteration) { + throw new UnsupportedOperationException(); + } + + @Override + public String getPlanId() { + throw new UnsupportedOperationException(); + } + + @Override + public void setPlanId(String planId) { + throw new UnsupportedOperationException(); + } + + @Override + public String getPlanMutator() { + throw new UnsupportedOperationException(); + } + + @Override + public void setPlanMutator(String planMutator) { + throw new UnsupportedOperationException(); + } @Override public void setScore(Double score) { diff --git a/contribs/pseudosimulation/src/main/java/org/matsim/contrib/pseudosimulation/distributed/plans/PlanGenome.java b/contribs/pseudosimulation/src/main/java/org/matsim/contrib/pseudosimulation/distributed/plans/PlanGenome.java index 12cd0a7023f..63f9bf8d8d9 100644 --- a/contribs/pseudosimulation/src/main/java/org/matsim/contrib/pseudosimulation/distributed/plans/PlanGenome.java +++ b/contribs/pseudosimulation/src/main/java/org/matsim/contrib/pseudosimulation/distributed/plans/PlanGenome.java @@ -219,6 +219,24 @@ public String getType() { public void setType(final String type) { this.type = type; } + + @Override + public String getPlanId() { return null; } + + @Override + public void setPlanId(String planId) { /* nothing to do here */ } + + @Override + public int getIterationCreated() { return -1; } + + @Override + public void setIterationCreated(int iteration) { /* nothing to do here */ } + + @Override + public String getPlanMutator() { return null; } + + @Override + public void setPlanMutator(String planMutator) { /* nothing to do here */ } @Override public final List getPlanElements() { diff --git a/contribs/socnetsim/src/main/java/org/matsim/contrib/socnetsim/framework/population/PlanWithCachedJointPlan.java b/contribs/socnetsim/src/main/java/org/matsim/contrib/socnetsim/framework/population/PlanWithCachedJointPlan.java index c1def957531..00e96f82d89 100644 --- a/contribs/socnetsim/src/main/java/org/matsim/contrib/socnetsim/framework/population/PlanWithCachedJointPlan.java +++ b/contribs/socnetsim/src/main/java/org/matsim/contrib/socnetsim/framework/population/PlanWithCachedJointPlan.java @@ -172,6 +172,24 @@ public String getType() { public void setType(String type) { this.delegate.setType(type); } + + @Override + public String getPlanId() { return null; } + + @Override + public void setPlanId(String planId) { /* nothing to do here */ } + + @Override + public int getIterationCreated() { return -1; } + + @Override + public void setIterationCreated(int iteration) { /* nothing to do here */ } + + @Override + public String getPlanMutator() { return null; } + + @Override + public void setPlanMutator(String planMutator) { /* nothing to do here */ } @Override public Person getPerson() { diff --git a/matsim/src/main/java/org/matsim/api/core/v01/population/Plan.java b/matsim/src/main/java/org/matsim/api/core/v01/population/Plan.java index e06412da59e..556f1e80d8a 100644 --- a/matsim/src/main/java/org/matsim/api/core/v01/population/Plan.java +++ b/matsim/src/main/java/org/matsim/api/core/v01/population/Plan.java @@ -49,6 +49,18 @@ public interface Plan extends MatsimPopulationObject, Customizable, BasicPlan, A public abstract String getType(); public abstract void setType(final String type); + + public abstract void setPlanId(final String planId); + + public abstract String getPlanId(); + + public abstract int getIterationCreated(); + + public abstract void setIterationCreated(int iteration); + + public abstract String getPlanMutator(); + + public abstract void setPlanMutator(String planMutator); public abstract Person getPerson(); diff --git a/matsim/src/main/java/org/matsim/core/controler/ControlerDefaultsModule.java b/matsim/src/main/java/org/matsim/core/controler/ControlerDefaultsModule.java index bd64b584d38..fc5c43da358 100755 --- a/matsim/src/main/java/org/matsim/core/controler/ControlerDefaultsModule.java +++ b/matsim/src/main/java/org/matsim/core/controler/ControlerDefaultsModule.java @@ -37,6 +37,7 @@ import org.matsim.core.population.VspPlansCleanerModule; import org.matsim.core.replanning.StrategyManagerModule; import org.matsim.core.replanning.annealing.ReplanningAnnealer; +import org.matsim.core.replanning.inheritance.PlanInheritanceModule; import org.matsim.core.router.TripRouterModule; import org.matsim.core.router.costcalculators.TravelDisutilityModule; import org.matsim.core.scoring.functions.CharyparNagelScoringFunctionModule; @@ -76,6 +77,7 @@ public void install() { install(new VspPlansCleanerModule()); install(new SnapshotWritersModule()); install(new DependencyGraphModule()); + install(new PlanInheritanceModule()); // Comment by Tarek Chouaki. // To make sure the cache files used under ChartUtils are located in tmp folder in the output directory diff --git a/matsim/src/main/java/org/matsim/core/population/PlanImpl.java b/matsim/src/main/java/org/matsim/core/population/PlanImpl.java index 9c8957cd480..08047673bfd 100644 --- a/matsim/src/main/java/org/matsim/core/population/PlanImpl.java +++ b/matsim/src/main/java/org/matsim/core/population/PlanImpl.java @@ -32,6 +32,7 @@ import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Plan; import org.matsim.api.core.v01.population.PlanElement; +import org.matsim.core.replanning.inheritance.PlanInheritanceModule; import org.matsim.core.scenario.CustomizableUtils; import org.matsim.utils.objectattributes.attributable.Attributes; import org.matsim.utils.objectattributes.attributable.AttributesImpl; @@ -121,6 +122,36 @@ public String getType() { public void setType(final String type) { this.type = type; } + + @Override + public String getPlanId() { + return (String) this.getAttributes().getAttribute(PlanInheritanceModule.PLAN_ID); + } + + @Override + public void setPlanId(String planId) { + this.getAttributes().putAttribute(PlanInheritanceModule.PLAN_ID, planId); + } + + @Override + public int getIterationCreated() { + return (int) this.getAttributes().getAttribute(PlanInheritanceModule.ITERATION_CREATED); + } + + @Override + public void setIterationCreated(int iteration) { + this.getAttributes().putAttribute(PlanInheritanceModule.ITERATION_CREATED, iteration); + } + + @Override + public String getPlanMutator() { + return (String) this.getAttributes().getAttribute(PlanInheritanceModule.PLAN_MUTATOR); + } + + @Override + public void setPlanMutator(String planMutator) { + this.getAttributes().putAttribute(PlanInheritanceModule.PLAN_MUTATOR, planMutator); + } @Override public final List getPlanElements() { diff --git a/matsim/src/main/java/org/matsim/core/population/PopulationUtils.java b/matsim/src/main/java/org/matsim/core/population/PopulationUtils.java index 7f187b285a4..ed49e66ed22 100644 --- a/matsim/src/main/java/org/matsim/core/population/PopulationUtils.java +++ b/matsim/src/main/java/org/matsim/core/population/PopulationUtils.java @@ -381,6 +381,36 @@ public String getType() { public void setType(String type) { throw new UnsupportedOperationException(); } + + @Override + public String getPlanId() { + return this.delegate.getPlanId(); + } + + @Override + public void setPlanId(String planId) { + throw new UnsupportedOperationException(); + } + + @Override + public int getIterationCreated() { + return this.delegate.getIterationCreated(); + } + + @Override + public void setIterationCreated(int iteration) { + throw new UnsupportedOperationException(); + } + + @Override + public String getPlanMutator() { + return this.delegate.getPlanMutator(); + } + + @Override + public void setPlanMutator(String planMutator) { + throw new UnsupportedOperationException(); + } @Override public void addLeg(Leg leg) { diff --git a/matsim/src/main/java/org/matsim/core/replanning/GenericPlanStrategyImpl.java b/matsim/src/main/java/org/matsim/core/replanning/GenericPlanStrategyImpl.java index db83e5d4749..341e32d1ca6 100644 --- a/matsim/src/main/java/org/matsim/core/replanning/GenericPlanStrategyImpl.java +++ b/matsim/src/main/java/org/matsim/core/replanning/GenericPlanStrategyImpl.java @@ -22,6 +22,7 @@ import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.population.BasicPlan; import org.matsim.api.core.v01.population.HasPlansAndId; +import org.matsim.api.core.v01.population.Plan; import org.matsim.core.replanning.modules.GenericPlanStrategyModule; import org.matsim.core.replanning.selectors.PlanSelector; import org.matsim.core.replanning.selectors.RandomUnscoredPlanSelector; @@ -92,6 +93,12 @@ public void run(final HasPlansAndId person) { // set the working plan to a copy of the selected plan: plan = person.createCopyOfSelectedPlanAndMakeSelected(); + if (plan instanceof Plan) { + // add plan inheritance flags + ((Plan) plan).setIterationCreated(this.replanningContext.getIteration()); + ((Plan) plan).setPlanMutator(this.toString()); + } + // add new plan to container that contains the plans that are handled by this PlanStrategy: this.plans.add(plan); diff --git a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java new file mode 100644 index 00000000000..3c22bed37e3 --- /dev/null +++ b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java @@ -0,0 +1,115 @@ +package org.matsim.core.replanning.inheritance; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.Plan; +import org.matsim.core.config.groups.ControlerConfigGroup.CompressionType; +import org.matsim.core.controler.AbstractModule; +import org.matsim.core.controler.events.BeforeMobsimEvent; +import org.matsim.core.controler.events.ShutdownEvent; +import org.matsim.core.controler.events.StartupEvent; +import org.matsim.core.controler.listener.BeforeMobsimListener; +import org.matsim.core.controler.listener.ShutdownListener; +import org.matsim.core.controler.listener.StartupListener; +import org.matsim.core.population.PersonUtils; + +import com.google.inject.Singleton; + +@Singleton +public class PlanInheritanceModule extends AbstractModule implements StartupListener, BeforeMobsimListener, ShutdownListener { + + + public static final String PLAN_ID = "planId"; + public static final String ITERATION_CREATED = "iterationCreated"; + public static final String PLAN_MUTATOR = "planMutator"; + + public static final String INITIAL_PLAN = "initialPlan"; + + public static final String FILENAME_PLAN_INHERITANCE_RECORDS = "planInheritanceRecords"; + + long numberOfPlanInheritanceRecordsCreated = 0; + Map planId2planInheritanceRecords = new ConcurrentHashMap<>(); + + PlanInheritanceRecordWriter planInheritanceRecordWriter; + + @Override + public void notifyStartup(StartupEvent event) { + CompressionType compressionType = event.getServices().getConfig().controler().getCompressionType(); + this.planInheritanceRecordWriter = new PlanInheritanceRecordWriter(event.getServices().getControlerIO().getOutputFilename(FILENAME_PLAN_INHERITANCE_RECORDS + ".csv", compressionType)); + } + + @Override + public void notifyBeforeMobsim(BeforeMobsimEvent event) { + + Set activePlanIds = new HashSet<>(); + + for (Person person : event.getServices().getScenario().getPopulation().getPersons().values()) { + for (Plan plan : person.getPlans()) { + + if (plan.getPlanMutator() == null) { + // initial plan - set initial plan defaults + plan.setPlanMutator(INITIAL_PLAN); + plan.setIterationCreated(event.getIteration()); + } + + if (plan.getIterationCreated() == event.getIteration()) { + // it's a new plan created in this iteration - create a new record + + PlanInheritanceRecord planInheritanceRecord = new PlanInheritanceRecord(); + planInheritanceRecord.agentId = person.getId().toString(); + planInheritanceRecord.planId = Long.toString(++this.numberOfPlanInheritanceRecordsCreated, 36); + planInheritanceRecord.ancestorId = plan.getPlanId(); + plan.setPlanId(planInheritanceRecord.planId); + planInheritanceRecord.iterationCreated = plan.getIterationCreated(); + planInheritanceRecord.mutatedBy = plan.getPlanMutator(); + + this.planId2planInheritanceRecords.put(planInheritanceRecord.planId, planInheritanceRecord); + } + + if (PersonUtils.isSelected(plan)) { + this.planId2planInheritanceRecords.get(plan.getPlanId()).iterationsSelected.add(event.getIteration()); + } + + activePlanIds.add(plan.getPlanId()); + } + } + + List deletedPlans = new ArrayList<>(); + for (String planId : this.planId2planInheritanceRecords.keySet()) { + if (!activePlanIds.contains(planId)) { + deletedPlans.add(planId); + } + } + + for (String deletedPlanId : deletedPlans) { + PlanInheritanceRecord deletedPlanInheritanceRecord = this.planId2planInheritanceRecords.remove(deletedPlanId); + deletedPlanInheritanceRecord.iterationRemoved = event.getIteration(); + this.planInheritanceRecordWriter.write(deletedPlanInheritanceRecord); + } + + this.planInheritanceRecordWriter.flush(); + } + + @Override + public void notifyShutdown(ShutdownEvent event) { + for (PlanInheritanceRecord planInheritanceRecord : this.planId2planInheritanceRecords.values()) { + this.planInheritanceRecordWriter.write(planInheritanceRecord); + } + + this.planInheritanceRecordWriter.flush(); + this.planInheritanceRecordWriter.close(); + + this.planId2planInheritanceRecords.clear(); + } + + @Override + public void install() { + addControlerListenerBinding().to(PlanInheritanceModule.class); + } +} diff --git a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecord.java b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecord.java new file mode 100644 index 00000000000..cd315d924a3 --- /dev/null +++ b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecord.java @@ -0,0 +1,21 @@ +package org.matsim.core.replanning.inheritance; + +import java.util.ArrayList; +import java.util.List; + +public class PlanInheritanceRecord { + + String agentId; + String planId; + String ancestorId; + String mutatedBy; + int iterationCreated; + int iterationRemoved; + + /** + * Collection of iterations this plan had been the selected plan. + * Initialize this with one since each plan is selected at least once. + */ + List iterationsSelected = new ArrayList<>(1); + +} diff --git a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecordWriter.java b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecordWriter.java new file mode 100644 index 00000000000..2d4acde2cc5 --- /dev/null +++ b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecordWriter.java @@ -0,0 +1,74 @@ +package org.matsim.core.replanning.inheritance; + +import java.io.BufferedWriter; +import java.io.IOException; + +import org.matsim.core.utils.io.IOUtils; + +public class PlanInheritanceRecordWriter { + + public final String AGENT_ID = "agentId"; + public final String PLAN_ID = "planId"; + public final String ANCESTOR_ID = "ancestorId"; + public final String MUTATED_BY = "mutatedBy"; + public final String ITERATION_CREATED = "iterationCreated"; + public final String ITERATION_REMOVED = "iterationRemoved"; + public final String ITERATIONS_SELECTED = "iterationsSelected"; + + private final Character DELIMITER = '\t'; + private final BufferedWriter writer; + + public PlanInheritanceRecordWriter(String filename) { + this.writer = IOUtils.getBufferedWriter(filename); + + StringBuffer header = new StringBuffer(); + header.append(AGENT_ID); header.append(DELIMITER); + header.append(PLAN_ID); header.append(DELIMITER); + header.append(ANCESTOR_ID); header.append(DELIMITER); + header.append(MUTATED_BY); header.append(DELIMITER); + header.append(ITERATION_CREATED); header.append(DELIMITER); + header.append(ITERATION_REMOVED); header.append(DELIMITER); + header.append(ITERATIONS_SELECTED); + + try { + this.writer.write(header.toString()); + this.writer.newLine(); + } catch (IOException e) { + throw new RuntimeException("Could not initialize the plan inheritance writer!", e); + } + } + + public void write(PlanInheritanceRecord planInheritanceRecord) { + StringBuffer line = new StringBuffer(); + line.append(planInheritanceRecord.agentId); line.append(DELIMITER); + line.append(planInheritanceRecord.planId); line.append(DELIMITER); + line.append(planInheritanceRecord.ancestorId); line.append(DELIMITER); + line.append(planInheritanceRecord.mutatedBy); line.append(DELIMITER); + line.append(planInheritanceRecord.iterationCreated); line.append(DELIMITER); + line.append(planInheritanceRecord.iterationRemoved); line.append(DELIMITER); + line.append(planInheritanceRecord.iterationsSelected); + + try { + this.writer.write(line.toString()); + this.writer.newLine(); + } catch (IOException e) { + throw new RuntimeException("Could not initialize the plan inheritance writer!", e); + } + } + + public void flush() { + try { + this.writer.flush(); + } catch (IOException e) { + throw new RuntimeException("Failed to flush plan inheritance writer!", e); + } + } + + public void close() { + try { + this.writer.close(); + } catch (IOException e) { + throw new RuntimeException("Failed to close plan inheritance writer!", e); + } + } +} From 5af1b11298dcc44baad764b21bafbf9c037bce7f Mon Sep 17 00:00:00 2001 From: Andreas Neumann Date: Fri, 22 Sep 2023 08:05:25 +0200 Subject: [PATCH 2/9] added strat distribution stats --- .../inheritance/PlanInheritanceModule.java | 111 +++++++++++++++++- 1 file changed, 110 insertions(+), 1 deletion(-) diff --git a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java index 3c22bed37e3..55a34591e6b 100644 --- a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java +++ b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java @@ -1,15 +1,22 @@ package org.matsim.core.replanning.inheritance; +import java.io.BufferedWriter; +import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Plan; import org.matsim.core.config.groups.ControlerConfigGroup.CompressionType; +import org.matsim.core.config.groups.StrategyConfigGroup.StrategySettings; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.events.BeforeMobsimEvent; import org.matsim.core.controler.events.ShutdownEvent; @@ -18,6 +25,9 @@ import org.matsim.core.controler.listener.ShutdownListener; import org.matsim.core.controler.listener.StartupListener; import org.matsim.core.population.PersonUtils; +import org.matsim.core.replanning.GenericPlanStrategy; +import org.matsim.core.replanning.StrategyManager; +import org.matsim.core.utils.io.IOUtils; import com.google.inject.Singleton; @@ -37,17 +47,76 @@ public class PlanInheritanceModule extends AbstractModule implements StartupList Map planId2planInheritanceRecords = new ConcurrentHashMap<>(); PlanInheritanceRecordWriter planInheritanceRecordWriter; + private ArrayList strategies; + + private final Character DELIMITER = '\t'; + private BufferedWriter selectedPlanStrategyShareWriter; + private BufferedWriter planStrategyShareWriter; @Override public void notifyStartup(StartupEvent event) { CompressionType compressionType = event.getServices().getConfig().controler().getCompressionType(); - this.planInheritanceRecordWriter = new PlanInheritanceRecordWriter(event.getServices().getControlerIO().getOutputFilename(FILENAME_PLAN_INHERITANCE_RECORDS + ".csv", compressionType)); + this.planInheritanceRecordWriter = new PlanInheritanceRecordWriter(event.getServices().getControlerIO().getOutputFilename(FILENAME_PLAN_INHERITANCE_RECORDS + ".csv", compressionType)); + this.strategies = this.getActiveStrategies(event.getServices().getConfig().strategy().getStrategySettings(), event.getServices().getStrategyManager()); + this.selectedPlanStrategyShareWriter = this.initializeDistributionWriter(this.strategies, event.getServices().getControlerIO().getOutputFilename(FILENAME_PLAN_INHERITANCE_RECORDS + "_shares_selected.csv")); + this.planStrategyShareWriter = this.initializeDistributionWriter(this.strategies, event.getServices().getControlerIO().getOutputFilename(FILENAME_PLAN_INHERITANCE_RECORDS + "_shares.csv")); + } + + /** + * Retrieve all active plan strategies with their correct name in alphabetical order + */ + private ArrayList getActiveStrategies(Collection strategySettings, StrategyManager strategyManager) { + Set activeSubpopulations = new HashSet<>(); + for (StrategySettings strategySetting : strategySettings) { + activeSubpopulations.add(strategySetting.getSubpopulation()); + } + + Set planStrategiesNames = new HashSet<>(); + for (String subpopulation : activeSubpopulations) { + for (GenericPlanStrategy planStrategy : strategyManager.getStrategies(subpopulation)) { + planStrategiesNames.add(planStrategy.toString()); + } + } + + ArrayList strategies = new ArrayList<>(planStrategiesNames.size() + 1); + strategies.addAll(planStrategiesNames); + Collections.sort(strategies); + strategies.add(0, INITIAL_PLAN); + + return strategies; + } + + /** + * Initialize the writer with the active strategies + */ + private BufferedWriter initializeDistributionWriter(ArrayList strategies, String filename) { + + BufferedWriter planStrategyShareWriter = IOUtils.getBufferedWriter(filename); + + StringBuffer header = new StringBuffer(); + header.append("iteration"); header.append(DELIMITER); + for (int i = 0; i < strategies.size(); i++) { + if (i > 0) { + header.append(DELIMITER); + } + header.append(strategies.get(i)); + } + + try { + planStrategyShareWriter.write(header.toString()); + planStrategyShareWriter.newLine(); + } catch (IOException e) { + throw new RuntimeException("Could not initialize the plan strategy share writer!", e); + } + + return planStrategyShareWriter; } @Override public void notifyBeforeMobsim(BeforeMobsimEvent event) { Set activePlanIds = new HashSet<>(); + Set selectedPlanIds = new HashSet<>(); for (Person person : event.getServices().getScenario().getPopulation().getPersons().values()) { for (Plan plan : person.getPlans()) { @@ -74,6 +143,7 @@ public void notifyBeforeMobsim(BeforeMobsimEvent event) { if (PersonUtils.isSelected(plan)) { this.planId2planInheritanceRecords.get(plan.getPlanId()).iterationsSelected.add(event.getIteration()); + selectedPlanIds.add(plan.getPlanId()); } activePlanIds.add(plan.getPlanId()); @@ -94,6 +164,36 @@ public void notifyBeforeMobsim(BeforeMobsimEvent event) { } this.planInheritanceRecordWriter.flush(); + + this.calculateAndWriteDistribution(event.getIteration(), this.strategies, this.planId2planInheritanceRecords, selectedPlanIds, this.selectedPlanStrategyShareWriter); + this.calculateAndWriteDistribution(event.getIteration(), this.strategies, this.planId2planInheritanceRecords, this.planId2planInheritanceRecords.keySet(), this.planStrategyShareWriter); + } + + private void calculateAndWriteDistribution(int currentIteration, ArrayList strategies, Map planId2planInheritanceRecords, Set planIds, BufferedWriter writer) { + Map strategy2count = new HashMap<>(); + for (String strategyName : strategies) { + strategy2count.put(strategyName, new AtomicLong(0)); + } + for (String planId : planIds) { + String mutatedBy = planId2planInheritanceRecords.get(planId).mutatedBy; + strategy2count.get(mutatedBy).incrementAndGet(); + } + long sum = strategy2count.values().stream().mapToLong(count -> count.get()).sum(); + StringBuffer line = new StringBuffer(); + line.append(currentIteration); + line.append(DELIMITER); + for (int i = 0; i < strategies.size(); i++) { + if (i > 0) { + line.append(DELIMITER); + } + line.append(String.valueOf(strategy2count.get(strategies.get(i)).doubleValue() / sum)); + } + try { + writer.write(line.toString()); + writer.newLine(); + } catch (IOException e) { + throw new RuntimeException("Could not initialize the plan strategy share writer!", e); + } } @Override @@ -105,6 +205,15 @@ public void notifyShutdown(ShutdownEvent event) { this.planInheritanceRecordWriter.flush(); this.planInheritanceRecordWriter.close(); + try { + this.selectedPlanStrategyShareWriter.flush(); + this.selectedPlanStrategyShareWriter.close(); + this.planStrategyShareWriter.flush(); + this.planStrategyShareWriter.close(); + } catch (IOException e) { + new RuntimeException(e); + } + this.planId2planInheritanceRecords.clear(); } From f302b4b9a403d0f5e0c8af5c960b006a827305fa Mon Sep 17 00:00:00 2001 From: Andreas Neumann Date: Wed, 27 Sep 2023 09:26:52 +0200 Subject: [PATCH 3/9] some javadoc --- .../inheritance/PlanInheritanceModule.java | 45 ++++++++++++++++- .../inheritance/PlanInheritanceRecord.java | 48 +++++++++++++++++++ .../PlanInheritanceRecordWriter.java | 25 ++++++++++ 3 files changed, 117 insertions(+), 1 deletion(-) diff --git a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java index 55a34591e6b..c16514a4ecc 100644 --- a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java +++ b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java @@ -1,5 +1,25 @@ package org.matsim.core.replanning.inheritance; +/* *********************************************************************** * + * project: org.matsim.* + * ParallelPopulationReaderMatsimV6.java + * * + * *********************************************************************** * + * * + * copyright : (C) 2023 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** */ + import java.io.BufferedWriter; import java.io.IOException; import java.util.ArrayList; @@ -31,9 +51,16 @@ import com.google.inject.Singleton; +/** + * The core plan inheritance module responsible for + *
  • Initialization of initially read plans and default writers + *
  • Book-keeping, i.e. setting additional plan attributes not stored in the plan itself + *
  • Calculation default stats like the distribution of mutators among (selected) plans + * + * @author neuma + */ @Singleton public class PlanInheritanceModule extends AbstractModule implements StartupListener, BeforeMobsimListener, ShutdownListener { - public static final String PLAN_ID = "planId"; public static final String ITERATION_CREATED = "iterationCreated"; @@ -55,11 +82,21 @@ public class PlanInheritanceModule extends AbstractModule implements StartupList @Override public void notifyStartup(StartupEvent event) { + // initialize all default writers CompressionType compressionType = event.getServices().getConfig().controler().getCompressionType(); this.planInheritanceRecordWriter = new PlanInheritanceRecordWriter(event.getServices().getControlerIO().getOutputFilename(FILENAME_PLAN_INHERITANCE_RECORDS + ".csv", compressionType)); this.strategies = this.getActiveStrategies(event.getServices().getConfig().strategy().getStrategySettings(), event.getServices().getStrategyManager()); this.selectedPlanStrategyShareWriter = this.initializeDistributionWriter(this.strategies, event.getServices().getControlerIO().getOutputFilename(FILENAME_PLAN_INHERITANCE_RECORDS + "_shares_selected.csv")); this.planStrategyShareWriter = this.initializeDistributionWriter(this.strategies, event.getServices().getControlerIO().getOutputFilename(FILENAME_PLAN_INHERITANCE_RECORDS + "_shares.csv")); + + // reset all plan attributes that might be present from a previously performed matsim run + for (Person person : event.getServices().getScenario().getPopulation().getPersons().values()) { + for (Plan plan : person.getPlans()) { + plan.setPlanId(null); + plan.setPlanMutator(null); + plan.setIterationCreated(0); + } + } } /** @@ -114,6 +151,7 @@ private BufferedWriter initializeDistributionWriter(ArrayList strategies @Override public void notifyBeforeMobsim(BeforeMobsimEvent event) { + // check the plans of the population and all currently stored plan records - do the actual book-keeping Set activePlanIds = new HashSet<>(); Set selectedPlanIds = new HashSet<>(); @@ -169,6 +207,9 @@ public void notifyBeforeMobsim(BeforeMobsimEvent event) { this.calculateAndWriteDistribution(event.getIteration(), this.strategies, this.planId2planInheritanceRecords, this.planId2planInheritanceRecords.keySet(), this.planStrategyShareWriter); } + /** + * Updates the default plan stats - namely the distribution of plan mutators based on the given plan ids. + */ private void calculateAndWriteDistribution(int currentIteration, ArrayList strategies, Map planId2planInheritanceRecords, Set planIds, BufferedWriter writer) { Map strategy2count = new HashMap<>(); for (String strategyName : strategies) { @@ -198,6 +239,8 @@ private void calculateAndWriteDistribution(int currentIteration, ArrayList Date: Tue, 10 Oct 2023 14:07:51 +0200 Subject: [PATCH 4/9] added PlanInheritanceConfigGroup.java to en-/disable planInheritance, intialised planInheritance attributes != null bc planAttributes writer --- .../java/org/matsim/core/config/Config.java | 11 +++- .../groups/PlanInheritanceConfigGroup.java | 59 +++++++++++++++++++ .../replanning/GenericPlanStrategyImpl.java | 3 +- .../inheritance/PlanInheritanceModule.java | 8 ++- 4 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 matsim/src/main/java/org/matsim/core/config/groups/PlanInheritanceConfigGroup.java diff --git a/matsim/src/main/java/org/matsim/core/config/Config.java b/matsim/src/main/java/org/matsim/core/config/Config.java index ecff0be5678..a409e64d579 100644 --- a/matsim/src/main/java/org/matsim/core/config/Config.java +++ b/matsim/src/main/java/org/matsim/core/config/Config.java @@ -47,8 +47,7 @@ import org.matsim.core.config.groups.NetworkConfigGroup; import org.matsim.core.config.groups.ReplanningConfigGroup; import org.matsim.core.config.groups.ScoringConfigGroup; -import org.matsim.core.config.groups.RoutingConfigGroup; -import org.matsim.core.config.groups.PlansConfigGroup; +import org.matsim.core.config.groups.RoutingConfigGroup;import org.matsim.core.config.groups.PlansConfigGroup; import org.matsim.core.config.groups.QSimConfigGroup; import org.matsim.core.config.groups.ScenarioConfigGroup; import org.matsim.core.config.groups.SubtourModeChoiceConfigGroup; @@ -123,7 +122,6 @@ public void addCoreModules() { this.modules.put(QSimConfigGroup.GROUP_NAME, new QSimConfigGroup()); this.modules.put(CountsConfigGroup.GROUP_NAME, new CountsConfigGroup()); - this.modules.put(ScoringConfigGroup.GROUP_NAME, new ScoringConfigGroup()); this.modules.put(NetworkConfigGroup.GROUP_NAME, new NetworkConfigGroup()); @@ -147,6 +145,7 @@ public void addCoreModules() { this.modules.put(TimeAllocationMutatorConfigGroup.GROUP_NAME, new TimeAllocationMutatorConfigGroup()); this.modules.put(VspExperimentalConfigGroup.GROUP_NAME, new VspExperimentalConfigGroup()); + this.modules.put(TransitConfigGroup.GROUP_NAME, new TransitConfigGroup()); @@ -168,6 +167,8 @@ public void addCoreModules() { this.modules.put(HermesConfigGroup.NAME, new HermesConfigGroup()); this.modules.put(ReplanningAnnealerConfigGroup.GROUP_NAME, new ReplanningAnnealerConfigGroup()); + + this.modules.put(PlanInheritanceConfigGroup.GROUP_NAME, new PlanInheritanceConfigGroup()); this.addConfigConsistencyChecker(new VspConfigConsistencyCheckerImpl()); this.addConfigConsistencyChecker(new UnmaterializedConfigGroupChecker()); @@ -488,6 +489,10 @@ public HermesConfigGroup hermes() { public ReplanningAnnealerConfigGroup replanningAnnealer() { return (ReplanningAnnealerConfigGroup) this.getModule(ReplanningAnnealerConfigGroup.GROUP_NAME); } + + public PlanInheritanceConfigGroup planInheritance() { + return (PlanInheritanceConfigGroup) this.getModule(PlanInheritanceConfigGroup.GROUP_NAME); + } // other: diff --git a/matsim/src/main/java/org/matsim/core/config/groups/PlanInheritanceConfigGroup.java b/matsim/src/main/java/org/matsim/core/config/groups/PlanInheritanceConfigGroup.java new file mode 100644 index 00000000000..922f2e37eb0 --- /dev/null +++ b/matsim/src/main/java/org/matsim/core/config/groups/PlanInheritanceConfigGroup.java @@ -0,0 +1,59 @@ +/* *********************************************************************** * + * project: org.matsim.* + * * + * *********************************************************************** * + * * + * copyright : (C) 2011 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** */ + +package org.matsim.core.config.groups; + +import java.util.Map; + +import org.matsim.core.config.ReflectiveConfigGroup; + +/** + * @author awagner + */ +public final class PlanInheritanceConfigGroup extends ReflectiveConfigGroup { + + public static final String GROUP_NAME = "planInheritance"; + + private static final String ENABLED = "enabled"; + + private boolean enabled = false; + + public PlanInheritanceConfigGroup() { + super(GROUP_NAME); + } + + @Override + public Map getComments() { + Map comments = super.getComments(); + comments.put(ENABLED, "Specifies whether or not PlanInheritance Information should be tracked."); + return comments; + } + + + @StringSetter( ENABLED ) + public void setWriteLinkStatsInterval(boolean enabled) { + this.enabled = enabled; + } + + + @StringGetter( ENABLED ) + public boolean getEnabled() { + return this.enabled; + } +} diff --git a/matsim/src/main/java/org/matsim/core/replanning/GenericPlanStrategyImpl.java b/matsim/src/main/java/org/matsim/core/replanning/GenericPlanStrategyImpl.java index 341e32d1ca6..75daefffb28 100644 --- a/matsim/src/main/java/org/matsim/core/replanning/GenericPlanStrategyImpl.java +++ b/matsim/src/main/java/org/matsim/core/replanning/GenericPlanStrategyImpl.java @@ -93,7 +93,8 @@ public void run(final HasPlansAndId person) { // set the working plan to a copy of the selected plan: plan = person.createCopyOfSelectedPlanAndMakeSelected(); - if (plan instanceof Plan) { + //planId is only set inside planInheritance -> if null planInheritance is disabled + if (plan instanceof Plan && ((Plan) plan).getPlanId() != null) { // add plan inheritance flags ((Plan) plan).setIterationCreated(this.replanningContext.getIteration()); ((Plan) plan).setPlanMutator(this.toString()); diff --git a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java index c16514a4ecc..c400c04b234 100644 --- a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java +++ b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java @@ -36,6 +36,7 @@ import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Plan; import org.matsim.core.config.groups.ControlerConfigGroup.CompressionType; +import org.matsim.core.config.groups.PlanInheritanceConfigGroup; import org.matsim.core.config.groups.StrategyConfigGroup.StrategySettings; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.events.BeforeMobsimEvent; @@ -47,6 +48,7 @@ import org.matsim.core.population.PersonUtils; import org.matsim.core.replanning.GenericPlanStrategy; import org.matsim.core.replanning.StrategyManager; +import org.matsim.core.replanning.annealing.ReplanningAnnealerConfigGroup; import org.matsim.core.utils.io.IOUtils; import com.google.inject.Singleton; @@ -92,8 +94,8 @@ public void notifyStartup(StartupEvent event) { // reset all plan attributes that might be present from a previously performed matsim run for (Person person : event.getServices().getScenario().getPopulation().getPersons().values()) { for (Plan plan : person.getPlans()) { - plan.setPlanId(null); - plan.setPlanMutator(null); + plan.setPlanId(Long.toString(0, 36)); + plan.setPlanMutator(INITIAL_PLAN); plan.setIterationCreated(0); } } @@ -262,6 +264,6 @@ public void notifyShutdown(ShutdownEvent event) { @Override public void install() { - addControlerListenerBinding().to(PlanInheritanceModule.class); + if (getConfig().planInheritance().getEnabled()) addControlerListenerBinding().to(PlanInheritanceModule.class); } } From 805ed4695aa5fc62c23c9b3b185db0f4e8354093 Mon Sep 17 00:00:00 2001 From: awagner Date: Tue, 10 Oct 2023 15:22:51 +0200 Subject: [PATCH 5/9] added new Plan setter and getter UnsupportedOperationException to LCPlan.java --- .../locationchoice/zzunused/LCPlan.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/contribs/locationchoice/src/main/java/org/matsim/contrib/locationchoice/zzunused/LCPlan.java b/contribs/locationchoice/src/main/java/org/matsim/contrib/locationchoice/zzunused/LCPlan.java index 75da3189c3a..b92cf6ebe7f 100644 --- a/contribs/locationchoice/src/main/java/org/matsim/contrib/locationchoice/zzunused/LCPlan.java +++ b/contribs/locationchoice/src/main/java/org/matsim/contrib/locationchoice/zzunused/LCPlan.java @@ -285,4 +285,35 @@ else if (planElement instanceof Leg) { destPlan.score = srcPlan.getScore(); } + @Override + public void setPlanId(String planId) { + throw new UnsupportedOperationException(); + + } + + @Override + public String getPlanId() { + throw new UnsupportedOperationException(); + } + + @Override + public int getIterationCreated() { + throw new UnsupportedOperationException(); + } + + @Override + public void setIterationCreated(int iteration) { + throw new UnsupportedOperationException(); + } + + @Override + public String getPlanMutator() { + throw new UnsupportedOperationException(); + } + + @Override + public void setPlanMutator(String planMutator) { + throw new UnsupportedOperationException(); + } + } From b733b6625702c66a4d15361dcbf8e4c8dc79b578 Mon Sep 17 00:00:00 2001 From: awagner Date: Wed, 11 Oct 2023 10:58:30 +0200 Subject: [PATCH 6/9] changed Initial planId to NONE --- .../core/replanning/inheritance/PlanInheritanceModule.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java index c400c04b234..e8b2b30fbe5 100644 --- a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java +++ b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java @@ -69,6 +69,7 @@ public class PlanInheritanceModule extends AbstractModule implements StartupList public static final String PLAN_MUTATOR = "planMutator"; public static final String INITIAL_PLAN = "initialPlan"; + public static final String NONE = "NONE"; public static final String FILENAME_PLAN_INHERITANCE_RECORDS = "planInheritanceRecords"; @@ -94,7 +95,7 @@ public void notifyStartup(StartupEvent event) { // reset all plan attributes that might be present from a previously performed matsim run for (Person person : event.getServices().getScenario().getPopulation().getPersons().values()) { for (Plan plan : person.getPlans()) { - plan.setPlanId(Long.toString(0, 36)); + plan.setPlanId(NONE); plan.setPlanMutator(INITIAL_PLAN); plan.setIterationCreated(0); } From b6bada133d201672029530fba3fd83ec4ebdfcfe Mon Sep 17 00:00:00 2001 From: awagner Date: Wed, 11 Oct 2023 15:42:31 +0200 Subject: [PATCH 7/9] switched from String to Id<> for planId, Junit Test, Record Reader --- .../dvrp/vrpagent/VrpAgentQueryHelper.java | 5 +- .../locationchoice/zzunused/LCPlan.java | 4 +- .../distributed/plans/PlanGenome.java | 4 +- .../population/PlanWithCachedJointPlan.java | 5 +- .../matsim/api/core/v01/population/Plan.java | 5 +- .../groups/PlanInheritanceConfigGroup.java | 2 +- .../org/matsim/core/population/PlanImpl.java | 7 +- .../core/population/PopulationUtils.java | 4 +- .../inheritance/PlanInheritanceModule.java | 41 +++---- .../inheritance/PlanInheritanceRecord.java | 75 ++++++++++-- .../PlanInheritanceRecordReader.java | 95 +++++++++++++++ .../PlanInheritanceRecordWriter.java | 30 ++--- .../planInheritance/PlanInheritanceTest.java | 110 ++++++++++++++++++ 13 files changed, 328 insertions(+), 59 deletions(-) create mode 100644 matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecordReader.java create mode 100644 matsim/src/test/java/org/matsim/core/replanning/planInheritance/PlanInheritanceTest.java diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/vrpagent/VrpAgentQueryHelper.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/vrpagent/VrpAgentQueryHelper.java index 64e15ad5036..ddb8d2e6f08 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/vrpagent/VrpAgentQueryHelper.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/vrpagent/VrpAgentQueryHelper.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.Map; +import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.TransportMode; import org.matsim.api.core.v01.population.Activity; import org.matsim.api.core.v01.population.Leg; @@ -170,12 +171,12 @@ public void setIterationCreated(int iteration) { } @Override - public String getPlanId() { + public Id getPlanId() { throw new UnsupportedOperationException(); } @Override - public void setPlanId(String planId) { + public void setPlanId(Id planId) { throw new UnsupportedOperationException(); } diff --git a/contribs/locationchoice/src/main/java/org/matsim/contrib/locationchoice/zzunused/LCPlan.java b/contribs/locationchoice/src/main/java/org/matsim/contrib/locationchoice/zzunused/LCPlan.java index b92cf6ebe7f..f9a167cde9a 100644 --- a/contribs/locationchoice/src/main/java/org/matsim/contrib/locationchoice/zzunused/LCPlan.java +++ b/contribs/locationchoice/src/main/java/org/matsim/contrib/locationchoice/zzunused/LCPlan.java @@ -286,13 +286,13 @@ else if (planElement instanceof Leg) { } @Override - public void setPlanId(String planId) { + public void setPlanId(Id planId) { throw new UnsupportedOperationException(); } @Override - public String getPlanId() { + public Id getPlanId() { throw new UnsupportedOperationException(); } diff --git a/contribs/pseudosimulation/src/main/java/org/matsim/contrib/pseudosimulation/distributed/plans/PlanGenome.java b/contribs/pseudosimulation/src/main/java/org/matsim/contrib/pseudosimulation/distributed/plans/PlanGenome.java index 63f9bf8d8d9..34f725fc92a 100644 --- a/contribs/pseudosimulation/src/main/java/org/matsim/contrib/pseudosimulation/distributed/plans/PlanGenome.java +++ b/contribs/pseudosimulation/src/main/java/org/matsim/contrib/pseudosimulation/distributed/plans/PlanGenome.java @@ -221,10 +221,10 @@ public void setType(final String type) { } @Override - public String getPlanId() { return null; } + public Id getPlanId() { return null; } @Override - public void setPlanId(String planId) { /* nothing to do here */ } + public void setPlanId(Id planId) { /* nothing to do here */ } @Override public int getIterationCreated() { return -1; } diff --git a/contribs/socnetsim/src/main/java/org/matsim/contrib/socnetsim/framework/population/PlanWithCachedJointPlan.java b/contribs/socnetsim/src/main/java/org/matsim/contrib/socnetsim/framework/population/PlanWithCachedJointPlan.java index 00e96f82d89..ce912ec1682 100644 --- a/contribs/socnetsim/src/main/java/org/matsim/contrib/socnetsim/framework/population/PlanWithCachedJointPlan.java +++ b/contribs/socnetsim/src/main/java/org/matsim/contrib/socnetsim/framework/population/PlanWithCachedJointPlan.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Map; +import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.population.Activity; import org.matsim.api.core.v01.population.Leg; import org.matsim.api.core.v01.population.Person; @@ -174,10 +175,10 @@ public void setType(String type) { } @Override - public String getPlanId() { return null; } + public Id getPlanId() { return null; } @Override - public void setPlanId(String planId) { /* nothing to do here */ } + public void setPlanId(Id planId) { /* nothing to do here */ } @Override public int getIterationCreated() { return -1; } diff --git a/matsim/src/main/java/org/matsim/api/core/v01/population/Plan.java b/matsim/src/main/java/org/matsim/api/core/v01/population/Plan.java index 556f1e80d8a..85e7775e9b9 100644 --- a/matsim/src/main/java/org/matsim/api/core/v01/population/Plan.java +++ b/matsim/src/main/java/org/matsim/api/core/v01/population/Plan.java @@ -23,6 +23,7 @@ import java.util.List; import org.matsim.api.core.v01.Customizable; +import org.matsim.api.core.v01.Id; import org.matsim.core.api.internal.MatsimPopulationObject; import org.matsim.utils.objectattributes.attributable.Attributable; @@ -50,9 +51,9 @@ public interface Plan extends MatsimPopulationObject, Customizable, BasicPlan, A public abstract void setType(final String type); - public abstract void setPlanId(final String planId); + public abstract void setPlanId(final Id planId); - public abstract String getPlanId(); + public abstract Id getPlanId(); public abstract int getIterationCreated(); diff --git a/matsim/src/main/java/org/matsim/core/config/groups/PlanInheritanceConfigGroup.java b/matsim/src/main/java/org/matsim/core/config/groups/PlanInheritanceConfigGroup.java index 922f2e37eb0..b889df2fa15 100644 --- a/matsim/src/main/java/org/matsim/core/config/groups/PlanInheritanceConfigGroup.java +++ b/matsim/src/main/java/org/matsim/core/config/groups/PlanInheritanceConfigGroup.java @@ -47,7 +47,7 @@ public Map getComments() { @StringSetter( ENABLED ) - public void setWriteLinkStatsInterval(boolean enabled) { + public void setEnabled(boolean enabled) { this.enabled = enabled; } diff --git a/matsim/src/main/java/org/matsim/core/population/PlanImpl.java b/matsim/src/main/java/org/matsim/core/population/PlanImpl.java index 08047673bfd..4d7f0fd0363 100644 --- a/matsim/src/main/java/org/matsim/core/population/PlanImpl.java +++ b/matsim/src/main/java/org/matsim/core/population/PlanImpl.java @@ -27,6 +27,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.Customizable; +import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.population.Activity; import org.matsim.api.core.v01.population.Leg; import org.matsim.api.core.v01.population.Person; @@ -124,12 +125,12 @@ public void setType(final String type) { } @Override - public String getPlanId() { - return (String) this.getAttributes().getAttribute(PlanInheritanceModule.PLAN_ID); + public Id getPlanId() { + return (Id) this.getAttributes().getAttribute(PlanInheritanceModule.PLAN_ID); } @Override - public void setPlanId(String planId) { + public void setPlanId(Id planId) { this.getAttributes().putAttribute(PlanInheritanceModule.PLAN_ID, planId); } diff --git a/matsim/src/main/java/org/matsim/core/population/PopulationUtils.java b/matsim/src/main/java/org/matsim/core/population/PopulationUtils.java index ed49e66ed22..adac6f947a2 100644 --- a/matsim/src/main/java/org/matsim/core/population/PopulationUtils.java +++ b/matsim/src/main/java/org/matsim/core/population/PopulationUtils.java @@ -383,12 +383,12 @@ public void setType(String type) { } @Override - public String getPlanId() { + public Id getPlanId() { return this.delegate.getPlanId(); } @Override - public void setPlanId(String planId) { + public void setPlanId(Id planId) { throw new UnsupportedOperationException(); } diff --git a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java index e8b2b30fbe5..80ef946b263 100644 --- a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java +++ b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java @@ -33,6 +33,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; +import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Plan; import org.matsim.core.config.groups.ControlerConfigGroup.CompressionType; @@ -59,7 +60,7 @@ *
  • Book-keeping, i.e. setting additional plan attributes not stored in the plan itself *
  • Calculation default stats like the distribution of mutators among (selected) plans * - * @author neuma + * @author neuma, alex94263 */ @Singleton public class PlanInheritanceModule extends AbstractModule implements StartupListener, BeforeMobsimListener, ShutdownListener { @@ -74,7 +75,7 @@ public class PlanInheritanceModule extends AbstractModule implements StartupList public static final String FILENAME_PLAN_INHERITANCE_RECORDS = "planInheritanceRecords"; long numberOfPlanInheritanceRecordsCreated = 0; - Map planId2planInheritanceRecords = new ConcurrentHashMap<>(); + Map, PlanInheritanceRecord> planId2planInheritanceRecords = new ConcurrentHashMap<>(); PlanInheritanceRecordWriter planInheritanceRecordWriter; private ArrayList strategies; @@ -95,7 +96,7 @@ public void notifyStartup(StartupEvent event) { // reset all plan attributes that might be present from a previously performed matsim run for (Person person : event.getServices().getScenario().getPopulation().getPersons().values()) { for (Plan plan : person.getPlans()) { - plan.setPlanId(NONE); + plan.setPlanId(Id.create(NONE, String.class)); plan.setPlanMutator(INITIAL_PLAN); plan.setIterationCreated(0); } @@ -156,8 +157,8 @@ private BufferedWriter initializeDistributionWriter(ArrayList strategies public void notifyBeforeMobsim(BeforeMobsimEvent event) { // check the plans of the population and all currently stored plan records - do the actual book-keeping - Set activePlanIds = new HashSet<>(); - Set selectedPlanIds = new HashSet<>(); + Set> activePlanIds = new HashSet<>(); + Set> selectedPlanIds = new HashSet<>(); for (Person person : event.getServices().getScenario().getPopulation().getPersons().values()) { for (Plan plan : person.getPlans()) { @@ -172,18 +173,18 @@ public void notifyBeforeMobsim(BeforeMobsimEvent event) { // it's a new plan created in this iteration - create a new record PlanInheritanceRecord planInheritanceRecord = new PlanInheritanceRecord(); - planInheritanceRecord.agentId = person.getId().toString(); - planInheritanceRecord.planId = Long.toString(++this.numberOfPlanInheritanceRecordsCreated, 36); - planInheritanceRecord.ancestorId = plan.getPlanId(); - plan.setPlanId(planInheritanceRecord.planId); - planInheritanceRecord.iterationCreated = plan.getIterationCreated(); - planInheritanceRecord.mutatedBy = plan.getPlanMutator(); + planInheritanceRecord.setAgentId(person.getId()); + planInheritanceRecord.setPlanId( Id.create(Long.toString(++this.numberOfPlanInheritanceRecordsCreated, 36), String.class) ); + planInheritanceRecord.setAncestorId(plan.getPlanId()); + plan.setPlanId(planInheritanceRecord.getPlanId()); + planInheritanceRecord.setIterationCreated(plan.getIterationCreated()); + planInheritanceRecord.setMutatedBy(plan.getPlanMutator()); - this.planId2planInheritanceRecords.put(planInheritanceRecord.planId, planInheritanceRecord); + this.planId2planInheritanceRecords.put(planInheritanceRecord.getPlanId(), planInheritanceRecord); } if (PersonUtils.isSelected(plan)) { - this.planId2planInheritanceRecords.get(plan.getPlanId()).iterationsSelected.add(event.getIteration()); + this.planId2planInheritanceRecords.get(plan.getPlanId()).getIterationsSelected().add(event.getIteration()); selectedPlanIds.add(plan.getPlanId()); } @@ -191,16 +192,16 @@ public void notifyBeforeMobsim(BeforeMobsimEvent event) { } } - List deletedPlans = new ArrayList<>(); - for (String planId : this.planId2planInheritanceRecords.keySet()) { + List> deletedPlans = new ArrayList<>(); + for (Id planId : this.planId2planInheritanceRecords.keySet()) { if (!activePlanIds.contains(planId)) { deletedPlans.add(planId); } } - for (String deletedPlanId : deletedPlans) { + for (Id deletedPlanId : deletedPlans) { PlanInheritanceRecord deletedPlanInheritanceRecord = this.planId2planInheritanceRecords.remove(deletedPlanId); - deletedPlanInheritanceRecord.iterationRemoved = event.getIteration(); + deletedPlanInheritanceRecord.setIterationRemoved(event.getIteration()); this.planInheritanceRecordWriter.write(deletedPlanInheritanceRecord); } @@ -213,13 +214,13 @@ public void notifyBeforeMobsim(BeforeMobsimEvent event) { /** * Updates the default plan stats - namely the distribution of plan mutators based on the given plan ids. */ - private void calculateAndWriteDistribution(int currentIteration, ArrayList strategies, Map planId2planInheritanceRecords, Set planIds, BufferedWriter writer) { + private void calculateAndWriteDistribution(int currentIteration, ArrayList strategies, Map, PlanInheritanceRecord> planId2planInheritanceRecords, Set> planIds, BufferedWriter writer) { Map strategy2count = new HashMap<>(); for (String strategyName : strategies) { strategy2count.put(strategyName, new AtomicLong(0)); } - for (String planId : planIds) { - String mutatedBy = planId2planInheritanceRecords.get(planId).mutatedBy; + for (Id planId : planIds) { + String mutatedBy = planId2planInheritanceRecords.get(planId).getMutatedBy(); strategy2count.get(mutatedBy).incrementAndGet(); } long sum = strategy2count.values().stream().mapToLong(count -> count.get()).sum(); diff --git a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecord.java b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecord.java index 90dc463d98f..8a3e54280ac 100644 --- a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecord.java +++ b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecord.java @@ -23,47 +23,106 @@ import java.util.ArrayList; import java.util.List; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.population.Person; + /** * Data container storing the data of a single plan. * - * @author neuma + * @author neuma, alex94263 */ public class PlanInheritanceRecord { /** * Id of the person that plan record belongs to. */ - String agentId; + private Id agentId; /** * The globally unique plan id. */ - String planId; + private Id planId; /** * Id of the plan that this plan had been copied from before mutating. */ - String ancestorId; + private Id ancestorId; /** * The name of the strategy that altered this plan. */ - String mutatedBy; + private String mutatedBy; /** * Iteration in which this plan had been created. May be {@linkplain PlanInheritanceModule#INITIAL_PLAN} if the plan had been in the choice-set from the very beginning. */ - int iterationCreated; + private int iterationCreated; /** * Iteration in which the plan had been removed from the choice-set. */ - int iterationRemoved; + private int iterationRemoved; /** * Collection of iterations this plan had been the selected plan. * Initialize this with one since each plan is selected at least once. */ - List iterationsSelected = new ArrayList<>(1); + private List iterationsSelected = new ArrayList<>(1); + + public Id getPlanId() { + return planId; + } + + public void setPlanId(Id planId) { + this.planId = planId; + } + + public Id getAncestorId() { + return ancestorId; + } + + public void setAncestorId(Id ancestorId) { + this.ancestorId = ancestorId; + } + + public String getMutatedBy() { + return mutatedBy; + } + + public void setMutatedBy(String mutatedBy) { + this.mutatedBy = mutatedBy; + } + + public int getIterationCreated() { + return iterationCreated; + } + + public void setIterationCreated(int iterationCreated) { + this.iterationCreated = iterationCreated; + } + + public int getIterationRemoved() { + return iterationRemoved; + } + + public void setIterationRemoved(int iterationRemoved) { + this.iterationRemoved = iterationRemoved; + } + + public List getIterationsSelected() { + return iterationsSelected; + } + + public void setIterationsSelected(List iterationsSelected) { + this.iterationsSelected = iterationsSelected; + } + + public Id getAgentId() { + return agentId; + } + + public void setAgentId(Id agentId) { + this.agentId = agentId; + } } diff --git a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecordReader.java b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecordReader.java new file mode 100644 index 00000000000..a6b90fbd44e --- /dev/null +++ b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecordReader.java @@ -0,0 +1,95 @@ +package org.matsim.core.replanning.inheritance; + +import java.io.BufferedReader; + +/* *********************************************************************** * + * project: org.matsim.* + * ParallelPopulationReaderMatsimV6.java + * * + * *********************************************************************** * + * * + * copyright : (C) 2023 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** */ + +import java.io.BufferedWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.matsim.api.core.v01.Id; +import org.matsim.core.utils.io.IOUtils; + +/** + * Writes {@linkplain PlanInheritanceRecord} to file in a fixed column sequence. + * + * @author alex94263 + */ +public class PlanInheritanceRecordReader { + + + private final String DELIMITER = "\t"; + private final BufferedReader reader; + + public PlanInheritanceRecordReader(String filename) { + this.reader = IOUtils.getBufferedReader(filename); + + + + } + public Map buildIdx(String[] header) { + Map lookup = new HashMap(); + for (int i=0; i read() { + List records = new ArrayList(); + try { + Map lookUp = buildIdx(reader.readLine().split(DELIMITER)); + String lineString = reader.readLine(); + while(lineString !=null) { + String[] line = lineString.split(DELIMITER); + PlanInheritanceRecord planInheritanceRecord = new PlanInheritanceRecord(); + planInheritanceRecord.setAgentId(Id.createPersonId(line[lookUp.get(PlanInheritanceRecordWriter.AGENT_ID)])); + planInheritanceRecord.setPlanId(Id.create(line[lookUp.get(PlanInheritanceRecordWriter.PLAN_ID)], String.class)); + planInheritanceRecord.setAncestorId(Id.create(line[lookUp.get(PlanInheritanceRecordWriter.ANCESTOR_ID)], String.class)); + planInheritanceRecord.setMutatedBy(line[lookUp.get(PlanInheritanceRecordWriter.MUTATED_BY)]); + planInheritanceRecord.setIterationCreated(Integer.parseInt(line[lookUp.get(PlanInheritanceRecordWriter.ITERATION_CREATED)])); + planInheritanceRecord.setIterationRemoved(Integer.parseInt(line[lookUp.get(PlanInheritanceRecordWriter.ITERATION_REMOVED)])); + String iterationsSelected = line[lookUp.get(PlanInheritanceRecordWriter.ITERATIONS_SELECTED)]; + planInheritanceRecord.setIterationsSelected(Arrays.asList(iterationsSelected.substring(1, iterationsSelected.length()-1).split(", ")).stream() + .map(Integer::parseInt) + .collect(Collectors.toList())); + records.add(planInheritanceRecord); + lineString = reader.readLine(); + } + return records; + + } catch (IOException e) { + throw new RuntimeException("Could not read the plan inheritance records!", e); + } + + + + } + + +} diff --git a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecordWriter.java b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecordWriter.java index 04c3729ac11..1400a915406 100644 --- a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecordWriter.java +++ b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecordWriter.java @@ -28,17 +28,17 @@ /** * Writes {@linkplain PlanInheritanceRecord} to file in a fixed column sequence. * - * @author neuma + * @author neuma, alex94263 */ public class PlanInheritanceRecordWriter { - public final String AGENT_ID = "agentId"; - public final String PLAN_ID = "planId"; - public final String ANCESTOR_ID = "ancestorId"; - public final String MUTATED_BY = "mutatedBy"; - public final String ITERATION_CREATED = "iterationCreated"; - public final String ITERATION_REMOVED = "iterationRemoved"; - public final String ITERATIONS_SELECTED = "iterationsSelected"; + public static final String AGENT_ID = "agentId"; + public static final String PLAN_ID = "planId"; + public static final String ANCESTOR_ID = "ancestorId"; + public static final String MUTATED_BY = "mutatedBy"; + public static final String ITERATION_CREATED = "iterationCreated"; + public static final String ITERATION_REMOVED = "iterationRemoved"; + public static final String ITERATIONS_SELECTED = "iterationsSelected"; private final Character DELIMITER = '\t'; private final BufferedWriter writer; @@ -65,13 +65,13 @@ public PlanInheritanceRecordWriter(String filename) { public void write(PlanInheritanceRecord planInheritanceRecord) { StringBuffer line = new StringBuffer(); - line.append(planInheritanceRecord.agentId); line.append(DELIMITER); - line.append(planInheritanceRecord.planId); line.append(DELIMITER); - line.append(planInheritanceRecord.ancestorId); line.append(DELIMITER); - line.append(planInheritanceRecord.mutatedBy); line.append(DELIMITER); - line.append(planInheritanceRecord.iterationCreated); line.append(DELIMITER); - line.append(planInheritanceRecord.iterationRemoved); line.append(DELIMITER); - line.append(planInheritanceRecord.iterationsSelected); + line.append(planInheritanceRecord.getAgentId()); line.append(DELIMITER); + line.append(planInheritanceRecord.getPlanId()); line.append(DELIMITER); + line.append(planInheritanceRecord.getAncestorId()); line.append(DELIMITER); + line.append(planInheritanceRecord.getMutatedBy()); line.append(DELIMITER); + line.append(planInheritanceRecord.getIterationCreated()); line.append(DELIMITER); + line.append(planInheritanceRecord.getIterationRemoved()); line.append(DELIMITER); + line.append(planInheritanceRecord.getIterationsSelected()); try { this.writer.write(line.toString()); diff --git a/matsim/src/test/java/org/matsim/core/replanning/planInheritance/PlanInheritanceTest.java b/matsim/src/test/java/org/matsim/core/replanning/planInheritance/PlanInheritanceTest.java new file mode 100644 index 00000000000..56f27301f11 --- /dev/null +++ b/matsim/src/test/java/org/matsim/core/replanning/planInheritance/PlanInheritanceTest.java @@ -0,0 +1,110 @@ +package org.matsim.core.replanning.planInheritance; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import org.junit.Rule; +import org.junit.Test; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.Scenario; +import org.matsim.api.core.v01.population.Person; +import org.matsim.core.config.Config; +import org.matsim.core.controler.Controler; +import org.matsim.core.population.io.StreamingPopulationReader; +import org.matsim.core.replanning.inheritance.PlanInheritanceModule; +import org.matsim.core.replanning.inheritance.PlanInheritanceRecord; +import org.matsim.core.replanning.inheritance.PlanInheritanceRecordReader; +import org.matsim.core.scenario.ScenarioUtils; +import org.matsim.testcases.MatsimTestUtils; + + + +public class PlanInheritanceTest { + /** + * @author alex94263 + */ + + @Rule + public MatsimTestUtils util = new MatsimTestUtils(); + + @Test + public void testPlanInheritanceEnabled() throws IOException { + String outputDirectory = util.getOutputDirectory(); + + Config config = this.util.loadConfig("test/scenarios/equil/config_plans1.xml"); + config.controler().setLastIteration(10); + config.controler().setOutputDirectory(outputDirectory); + config.planInheritance().setEnabled(true); + Controler c = new Controler(config); + + c.run(); + File csv = new File(outputDirectory, "planInheritanceRecords.csv.gz"); + + assertThat(csv).exists(); + + + final Scenario scenario = ScenarioUtils.createScenario(config); + StreamingPopulationReader streamingPopulationReader = new StreamingPopulationReader(scenario); + streamingPopulationReader.readFile(util.getOutputDirectory()+"output_plans.xml.gz"); + for(Person p : scenario.getPopulation().getPersons().values()) { + + assert(p.getAttributes().getAsMap().keySet().contains(PlanInheritanceModule.PLAN_ID)); + assert(p.getAttributes().getAsMap().keySet().contains(PlanInheritanceModule.PLAN_MUTATOR)); + assert(p.getAttributes().getAsMap().keySet().contains(PlanInheritanceModule.ITERATION_CREATED)); + } + + PlanInheritanceRecordReader reader = new PlanInheritanceRecordReader(outputDirectory+"planInheritanceRecords.csv.gz"); + List records = reader.read(); + assert(records.size()==2); + assert( ((PlanInheritanceRecord) records.get(0)).getAgentId().equals(Id.createPersonId("1"))); + assert( ((PlanInheritanceRecord) records.get(0)).getAncestorId().equals(Id.create("NONE",String.class))); + assert( ((PlanInheritanceRecord) records.get(0)).getMutatedBy().equals(PlanInheritanceModule.INITIAL_PLAN)); + assert( ((PlanInheritanceRecord) records.get(0)).getIterationCreated() == 0); + assert( ((PlanInheritanceRecord) records.get(0)).getIterationRemoved() == 0); + assert( ((PlanInheritanceRecord) records.get(0)).getPlanId().equals(Id.create("1",String.class))); + assert( ((PlanInheritanceRecord) records.get(0)).getIterationsSelected().equals(Arrays.asList(0, 1, 2, 3, 4, 6, 7, 8, 9, 10))); + + assert( ((PlanInheritanceRecord) records.get(1)).getAgentId().equals(Id.createPersonId("1"))); + assert( ((PlanInheritanceRecord) records.get(1)).getAncestorId().equals(Id.create("1",String.class))); + assert( ((PlanInheritanceRecord) records.get(1)).getMutatedBy().equals("RandomPlanSelector_ReRoute")); + assert( ((PlanInheritanceRecord) records.get(1)).getIterationCreated() == 5); + assert( ((PlanInheritanceRecord) records.get(1)).getIterationRemoved() == 0); + assert( ((PlanInheritanceRecord) records.get(1)).getPlanId().equals(Id.create("2",String.class))); + assert( ((PlanInheritanceRecord) records.get(1)).getIterationsSelected().equals(Arrays.asList(5))); + + + + } + + @Test + public void testPlanInheritanceDisabled() throws IOException { + String outputDirectory = util.getOutputDirectory(); + + Config config = this.util.loadConfig("test/scenarios/equil/config_plans1.xml"); + config.controler().setLastIteration(1); + config.controler().setOutputDirectory(outputDirectory); + Controler c = new Controler(config); + + c.run(); + + File csv = new File(outputDirectory, "planInheritanceRecords.csv.gz"); + + assertThat(csv).doesNotExist(); + + + final Scenario scenario = ScenarioUtils.createScenario(config); + StreamingPopulationReader streamingPopulationReader = new StreamingPopulationReader(scenario); + streamingPopulationReader.readFile(util.getOutputDirectory()+"output_plans.xml.gz"); + for(Person p : scenario.getPopulation().getPersons().values()) { + + assert(!p.getAttributes().getAsMap().keySet().contains(PlanInheritanceModule.PLAN_ID)); + assert(!p.getAttributes().getAsMap().keySet().contains(PlanInheritanceModule.PLAN_MUTATOR)); + assert(!p.getAttributes().getAsMap().keySet().contains(PlanInheritanceModule.ITERATION_CREATED)); + } + + + } +} From 78532cfc899b89d8a00d8237ca53bb3da37ea5d1 Mon Sep 17 00:00:00 2001 From: awagner Date: Thu, 12 Oct 2023 16:29:13 +0200 Subject: [PATCH 8/9] implmented Plan as identifiable --- .../dvrp/vrpagent/VrpAgentQueryHelper.java | 4 +- .../locationchoice/zzunused/LCPlan.java | 4 +- .../distributed/plans/PlanGenome.java | 4 +- .../population/PlanWithCachedJointPlan.java | 4 +- .../matsim/api/core/v01/population/Plan.java | 8 ++- .../org/matsim/core/population/PlanImpl.java | 16 ++++-- .../core/population/PopulationUtils.java | 6 +- .../replanning/GenericPlanStrategyImpl.java | 4 +- .../inheritance/PlanInheritanceModule.java | 30 +++++----- .../inheritance/PlanInheritanceRecord.java | 13 +++-- .../PlanInheritanceRecordReader.java | 5 +- .../planInheritance/PlanInheritanceTest.java | 57 ++++++++++++------- 12 files changed, 92 insertions(+), 63 deletions(-) diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/vrpagent/VrpAgentQueryHelper.java b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/vrpagent/VrpAgentQueryHelper.java index ddb8d2e6f08..68d6e327ed5 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/vrpagent/VrpAgentQueryHelper.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/dvrp/vrpagent/VrpAgentQueryHelper.java @@ -171,12 +171,12 @@ public void setIterationCreated(int iteration) { } @Override - public Id getPlanId() { + public Id getId() { throw new UnsupportedOperationException(); } @Override - public void setPlanId(Id planId) { + public void setPlanId(Id planId) { throw new UnsupportedOperationException(); } diff --git a/contribs/locationchoice/src/main/java/org/matsim/contrib/locationchoice/zzunused/LCPlan.java b/contribs/locationchoice/src/main/java/org/matsim/contrib/locationchoice/zzunused/LCPlan.java index f9a167cde9a..f1ba43fd0f5 100644 --- a/contribs/locationchoice/src/main/java/org/matsim/contrib/locationchoice/zzunused/LCPlan.java +++ b/contribs/locationchoice/src/main/java/org/matsim/contrib/locationchoice/zzunused/LCPlan.java @@ -286,13 +286,13 @@ else if (planElement instanceof Leg) { } @Override - public void setPlanId(Id planId) { + public void setPlanId(Id planId) { throw new UnsupportedOperationException(); } @Override - public Id getPlanId() { + public Id getId() { throw new UnsupportedOperationException(); } diff --git a/contribs/pseudosimulation/src/main/java/org/matsim/contrib/pseudosimulation/distributed/plans/PlanGenome.java b/contribs/pseudosimulation/src/main/java/org/matsim/contrib/pseudosimulation/distributed/plans/PlanGenome.java index 34f725fc92a..33ee42fbc42 100644 --- a/contribs/pseudosimulation/src/main/java/org/matsim/contrib/pseudosimulation/distributed/plans/PlanGenome.java +++ b/contribs/pseudosimulation/src/main/java/org/matsim/contrib/pseudosimulation/distributed/plans/PlanGenome.java @@ -221,10 +221,10 @@ public void setType(final String type) { } @Override - public Id getPlanId() { return null; } + public Id getId() { return null; } @Override - public void setPlanId(Id planId) { /* nothing to do here */ } + public void setPlanId(Id planId) { /* nothing to do here */ } @Override public int getIterationCreated() { return -1; } diff --git a/contribs/socnetsim/src/main/java/org/matsim/contrib/socnetsim/framework/population/PlanWithCachedJointPlan.java b/contribs/socnetsim/src/main/java/org/matsim/contrib/socnetsim/framework/population/PlanWithCachedJointPlan.java index ce912ec1682..5d5990a7237 100644 --- a/contribs/socnetsim/src/main/java/org/matsim/contrib/socnetsim/framework/population/PlanWithCachedJointPlan.java +++ b/contribs/socnetsim/src/main/java/org/matsim/contrib/socnetsim/framework/population/PlanWithCachedJointPlan.java @@ -175,10 +175,10 @@ public void setType(String type) { } @Override - public Id getPlanId() { return null; } + public Id getId() { return null; } @Override - public void setPlanId(Id planId) { /* nothing to do here */ } + public void setPlanId(Id planId) { /* nothing to do here */ } @Override public int getIterationCreated() { return -1; } diff --git a/matsim/src/main/java/org/matsim/api/core/v01/population/Plan.java b/matsim/src/main/java/org/matsim/api/core/v01/population/Plan.java index 85e7775e9b9..6329b62a626 100644 --- a/matsim/src/main/java/org/matsim/api/core/v01/population/Plan.java +++ b/matsim/src/main/java/org/matsim/api/core/v01/population/Plan.java @@ -24,6 +24,7 @@ import org.matsim.api.core.v01.Customizable; import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.Identifiable; import org.matsim.core.api.internal.MatsimPopulationObject; import org.matsim.utils.objectattributes.attributable.Attributable; @@ -35,7 +36,7 @@ * The only thing which is not "expected" in the same sense is the score. * */ -public interface Plan extends MatsimPopulationObject, Customizable, BasicPlan, Attributable { +public interface Plan extends MatsimPopulationObject, Customizable, BasicPlan, Attributable, Identifiable { public abstract List getPlanElements(); @@ -51,9 +52,9 @@ public interface Plan extends MatsimPopulationObject, Customizable, BasicPlan, A public abstract void setType(final String type); - public abstract void setPlanId(final Id planId); + public abstract void setPlanId(Id planId); - public abstract Id getPlanId(); + public abstract Id getId(); public abstract int getIterationCreated(); @@ -72,5 +73,6 @@ public interface Plan extends MatsimPopulationObject, Customizable, BasicPlan, A * you are using this method!. */ public abstract void setPerson(Person person); + } diff --git a/matsim/src/main/java/org/matsim/core/population/PlanImpl.java b/matsim/src/main/java/org/matsim/core/population/PlanImpl.java index 4d7f0fd0363..5a928e62ba0 100644 --- a/matsim/src/main/java/org/matsim/core/population/PlanImpl.java +++ b/matsim/src/main/java/org/matsim/core/population/PlanImpl.java @@ -28,6 +28,7 @@ import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.Customizable; import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.population.Activity; import org.matsim.api.core.v01.population.Leg; import org.matsim.api.core.v01.population.Person; @@ -40,6 +41,8 @@ /* deliberately package */ final class PlanImpl implements Plan { + private Id id= null; + private ArrayList actsLegs = new ArrayList<>(); private Double score = null; @@ -125,13 +128,16 @@ public void setType(final String type) { } @Override - public Id getPlanId() { - return (Id) this.getAttributes().getAttribute(PlanInheritanceModule.PLAN_ID); + public Id getId() { + if(this.id!=null) + return this.id; + else return Id.create(this.getAttributes().getAttribute(PlanInheritanceModule.PLAN_ID).toString(),Plan.class); } @Override - public void setPlanId(Id planId) { - this.getAttributes().putAttribute(PlanInheritanceModule.PLAN_ID, planId); + public void setPlanId(Id planId) { + this.getAttributes().putAttribute(PlanInheritanceModule.PLAN_ID, planId.toString()); + this.id = planId; } @Override @@ -196,6 +202,8 @@ public final Map getCustomAttributes() { return this.customizableDelegate.getCustomAttributes(); } + + // public final void setLocked() { // for ( PlanElement pe : this.actsLegs ) { // if ( pe instanceof ActivityImpl ) { diff --git a/matsim/src/main/java/org/matsim/core/population/PopulationUtils.java b/matsim/src/main/java/org/matsim/core/population/PopulationUtils.java index adac6f947a2..49ea0197e73 100644 --- a/matsim/src/main/java/org/matsim/core/population/PopulationUtils.java +++ b/matsim/src/main/java/org/matsim/core/population/PopulationUtils.java @@ -383,12 +383,12 @@ public void setType(String type) { } @Override - public Id getPlanId() { - return this.delegate.getPlanId(); + public Id getId() { + return this.delegate.getId(); } @Override - public void setPlanId(Id planId) { + public void setPlanId(Id planId) { throw new UnsupportedOperationException(); } diff --git a/matsim/src/main/java/org/matsim/core/replanning/GenericPlanStrategyImpl.java b/matsim/src/main/java/org/matsim/core/replanning/GenericPlanStrategyImpl.java index 75daefffb28..b9063b0878d 100644 --- a/matsim/src/main/java/org/matsim/core/replanning/GenericPlanStrategyImpl.java +++ b/matsim/src/main/java/org/matsim/core/replanning/GenericPlanStrategyImpl.java @@ -93,8 +93,8 @@ public void run(final HasPlansAndId person) { // set the working plan to a copy of the selected plan: plan = person.createCopyOfSelectedPlanAndMakeSelected(); - //planId is only set inside planInheritance -> if null planInheritance is disabled - if (plan instanceof Plan && ((Plan) plan).getPlanId() != null) { + //Id is only set inside planInheritance -> if null planInheritance is disabled + if (plan instanceof Plan && ((Plan) plan).getId() != null) { // add plan inheritance flags ((Plan) plan).setIterationCreated(this.replanningContext.getIteration()); ((Plan) plan).setPlanMutator(this.toString()); diff --git a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java index 80ef946b263..5ee3f3775ac 100644 --- a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java +++ b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java @@ -37,7 +37,6 @@ import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Plan; import org.matsim.core.config.groups.ControlerConfigGroup.CompressionType; -import org.matsim.core.config.groups.PlanInheritanceConfigGroup; import org.matsim.core.config.groups.StrategyConfigGroup.StrategySettings; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.events.BeforeMobsimEvent; @@ -49,7 +48,6 @@ import org.matsim.core.population.PersonUtils; import org.matsim.core.replanning.GenericPlanStrategy; import org.matsim.core.replanning.StrategyManager; -import org.matsim.core.replanning.annealing.ReplanningAnnealerConfigGroup; import org.matsim.core.utils.io.IOUtils; import com.google.inject.Singleton; @@ -75,7 +73,7 @@ public class PlanInheritanceModule extends AbstractModule implements StartupList public static final String FILENAME_PLAN_INHERITANCE_RECORDS = "planInheritanceRecords"; long numberOfPlanInheritanceRecordsCreated = 0; - Map, PlanInheritanceRecord> planId2planInheritanceRecords = new ConcurrentHashMap<>(); + Map, PlanInheritanceRecord> planId2planInheritanceRecords = new ConcurrentHashMap<>(); PlanInheritanceRecordWriter planInheritanceRecordWriter; private ArrayList strategies; @@ -96,7 +94,7 @@ public void notifyStartup(StartupEvent event) { // reset all plan attributes that might be present from a previously performed matsim run for (Person person : event.getServices().getScenario().getPopulation().getPersons().values()) { for (Plan plan : person.getPlans()) { - plan.setPlanId(Id.create(NONE, String.class)); + plan.setPlanId(Id.create(NONE, Plan.class)); plan.setPlanMutator(INITIAL_PLAN); plan.setIterationCreated(0); } @@ -157,8 +155,8 @@ private BufferedWriter initializeDistributionWriter(ArrayList strategies public void notifyBeforeMobsim(BeforeMobsimEvent event) { // check the plans of the population and all currently stored plan records - do the actual book-keeping - Set> activePlanIds = new HashSet<>(); - Set> selectedPlanIds = new HashSet<>(); + Set> activePlanIds = new HashSet<>(); + Set> selectedPlanIds = new HashSet<>(); for (Person person : event.getServices().getScenario().getPopulation().getPersons().values()) { for (Plan plan : person.getPlans()) { @@ -174,8 +172,8 @@ public void notifyBeforeMobsim(BeforeMobsimEvent event) { PlanInheritanceRecord planInheritanceRecord = new PlanInheritanceRecord(); planInheritanceRecord.setAgentId(person.getId()); - planInheritanceRecord.setPlanId( Id.create(Long.toString(++this.numberOfPlanInheritanceRecordsCreated, 36), String.class) ); - planInheritanceRecord.setAncestorId(plan.getPlanId()); + planInheritanceRecord.setPlanId(Id.create(Long.toString(++this.numberOfPlanInheritanceRecordsCreated, 36), Plan.class)); + planInheritanceRecord.setAncestorId(plan.getId()); //works because new plan is copy of old selected and attributes are copied -> thus current attribute plan id is old selected plan id plan.setPlanId(planInheritanceRecord.getPlanId()); planInheritanceRecord.setIterationCreated(plan.getIterationCreated()); planInheritanceRecord.setMutatedBy(plan.getPlanMutator()); @@ -184,22 +182,22 @@ public void notifyBeforeMobsim(BeforeMobsimEvent event) { } if (PersonUtils.isSelected(plan)) { - this.planId2planInheritanceRecords.get(plan.getPlanId()).getIterationsSelected().add(event.getIteration()); - selectedPlanIds.add(plan.getPlanId()); + this.planId2planInheritanceRecords.get(plan.getId()).getIterationsSelected().add(event.getIteration()); + selectedPlanIds.add(plan.getId()); } - activePlanIds.add(plan.getPlanId()); + activePlanIds.add(plan.getId()); } } - List> deletedPlans = new ArrayList<>(); - for (Id planId : this.planId2planInheritanceRecords.keySet()) { + List> deletedPlans = new ArrayList<>(); + for (Id planId : this.planId2planInheritanceRecords.keySet()) { if (!activePlanIds.contains(planId)) { deletedPlans.add(planId); } } - for (Id deletedPlanId : deletedPlans) { + for (Id deletedPlanId : deletedPlans) { PlanInheritanceRecord deletedPlanInheritanceRecord = this.planId2planInheritanceRecords.remove(deletedPlanId); deletedPlanInheritanceRecord.setIterationRemoved(event.getIteration()); this.planInheritanceRecordWriter.write(deletedPlanInheritanceRecord); @@ -214,12 +212,12 @@ public void notifyBeforeMobsim(BeforeMobsimEvent event) { /** * Updates the default plan stats - namely the distribution of plan mutators based on the given plan ids. */ - private void calculateAndWriteDistribution(int currentIteration, ArrayList strategies, Map, PlanInheritanceRecord> planId2planInheritanceRecords, Set> planIds, BufferedWriter writer) { + private void calculateAndWriteDistribution(int currentIteration, ArrayList strategies, Map, PlanInheritanceRecord> planId2planInheritanceRecords, Set> planIds, BufferedWriter writer) { Map strategy2count = new HashMap<>(); for (String strategyName : strategies) { strategy2count.put(strategyName, new AtomicLong(0)); } - for (Id planId : planIds) { + for (Id planId : planIds) { String mutatedBy = planId2planInheritanceRecords.get(planId).getMutatedBy(); strategy2count.get(mutatedBy).incrementAndGet(); } diff --git a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecord.java b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecord.java index 8a3e54280ac..759e0a16961 100644 --- a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecord.java +++ b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecord.java @@ -25,6 +25,7 @@ import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.Plan; /** * Data container storing the data of a single plan. @@ -41,12 +42,12 @@ public class PlanInheritanceRecord { /** * The globally unique plan id. */ - private Id planId; + private Id planId; /** * Id of the plan that this plan had been copied from before mutating. */ - private Id ancestorId; + private Id ancestorId; /** * The name of the strategy that altered this plan. @@ -69,19 +70,19 @@ public class PlanInheritanceRecord { */ private List iterationsSelected = new ArrayList<>(1); - public Id getPlanId() { + public Id getPlanId() { return planId; } - public void setPlanId(Id planId) { + public void setPlanId(Id planId) { this.planId = planId; } - public Id getAncestorId() { + public Id getAncestorId() { return ancestorId; } - public void setAncestorId(Id ancestorId) { + public void setAncestorId(Id ancestorId) { this.ancestorId = ancestorId; } diff --git a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecordReader.java b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecordReader.java index a6b90fbd44e..8d83d6ef1de 100644 --- a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecordReader.java +++ b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecordReader.java @@ -33,6 +33,7 @@ import java.util.stream.Collectors; import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.population.Plan; import org.matsim.core.utils.io.IOUtils; /** @@ -69,8 +70,8 @@ public List read() { String[] line = lineString.split(DELIMITER); PlanInheritanceRecord planInheritanceRecord = new PlanInheritanceRecord(); planInheritanceRecord.setAgentId(Id.createPersonId(line[lookUp.get(PlanInheritanceRecordWriter.AGENT_ID)])); - planInheritanceRecord.setPlanId(Id.create(line[lookUp.get(PlanInheritanceRecordWriter.PLAN_ID)], String.class)); - planInheritanceRecord.setAncestorId(Id.create(line[lookUp.get(PlanInheritanceRecordWriter.ANCESTOR_ID)], String.class)); + planInheritanceRecord.setPlanId(Id.create(line[lookUp.get(PlanInheritanceRecordWriter.PLAN_ID)], Plan.class)); + planInheritanceRecord.setAncestorId(Id.create(line[lookUp.get(PlanInheritanceRecordWriter.ANCESTOR_ID)], Plan.class)); planInheritanceRecord.setMutatedBy(line[lookUp.get(PlanInheritanceRecordWriter.MUTATED_BY)]); planInheritanceRecord.setIterationCreated(Integer.parseInt(line[lookUp.get(PlanInheritanceRecordWriter.ITERATION_CREATED)])); planInheritanceRecord.setIterationRemoved(Integer.parseInt(line[lookUp.get(PlanInheritanceRecordWriter.ITERATION_REMOVED)])); diff --git a/matsim/src/test/java/org/matsim/core/replanning/planInheritance/PlanInheritanceTest.java b/matsim/src/test/java/org/matsim/core/replanning/planInheritance/PlanInheritanceTest.java index 56f27301f11..df351fddc3c 100644 --- a/matsim/src/test/java/org/matsim/core/replanning/planInheritance/PlanInheritanceTest.java +++ b/matsim/src/test/java/org/matsim/core/replanning/planInheritance/PlanInheritanceTest.java @@ -4,6 +4,7 @@ import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.junit.Rule; @@ -11,8 +12,10 @@ import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.population.Person; +import org.matsim.api.core.v01.population.Plan; import org.matsim.core.config.Config; import org.matsim.core.controler.Controler; +import org.matsim.core.population.algorithms.PersonAlgorithm; import org.matsim.core.population.io.StreamingPopulationReader; import org.matsim.core.replanning.inheritance.PlanInheritanceModule; import org.matsim.core.replanning.inheritance.PlanInheritanceRecord; @@ -27,6 +30,7 @@ public class PlanInheritanceTest { * @author alex94263 */ + @Rule public MatsimTestUtils util = new MatsimTestUtils(); @@ -46,33 +50,42 @@ public void testPlanInheritanceEnabled() throws IOException { assertThat(csv).exists(); + List personList = new ArrayList(); final Scenario scenario = ScenarioUtils.createScenario(config); - StreamingPopulationReader streamingPopulationReader = new StreamingPopulationReader(scenario); - streamingPopulationReader.readFile(util.getOutputDirectory()+"output_plans.xml.gz"); - for(Person p : scenario.getPopulation().getPersons().values()) { + StreamingPopulationReader spr = new StreamingPopulationReader(scenario); + spr.addAlgorithm(new PersonAlgorithm() { + @Override + public void run(Person person) { + personList.add(person); + } + }); + spr.readFile(util.getOutputDirectory()+"output_plans.xml.gz"); + for(Person per : personList) { + for(Plan p : per.getPlans()) { + assert(p.getAttributes().getAsMap().keySet().contains(PlanInheritanceModule.PLAN_MUTATOR)); + assert(p.getAttributes().getAsMap().keySet().contains(PlanInheritanceModule.ITERATION_CREATED)); + assert(p.getAttributes().getAsMap().keySet().contains(PlanInheritanceModule.PLAN_ID)); + } - assert(p.getAttributes().getAsMap().keySet().contains(PlanInheritanceModule.PLAN_ID)); - assert(p.getAttributes().getAsMap().keySet().contains(PlanInheritanceModule.PLAN_MUTATOR)); - assert(p.getAttributes().getAsMap().keySet().contains(PlanInheritanceModule.ITERATION_CREATED)); } PlanInheritanceRecordReader reader = new PlanInheritanceRecordReader(outputDirectory+"planInheritanceRecords.csv.gz"); List records = reader.read(); assert(records.size()==2); assert( ((PlanInheritanceRecord) records.get(0)).getAgentId().equals(Id.createPersonId("1"))); - assert( ((PlanInheritanceRecord) records.get(0)).getAncestorId().equals(Id.create("NONE",String.class))); + assert( ((PlanInheritanceRecord) records.get(0)).getAncestorId().equals(Id.create("NONE",Plan.class))); assert( ((PlanInheritanceRecord) records.get(0)).getMutatedBy().equals(PlanInheritanceModule.INITIAL_PLAN)); assert( ((PlanInheritanceRecord) records.get(0)).getIterationCreated() == 0); assert( ((PlanInheritanceRecord) records.get(0)).getIterationRemoved() == 0); - assert( ((PlanInheritanceRecord) records.get(0)).getPlanId().equals(Id.create("1",String.class))); + assert( ((PlanInheritanceRecord) records.get(0)).getPlanId().equals(Id.create("1",Plan.class))); assert( ((PlanInheritanceRecord) records.get(0)).getIterationsSelected().equals(Arrays.asList(0, 1, 2, 3, 4, 6, 7, 8, 9, 10))); assert( ((PlanInheritanceRecord) records.get(1)).getAgentId().equals(Id.createPersonId("1"))); - assert( ((PlanInheritanceRecord) records.get(1)).getAncestorId().equals(Id.create("1",String.class))); + assert( ((PlanInheritanceRecord) records.get(1)).getAncestorId().equals(Id.create("1",Plan.class))); assert( ((PlanInheritanceRecord) records.get(1)).getMutatedBy().equals("RandomPlanSelector_ReRoute")); assert( ((PlanInheritanceRecord) records.get(1)).getIterationCreated() == 5); assert( ((PlanInheritanceRecord) records.get(1)).getIterationRemoved() == 0); - assert( ((PlanInheritanceRecord) records.get(1)).getPlanId().equals(Id.create("2",String.class))); + assert( ((PlanInheritanceRecord) records.get(1)).getPlanId().equals(Id.create("2",Plan.class))); assert( ((PlanInheritanceRecord) records.get(1)).getIterationsSelected().equals(Arrays.asList(5))); @@ -94,17 +107,23 @@ public void testPlanInheritanceDisabled() throws IOException { assertThat(csv).doesNotExist(); - + List personList = new ArrayList(); final Scenario scenario = ScenarioUtils.createScenario(config); - StreamingPopulationReader streamingPopulationReader = new StreamingPopulationReader(scenario); - streamingPopulationReader.readFile(util.getOutputDirectory()+"output_plans.xml.gz"); - for(Person p : scenario.getPopulation().getPersons().values()) { + StreamingPopulationReader spr = new StreamingPopulationReader(scenario); + spr.addAlgorithm(new PersonAlgorithm() { + @Override + public void run(Person person) { + personList.add(person); + } + }); + spr.readFile(util.getOutputDirectory()+"output_plans.xml.gz"); + for(Person per : personList) { + for(Plan p : per.getPlans()) { + assert(!p.getAttributes().getAsMap().keySet().contains(PlanInheritanceModule.PLAN_MUTATOR)); + assert(!p.getAttributes().getAsMap().keySet().contains(PlanInheritanceModule.ITERATION_CREATED)); + assert(!p.getAttributes().getAsMap().keySet().contains(PlanInheritanceModule.PLAN_ID)); + } - assert(!p.getAttributes().getAsMap().keySet().contains(PlanInheritanceModule.PLAN_ID)); - assert(!p.getAttributes().getAsMap().keySet().contains(PlanInheritanceModule.PLAN_MUTATOR)); - assert(!p.getAttributes().getAsMap().keySet().contains(PlanInheritanceModule.ITERATION_CREATED)); } - - } } From bae280b5f2ddacf22865d6bc2a9cbda9e79eb14c Mon Sep 17 00:00:00 2001 From: awagner Date: Fri, 13 Oct 2023 13:54:55 +0200 Subject: [PATCH 9/9] refactor Config Renames, default Iteration removed changed to -1 --- .../src/main/java/org/matsim/core/config/Config.java | 1 + .../java/org/matsim/core/population/PlanImpl.java | 7 ++++++- .../inheritance/PlanInheritanceModule.java | 8 ++++---- .../inheritance/PlanInheritanceRecord.java | 2 +- .../planInheritance/PlanInheritanceTest.java | 12 ++++++------ 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/matsim/src/main/java/org/matsim/core/config/Config.java b/matsim/src/main/java/org/matsim/core/config/Config.java index a409e64d579..e6ee24c19be 100644 --- a/matsim/src/main/java/org/matsim/core/config/Config.java +++ b/matsim/src/main/java/org/matsim/core/config/Config.java @@ -45,6 +45,7 @@ import org.matsim.core.config.groups.HouseholdsConfigGroup; import org.matsim.core.config.groups.LinkStatsConfigGroup; import org.matsim.core.config.groups.NetworkConfigGroup; +import org.matsim.core.config.groups.PlanInheritanceConfigGroup; import org.matsim.core.config.groups.ReplanningConfigGroup; import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.config.groups.RoutingConfigGroup;import org.matsim.core.config.groups.PlansConfigGroup; diff --git a/matsim/src/main/java/org/matsim/core/population/PlanImpl.java b/matsim/src/main/java/org/matsim/core/population/PlanImpl.java index 5a928e62ba0..8477a25b7dc 100644 --- a/matsim/src/main/java/org/matsim/core/population/PlanImpl.java +++ b/matsim/src/main/java/org/matsim/core/population/PlanImpl.java @@ -131,7 +131,12 @@ public void setType(final String type) { public Id getId() { if(this.id!=null) return this.id; - else return Id.create(this.getAttributes().getAttribute(PlanInheritanceModule.PLAN_ID).toString(),Plan.class); + else { + if(this.getAttributes().getAttribute(PlanInheritanceModule.PLAN_ID)!=null) + return Id.create(this.getAttributes().getAttribute(PlanInheritanceModule.PLAN_ID).toString(),Plan.class); + else return null; + } + } @Override diff --git a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java index 5ee3f3775ac..0a0a48f961d 100644 --- a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java +++ b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceModule.java @@ -36,8 +36,8 @@ import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Plan; -import org.matsim.core.config.groups.ControlerConfigGroup.CompressionType; -import org.matsim.core.config.groups.StrategyConfigGroup.StrategySettings; +import org.matsim.core.config.groups.ControllerConfigGroup.CompressionType; +import org.matsim.core.config.groups.ReplanningConfigGroup.StrategySettings; import org.matsim.core.controler.AbstractModule; import org.matsim.core.controler.events.BeforeMobsimEvent; import org.matsim.core.controler.events.ShutdownEvent; @@ -85,9 +85,9 @@ public class PlanInheritanceModule extends AbstractModule implements StartupList @Override public void notifyStartup(StartupEvent event) { // initialize all default writers - CompressionType compressionType = event.getServices().getConfig().controler().getCompressionType(); + CompressionType compressionType = event.getServices().getConfig().controller().getCompressionType(); this.planInheritanceRecordWriter = new PlanInheritanceRecordWriter(event.getServices().getControlerIO().getOutputFilename(FILENAME_PLAN_INHERITANCE_RECORDS + ".csv", compressionType)); - this.strategies = this.getActiveStrategies(event.getServices().getConfig().strategy().getStrategySettings(), event.getServices().getStrategyManager()); + this.strategies = this.getActiveStrategies(event.getServices().getConfig().replanning().getStrategySettings(), event.getServices().getStrategyManager()); this.selectedPlanStrategyShareWriter = this.initializeDistributionWriter(this.strategies, event.getServices().getControlerIO().getOutputFilename(FILENAME_PLAN_INHERITANCE_RECORDS + "_shares_selected.csv")); this.planStrategyShareWriter = this.initializeDistributionWriter(this.strategies, event.getServices().getControlerIO().getOutputFilename(FILENAME_PLAN_INHERITANCE_RECORDS + "_shares.csv")); diff --git a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecord.java b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecord.java index 759e0a16961..7212f337896 100644 --- a/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecord.java +++ b/matsim/src/main/java/org/matsim/core/replanning/inheritance/PlanInheritanceRecord.java @@ -62,7 +62,7 @@ public class PlanInheritanceRecord { /** * Iteration in which the plan had been removed from the choice-set. */ - private int iterationRemoved; + private int iterationRemoved = -1; /** * Collection of iterations this plan had been the selected plan. diff --git a/matsim/src/test/java/org/matsim/core/replanning/planInheritance/PlanInheritanceTest.java b/matsim/src/test/java/org/matsim/core/replanning/planInheritance/PlanInheritanceTest.java index df351fddc3c..c15436d3391 100644 --- a/matsim/src/test/java/org/matsim/core/replanning/planInheritance/PlanInheritanceTest.java +++ b/matsim/src/test/java/org/matsim/core/replanning/planInheritance/PlanInheritanceTest.java @@ -39,8 +39,8 @@ public void testPlanInheritanceEnabled() throws IOException { String outputDirectory = util.getOutputDirectory(); Config config = this.util.loadConfig("test/scenarios/equil/config_plans1.xml"); - config.controler().setLastIteration(10); - config.controler().setOutputDirectory(outputDirectory); + config.controller().setLastIteration(10); + config.controller().setOutputDirectory(outputDirectory); config.planInheritance().setEnabled(true); Controler c = new Controler(config); @@ -76,7 +76,7 @@ public void run(Person person) { assert( ((PlanInheritanceRecord) records.get(0)).getAncestorId().equals(Id.create("NONE",Plan.class))); assert( ((PlanInheritanceRecord) records.get(0)).getMutatedBy().equals(PlanInheritanceModule.INITIAL_PLAN)); assert( ((PlanInheritanceRecord) records.get(0)).getIterationCreated() == 0); - assert( ((PlanInheritanceRecord) records.get(0)).getIterationRemoved() == 0); + assert( ((PlanInheritanceRecord) records.get(0)).getIterationRemoved() == -1); assert( ((PlanInheritanceRecord) records.get(0)).getPlanId().equals(Id.create("1",Plan.class))); assert( ((PlanInheritanceRecord) records.get(0)).getIterationsSelected().equals(Arrays.asList(0, 1, 2, 3, 4, 6, 7, 8, 9, 10))); @@ -84,7 +84,7 @@ public void run(Person person) { assert( ((PlanInheritanceRecord) records.get(1)).getAncestorId().equals(Id.create("1",Plan.class))); assert( ((PlanInheritanceRecord) records.get(1)).getMutatedBy().equals("RandomPlanSelector_ReRoute")); assert( ((PlanInheritanceRecord) records.get(1)).getIterationCreated() == 5); - assert( ((PlanInheritanceRecord) records.get(1)).getIterationRemoved() == 0); + assert( ((PlanInheritanceRecord) records.get(1)).getIterationRemoved() == -1); assert( ((PlanInheritanceRecord) records.get(1)).getPlanId().equals(Id.create("2",Plan.class))); assert( ((PlanInheritanceRecord) records.get(1)).getIterationsSelected().equals(Arrays.asList(5))); @@ -97,8 +97,8 @@ public void testPlanInheritanceDisabled() throws IOException { String outputDirectory = util.getOutputDirectory(); Config config = this.util.loadConfig("test/scenarios/equil/config_plans1.xml"); - config.controler().setLastIteration(1); - config.controler().setOutputDirectory(outputDirectory); + config.controller().setLastIteration(1); + config.controller().setOutputDirectory(outputDirectory); Controler c = new Controler(config); c.run();