MATSIM
ConflictManager.java
Go to the documentation of this file.
1 package org.matsim.core.replanning.conflicts;
2 
3 import java.util.Collections;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7 import java.util.Random;
8 import java.util.Set;
9 import java.util.stream.Collectors;
10 
11 import org.apache.logging.log4j.LogManager;
12 import org.apache.logging.log4j.Logger;
13 import org.matsim.api.core.v01.Id;
14 import org.matsim.api.core.v01.IdSet;
19 
20 import com.google.common.base.Preconditions;
21 
32 public class ConflictManager {
33  private final static Logger logger = LogManager.getLogger(ConflictManager.class);
34 
35  private final Set<ConflictResolver> resolvers;
36  private final ConflictWriter writer;
37  private final Random random;
38 
39  public ConflictManager(Set<ConflictResolver> resolvers, ConflictWriter writer, Random random) {
40  this.resolvers = resolvers;
41  this.random = random;
42  this.writer = writer;
43  }
44 
45  public void initializeReplanning(Population population) {
46  if (resolvers.size() > 0) { // only require if active
47  population.getPersons().values().forEach(ReplanningUtils::setInitialPlan);
48  }
49  }
50 
51  public void run(Population population, int iteration) {
52  if (resolvers.size() == 0) {
53  return;
54  }
55 
56  logger.info("Resolving conflicts ...");
57 
58  Map<String, Integer> conflictCounts = new HashMap<>();
59  IdSet<Person> conflictingIds = new IdSet<>(Person.class);
60 
61  for (ConflictResolver resolver : resolvers) {
62  IdSet<Person> resolverConflictingIds = resolver.resolve(population, iteration);
63  conflictCounts.put(resolver.getName(), resolverConflictingIds.size());
64  conflictingIds.addAll(resolverConflictingIds);
65  }
66 
67  logger.info(" Conflicts: " + conflictCounts.entrySet().stream()
68  .map(entry -> String.format("%s=%d", entry.getKey(), entry.getValue()))
69  .collect(Collectors.joining(", ")));
70 
71  int switchedToInitialCount = 0;
72  int switchedToRandomCount = 0;
73 
74  for (Id<Person> personId : conflictingIds) {
75  Person person = population.getPersons().get(personId);
76 
77  // If the initial plan is non-conflicting, switch back to it
78  Plan initialPlan = ReplanningUtils.getInitialPlan(person);
79 
80  if (initialPlan != null && !isPotentiallyConflicting(initialPlan)) {
81  person.setSelectedPlan(initialPlan);
82  switchedToInitialCount++;
83  } else {
84  // Select a random non-conflicting plan
85  List<Plan> candidates = person.getPlans().stream().filter(p -> !isPotentiallyConflicting(p))
86  .collect(Collectors.toList());
87  Preconditions.checkState(candidates.size() > 0,
88  String.format("Agent %s has no non-conflicting plan", personId));
89 
90  // Shuffle, and select the first
91  Collections.shuffle(candidates, random);
92  person.setSelectedPlan(candidates.get(0));
93 
94  switchedToRandomCount++;
95  }
96  }
97 
98  logger.info(String.format(" %d (%.2f%%) switched to initial", switchedToInitialCount,
99  (double) switchedToInitialCount / population.getPersons().size()));
100  logger.info(String.format(" %d (%.2f%%) switched to random", switchedToRandomCount,
101  (double) switchedToRandomCount / population.getPersons().size()));
102 
103  writer.write(iteration, switchedToInitialCount, switchedToRandomCount, conflictCounts);
104 
105  logger.info(" Done resolving conflicts!");
106  }
107 
108  public boolean isPotentiallyConflicting(Plan plan) {
109  for (ConflictResolver resolver : resolvers) {
110  if (resolver.isPotentiallyConflicting(plan)) {
111  return true;
112  }
113  }
114 
115  return false;
116  }
117 }
Map< Id< Person >,? extends Person > getPersons()
ConflictManager(Set< ConflictResolver > resolvers, ConflictWriter writer, Random random)
boolean addAll(Collection<? extends Id< T >> c)
Definition: IdSet.java:132
void run(Population population, int iteration)
abstract void setSelectedPlan(T selectedPlan)
void write(int iteration, int rejectedToInitial, int rejectedToRandom, Map< String, Integer > conflictCounts)
abstract List<? extends T > getPlans()