MATSIM
ReplanningRunnable.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * ReplanningRunnable.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2008 by the members listed in the COPYING, *
8  * LICENSE and WARRANTY file. *
9  * email : info at matsim dot org *
10  * *
11  * *********************************************************************** *
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * See also COPYING, LICENSE and WARRANTY file *
18  * *
19  * *********************************************************************** */
20 
21 package org.matsim.withinday.replanning.parallel;
22 
23 import org.apache.logging.log4j.LogManager;
24 import org.apache.logging.log4j.Logger;
25 import org.matsim.api.core.v01.Id;
27 import org.matsim.core.gbl.Gbl;
30 import org.matsim.core.utils.misc.Time;
35 
36 import java.util.HashMap;
37 import java.util.Map;
38 import java.util.Map.Entry;
39 import java.util.Queue;
40 import java.util.TreeMap;
41 import java.util.concurrent.BrokenBarrierException;
42 import java.util.concurrent.CyclicBarrier;
43 
44 /*
45  * Typical Replanner Implementations should be able to use this
46  * Class method without any changes.
47  * Override the doReplanning() method to implement the replanning functionality.
48  */
49 public abstract class ReplanningRunnable implements Runnable {
50 
51  private final static Logger log = LogManager.getLogger(ReplanningRunnable.class);
52 
53  private Counter counter;
54  private double time = 0.0;
55  private volatile boolean simulationRunning = false;
56 
57  /*
58  * The original WithinDayReplanners are initialized and assigned
59  * to the Agents. They are cloned to run on parallel replanning
60  * Threads. Each agents has references to the original Replanners,
61  * so we have to identify the corresponding clone!
62  */
63  protected Map<Id<WithinDayReplanner>, WithinDayReplanner<? extends AgentSelector>> withinDayReplanners = new HashMap<>();
64 
65  /*
66  * Use one List of ReplanningTasks per WithinDayReplanner. By doing so
67  * and by using a CyclicBarrier, it can be ensured that only instances
68  * of the same WithinDayReplanner are run in parallel. Otherwise two
69  * different Replanners on different Threads could try to replan the
70  * same Agent.
71  */
72  protected Map<Id<WithinDayReplanner>, Queue<ReplanningTask>> replanningTasks = new TreeMap<>();
74 
75  protected CyclicBarrier timeStepStartBarrier;
76  protected CyclicBarrier betweenReplannerBarrier;
77  protected CyclicBarrier timeStepEndBarrier;
78 
79  public ReplanningRunnable(String counterText) {
80  counter = new Counter(counterText);
81  }
82 
83  public final void setEventsManager(EventsManager eventsManager) {
84  this.eventsManager = eventsManager;
85  }
86 
87  public final void setTime(double time) {
88  this.time = time;
89  }
90 
91  public final void setCyclicTimeStepStartBarrier(CyclicBarrier barrier) {
92  this.timeStepStartBarrier = barrier;
93  }
94 
95  public final void setBetweenReplannerBarrier(CyclicBarrier barrier) {
96  this.betweenReplannerBarrier = barrier;
97  }
98 
99  public final void setCyclicTimeStepEndBarrier(CyclicBarrier barrier) {
100  this.timeStepEndBarrier = barrier;
101  }
102 
103  public final void addReplanningTask(ReplanningTask replanningTask) {
104  Queue<ReplanningTask> queue = this.replanningTasks.get(replanningTask.getWithinDayReplannerId());
105  queue.add(replanningTask);
106  }
107 
108  public final void addWithinDayReplanner(WithinDayReplanner<? extends AgentSelector> withinDayReplanner, Queue<ReplanningTask> queue) {
109  this.withinDayReplanners.put(withinDayReplanner.getId(), withinDayReplanner);
110  this.replanningTasks.put(withinDayReplanner.getId(), queue);
111  }
112 
113  public final void removeWithinDayReplanner(Id<WithinDayReplanner> replannerId) {
114  this.withinDayReplanners.remove(replannerId);
115  this.replanningTasks.remove(replannerId);
116  }
117 
118  public final void resetReplanners() {
119  this.counter.reset();
120  for (WithinDayReplanner<? extends AgentSelector> withinDayReplanner : this.withinDayReplanners.values()) {
121  withinDayReplanner.reset();
122  }
123  }
124 
125  public final void beforeSim() {
126  this.simulationRunning = true;
127  }
128 
129  public final void afterSim() {
130  this.simulationRunning = false;
131  }
132 
133  /*
134  * Typical Replanner Implementations should be able to use
135  * this method without any Changes.
136  */
137  private void doReplanning() throws InterruptedException, BrokenBarrierException {
138 
139  for (Entry<Id<WithinDayReplanner>, Queue<ReplanningTask>> entry : this.replanningTasks.entrySet()) {
140 
141  Id<WithinDayReplanner> withinDayReplannerId = entry.getKey();
142  Queue<ReplanningTask> queue = entry.getValue();
143 
144  WithinDayReplanner<? extends AgentSelector> withinDayReplanner = this.withinDayReplanners.get(withinDayReplannerId);
145 
146  if (withinDayReplannerId == null) {
147  log.error("WithinDayReplanner Id is null!");
148  continue;
149  } else if (withinDayReplanner == null) {
150  log.error("WithinDayReplanner is null!");
151  continue;
152  }
153 
154  // set time once per replanner and time step
155  withinDayReplanner.setTime(time);
156 
157  ReplanningTask replanningTask;
158  while (true) {
159  replanningTask = queue.poll();
160 
161  // if no more elements are left in the queue, end while loop
162  if (replanningTask == null) break;
163 
164  MobsimAgent withinDayAgent = replanningTask.getAgentToReplan();
165 
166  if (withinDayAgent == null) {
167  log.error("WithinDayAgent is null!");
168  continue;
169  }
170 
171  boolean replanningSuccessful = withinDayReplanner.doReplanning(withinDayAgent);
172 
173  if (!replanningSuccessful) {
174  log.error("Replanning was not successful! Replanner " + withinDayReplanner.getClass().toString() +
175  ", time " + Time.writeTime(time) + ", agent " + withinDayAgent.getId());
176  }
177  else {
178  /*
179  * If the EventsManager is not null, we create an entry for the events log file.
180  */
181  if (eventsManager != null) {
182  ReplanningEvent replanningEvent = new ReplanningEvent(time, withinDayAgent.getId(),
183  withinDayReplanner.getClass().getSimpleName());
184  eventsManager.processEvent(replanningEvent);
185  }
186 
187  counter.incCounter();
188  }
189  }
190 
191  /*
192  * Wait here until all Threads have ended the replanning for the
193  * current WithinDayReplanner.
194  */
195  this.betweenReplannerBarrier.await();
196  }
197  }
198 
199  @Override
200  public final void run() {
201  while (simulationRunning) {
202  try {
203  /*
204  * The End of the Replanning is synchronized with
205  * the TimeStepEndBarrier. If all Threads reach this Barrier
206  * the main run() Thread can go on.
207  *
208  * The Threads wait now at the TimeStepStartBarrier until
209  * they are triggered again in the next TimeStep by the main run()
210  * method.
211  */
212  timeStepEndBarrier.await();
213 
214  timeStepStartBarrier.await();
215 
216  if (!simulationRunning) {
218  return;
219  }
220 
221  doReplanning();
222  } catch (InterruptedException | BrokenBarrierException e) {
223  throw new RuntimeException(e);
224  }
225 
226  } // while Simulation Running
227 
228  } // run()
229 
230 }
final void removeWithinDayReplanner(Id< WithinDayReplanner > replannerId)
abstract boolean doReplanning(MobsimAgent withinDayAgent)
final void setEventsManager(EventsManager eventsManager)
Map< Id< WithinDayReplanner >, Queue< ReplanningTask > > replanningTasks
static final String writeTime(final double seconds, final String timeformat)
Definition: Time.java:80
final void addReplanningTask(ReplanningTask replanningTask)
Map< Id< WithinDayReplanner >, WithinDayReplanner<? extends AgentSelector > > withinDayReplanners
final void addWithinDayReplanner(WithinDayReplanner<? extends AgentSelector > withinDayReplanner, Queue< ReplanningTask > queue)
static final void printCurrentThreadCpuTime()
Definition: Gbl.java:203