MATSIM
PlanInheritanceModule.java
Go to the documentation of this file.
1 package org.matsim.core.replanning.inheritance;
2 
3 /* *********************************************************************** *
4  * project: org.matsim.*
5  * ParallelPopulationReaderMatsimV6.java
6  * *
7  * *********************************************************************** *
8  * *
9  * copyright : (C) 2023 by the members listed in the COPYING, *
10  * LICENSE and WARRANTY file. *
11  * email : info at matsim dot org *
12  * *
13  * *********************************************************************** *
14  * *
15  * This program is free software; you can redistribute it and/or modify *
16  * it under the terms of the GNU General Public License as published by *
17  * the Free Software Foundation; either version 2 of the License, or *
18  * (at your option) any later version. *
19  * See also COPYING, LICENSE and WARRANTY file *
20  * *
21  * *********************************************************************** */
22 
23 import java.io.BufferedWriter;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.HashSet;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Set;
33 import java.util.concurrent.ConcurrentHashMap;
34 import java.util.concurrent.atomic.AtomicLong;
35 
36 import org.matsim.api.core.v01.Id;
51 import org.matsim.core.utils.io.IOUtils;
52 
53 import com.google.inject.Singleton;
54 
63 @Singleton
65 
66  public static final String PLAN_ID = "planId";
67  public static final String ITERATION_CREATED = "iterationCreated";
68  public static final String PLAN_MUTATOR = "planMutator";
69 
70  public static final String INITIAL_PLAN = "initialPlan";
71  public static final String NONE = "NONE";
72 
73  public static final String FILENAME_PLAN_INHERITANCE_RECORDS = "planInheritanceRecords";
74 
75  long numberOfPlanInheritanceRecordsCreated = 0;
76  Map<Id<Plan>, PlanInheritanceRecord> planId2planInheritanceRecords = new ConcurrentHashMap<>();
77 
78  PlanInheritanceRecordWriter planInheritanceRecordWriter;
79  private ArrayList<String> strategies;
80 
81  private final Character DELIMITER = '\t';
82  private BufferedWriter selectedPlanStrategyShareWriter;
83  private BufferedWriter planStrategyShareWriter;
84 
85  @Override
86  public void notifyStartup(StartupEvent event) {
87  // initialize all default writers
88  CompressionType compressionType = event.getServices().getConfig().controller().getCompressionType();
89  this.planInheritanceRecordWriter = new PlanInheritanceRecordWriter(event.getServices().getControlerIO().getOutputFilename(FILENAME_PLAN_INHERITANCE_RECORDS + ".csv", compressionType));
90  this.strategies = this.getActiveStrategies(event.getServices().getConfig().replanning().getStrategySettings(), event.getServices().getStrategyManager());
91  this.selectedPlanStrategyShareWriter = this.initializeDistributionWriter(this.strategies, event.getServices().getControlerIO().getOutputFilename(FILENAME_PLAN_INHERITANCE_RECORDS + "_shares_selected.csv"));
92  this.planStrategyShareWriter = this.initializeDistributionWriter(this.strategies, event.getServices().getControlerIO().getOutputFilename(FILENAME_PLAN_INHERITANCE_RECORDS + "_shares.csv"));
93 
94  // reset all plan attributes that might be present from a previously performed matsim run
95  for (Person person : event.getServices().getScenario().getPopulation().getPersons().values()) {
96  for (Plan plan : person.getPlans()) {
97  plan.setPlanId(Id.create(NONE, Plan.class));
98  plan.setPlanMutator(INITIAL_PLAN);
99  plan.setIterationCreated(0);
100  }
101  }
102  }
103 
107  private ArrayList<String> getActiveStrategies(Collection<StrategySettings> strategySettings, StrategyManager strategyManager) {
108  Set<String> activeSubpopulations = new HashSet<>();
109  for (StrategySettings strategySetting : strategySettings) {
110  activeSubpopulations.add(strategySetting.getSubpopulation());
111  }
112 
113  Set<String> planStrategiesNames = new HashSet<>();
114  for (String subpopulation : activeSubpopulations) {
115  for (GenericPlanStrategy<Plan, Person> planStrategy : strategyManager.getStrategies(subpopulation)) {
116  planStrategiesNames.add(planStrategy.toString());
117  }
118  }
119 
120  ArrayList<String> strategies = new ArrayList<>(planStrategiesNames.size() + 1);
121  strategies.addAll(planStrategiesNames);
122  Collections.sort(strategies);
123  strategies.add(0, INITIAL_PLAN);
124 
125  return strategies;
126  }
127 
131  private BufferedWriter initializeDistributionWriter(ArrayList<String> strategies, String filename) {
132 
133  BufferedWriter planStrategyShareWriter = IOUtils.getBufferedWriter(filename);
134 
135  StringBuffer header = new StringBuffer();
136  header.append("iteration"); header.append(DELIMITER);
137  for (int i = 0; i < strategies.size(); i++) {
138  if (i > 0) {
139  header.append(DELIMITER);
140  }
141  header.append(strategies.get(i));
142  }
143 
144  try {
145  planStrategyShareWriter.write(header.toString());
146  planStrategyShareWriter.newLine();
147  } catch (IOException e) {
148  throw new RuntimeException("Could not initialize the plan strategy share writer!", e);
149  }
150 
152  }
153 
154  @Override
156  // check the plans of the population and all currently stored plan records - do the actual book-keeping
157 
158  Set<Id<Plan>> activePlanIds = new HashSet<>();
159  Set<Id<Plan>> selectedPlanIds = new HashSet<>();
160 
161  for (Person person : event.getServices().getScenario().getPopulation().getPersons().values()) {
162  for (Plan plan : person.getPlans()) {
163 
164  if (plan.getPlanMutator() == null) {
165  // initial plan - set initial plan defaults
166  plan.setPlanMutator(INITIAL_PLAN);
167  plan.setIterationCreated(event.getIteration());
168  }
169 
170  if (plan.getIterationCreated() == event.getIteration()) {
171  // it's a new plan created in this iteration - create a new record
172 
173  PlanInheritanceRecord planInheritanceRecord = new PlanInheritanceRecord();
174  planInheritanceRecord.setAgentId(person.getId());
175  planInheritanceRecord.setPlanId(Id.create(Long.toString(++this.numberOfPlanInheritanceRecordsCreated, 36), Plan.class));
176  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
177  plan.setPlanId(planInheritanceRecord.getPlanId());
178  planInheritanceRecord.setIterationCreated(plan.getIterationCreated());
179  planInheritanceRecord.setMutatedBy(plan.getPlanMutator());
180 
181  this.planId2planInheritanceRecords.put(planInheritanceRecord.getPlanId(), planInheritanceRecord);
182  }
183 
184  if (PersonUtils.isSelected(plan)) {
185  this.planId2planInheritanceRecords.get(plan.getId()).getIterationsSelected().add(event.getIteration());
186  selectedPlanIds.add(plan.getId());
187  }
188 
189  activePlanIds.add(plan.getId());
190  }
191  }
192 
193  List<Id<Plan>> deletedPlans = new ArrayList<>();
194  for (Id<Plan> planId : this.planId2planInheritanceRecords.keySet()) {
195  if (!activePlanIds.contains(planId)) {
196  deletedPlans.add(planId);
197  }
198  }
199 
200  for (Id<Plan> deletedPlanId : deletedPlans) {
201  PlanInheritanceRecord deletedPlanInheritanceRecord = this.planId2planInheritanceRecords.remove(deletedPlanId);
202  deletedPlanInheritanceRecord.setIterationRemoved(event.getIteration());
203  this.planInheritanceRecordWriter.write(deletedPlanInheritanceRecord);
204  }
205 
206  this.planInheritanceRecordWriter.flush();
207 
208  this.calculateAndWriteDistribution(event.getIteration(), this.strategies, this.planId2planInheritanceRecords, selectedPlanIds, this.selectedPlanStrategyShareWriter);
209  this.calculateAndWriteDistribution(event.getIteration(), this.strategies, this.planId2planInheritanceRecords, this.planId2planInheritanceRecords.keySet(), this.planStrategyShareWriter);
210  }
211 
215  private void calculateAndWriteDistribution(int currentIteration, ArrayList<String> strategies, Map<Id<Plan>, PlanInheritanceRecord> planId2planInheritanceRecords, Set<Id<Plan>> planIds, BufferedWriter writer) {
216  Map<String, AtomicLong> strategy2count = new HashMap<>();
217  for (String strategyName : strategies) {
218  strategy2count.put(strategyName, new AtomicLong(0));
219  }
220  for (Id<Plan> planId : planIds) {
221  String mutatedBy = planId2planInheritanceRecords.get(planId).getMutatedBy();
222  strategy2count.get(mutatedBy).incrementAndGet();
223  }
224  long sum = strategy2count.values().stream().mapToLong(count -> count.get()).sum();
225  StringBuffer line = new StringBuffer();
226  line.append(currentIteration);
227  line.append(DELIMITER);
228  for (int i = 0; i < strategies.size(); i++) {
229  if (i > 0) {
230  line.append(DELIMITER);
231  }
232  line.append(String.valueOf(strategy2count.get(strategies.get(i)).doubleValue() / sum));
233  }
234  try {
235  writer.write(line.toString());
236  writer.newLine();
237  } catch (IOException e) {
238  throw new RuntimeException("Could not initialize the plan strategy share writer!", e);
239  }
240  }
241 
242  @Override
243  public void notifyShutdown(ShutdownEvent event) {
244  // flush all pending plan inheritance records and close the readers
245 
246  for (PlanInheritanceRecord planInheritanceRecord : this.planId2planInheritanceRecords.values()) {
247  this.planInheritanceRecordWriter.write(planInheritanceRecord);
248  }
249 
250  this.planInheritanceRecordWriter.flush();
251  this.planInheritanceRecordWriter.close();
252 
253  try {
254  this.selectedPlanStrategyShareWriter.flush();
255  this.selectedPlanStrategyShareWriter.close();
256  this.planStrategyShareWriter.flush();
257  this.planStrategyShareWriter.close();
258  } catch (IOException e) {
259  new RuntimeException(e);
260  }
261 
262  this.planId2planInheritanceRecords.clear();
263  }
264 
265  @Override
266  public void install() {
267  if (getConfig().planInheritance().getEnabled()) addControlerListenerBinding().to(PlanInheritanceModule.class);
268  }
269 }
OutputDirectoryHierarchy getControlerIO()
BufferedWriter initializeDistributionWriter(ArrayList< String > strategies, String filename)
final List< GenericPlanStrategy< Plan, Person > > getStrategies(final String subpopulation)
Map< Id< Person >,? extends Person > getPersons()
static BufferedWriter getBufferedWriter(URL url, Charset charset, boolean append)
Definition: IOUtils.java:390
static< T > Id< T > create(final long key, final Class< T > type)
Definition: Id.java:68
final LinkedBindingBuilder< ControlerListener > addControlerListenerBinding()
ArrayList< String > getActiveStrategies(Collection< StrategySettings > strategySettings, StrategyManager strategyManager)
void calculateAndWriteDistribution(int currentIteration, ArrayList< String > strategies, Map< Id< Plan >, PlanInheritanceRecord > planId2planInheritanceRecords, Set< Id< Plan >> planIds, BufferedWriter writer)
final ReplanningConfigGroup replanning()
Definition: Config.java:427
StrategySettings getStrategySettings(final Id< StrategySettings > index, final boolean createIfMissing)
static boolean isSelected(Plan plan)