MATSIM
PopulationComparison.java
Go to the documentation of this file.
1 package org.matsim.core.population.routes;
2 
3 import org.apache.logging.log4j.LogManager;
4 import org.apache.logging.log4j.Logger;
8 
9 import java.util.Iterator;
10 import java.util.List;
11 import java.util.Optional;
12 
13 public class PopulationComparison {
14 
15  private final static double DEFAULT_DELTA = 1e-10;
16 
17  public enum Result {equal, notEqual}
18 
19  private static final Logger log = LogManager.getLogger(PopulationComparison.class);
20 
22  }
23 
24  public static Result compare(Population population1, Population population2) {
25  return compare(population1, population2, DEFAULT_DELTA);
26  }
27 
28 
29  public static Result compare(Population population1, Population population2, double delta) {
30  Result result = Result.equal;
31 
32  Iterator<? extends Person> it1 = population1.getPersons().values().iterator();
33  Iterator<? extends Person> it2 = population2.getPersons().values().iterator();
34 
35  while (it1.hasNext() || it2.hasNext()) {
36  if (!it1.hasNext()) {
37  result = Result.notEqual;
38  log.warn("");
39  log.warn(" different length in populations. ");
40  return result;
41  }
42  if (!it2.hasNext()) {
43  result = Result.notEqual;
44  log.warn("");
45  log.warn(" different length in populations. ");
46  return result;
47  }
48 
49  Person person1 = it1.next();
50  Person person2 = it2.next();
51 
52  if (!person1.getId().equals(person2.getId())) {
53  log.warn("");
54  log.warn("persons out of sequence p1: " + person1.getId() + " | p2: " + person2.getId());
55  result = Result.notEqual;
56  continue;
57  }
58 
59  if (!AttributesComparison.equals(person1.getAttributes(), person2.getAttributes())) {
60  log.warn("");
61  log.warn("person attributes different p1: " + person1.getId() + " | p2: " + person2.getId());
62  }
63 
64  Plan plan1 = person1.getSelectedPlan();
65  Plan plan2 = person2.getSelectedPlan();
66 
67  if (!AttributesComparison.equals(plan1.getAttributes(), plan2.getAttributes())) {
68  log.warn("");
69  log.warn("selected plan attributes different p1: " + person1.getId() + " | p2: " + person2.getId());
70  }
71 
72  Optional<Double> score1 = Optional.ofNullable(plan1.getScore());
73  Optional<Double> score2 = Optional.ofNullable(plan2.getScore());
74 
75  if (score1.isPresent() && score2.isPresent()) {
76  if (!isWithinDelta(plan1.getScore(), plan2.getScore(), delta)) {
77 
78  double maxScore = Double.NEGATIVE_INFINITY;
79  for (Plan plan : person2.getPlans()) {
80  if (plan.getScore() > maxScore) {
81  maxScore = plan.getScore();
82  }
83  }
84 
85  log.warn("");
86  log.warn("personId=" + person1.getId() + "; score1=" + plan1.getScore() + "; score2=" + plan2.getScore() + "; maxScore2=" + maxScore);
87  log.warn("");
88 
89  result = Result.notEqual;
90 
91  }
92  } else if (score1.isEmpty() && score2.isEmpty()) {
93  } else {
94  log.warn("");
95  log.warn(" selected plan scores not consistently present: p1: " + person1.getId() + " | p2: " + person2.getId());
96  result = Result.notEqual;
97  }
98 
99  if (!equals(plan1.getPlanElements(), plan2.getPlanElements())) {
100  log.warn("");
101  log.warn(" selected plan elements not equal: p1: " + person1.getId() + " | p2: " + person2.getId());
102 
103  for (PlanElement planElement : plan1.getPlanElements()) {
104  log.warn(planElement);
105  }
106  log.warn("");
107  for (PlanElement planElement : plan2.getPlanElements()) {
108  log.warn(planElement);
109  }
110  log.warn("");
111  result = Result.notEqual;
112  }
113  }
114  return result;
115  }
116 
117  private static boolean isWithinDelta(double double1, double double2, double delta) {
118  return Math.abs(double1 - double2) < delta;
119  }
120 
121  private static boolean isBothUndefinedOrWithinDelta(OptionalTime time1, OptionalTime time2, double delta) {
122  if (time1.isUndefined() ^ time2.isUndefined()) {
123  return false;
124  } else if(time1.isDefined()) {
125  return isWithinDelta((int) time1.seconds(), (int) time2.seconds(), delta);
126  }
127  return true;
128  }
129 
130  public static boolean equals(List<PlanElement> planElements,
131  List<PlanElement> planElements2) {
132  return equals(planElements, planElements2, DEFAULT_DELTA);
133  }
134 
135  public static boolean equals(List<PlanElement> planElements,
136  List<PlanElement> planElements2, double delta) {
137  int nElements = planElements.size();
138  if (nElements != planElements2.size()) {
139  return false;
140  } else {
141  for (int i = 0; i < nElements; i++) {
142  if (!equals(planElements.get(i), planElements2.get(i), delta)) {
143  return false;
144  }
145  }
146  }
147  return true;
148  }
149 
150  /* Warning: This is NOT claimed to be correct. (It isn't.)
151  *
152  */
153  private static boolean equals(PlanElement o1, PlanElement o2, double delta) {
155  return false;
156  }
157  if (o1 instanceof Leg leg1) {
158  if (o2 instanceof Leg leg2) {
159  if(!isBothUndefinedOrWithinDelta(leg1.getDepartureTime(), leg2.getDepartureTime(), delta)) {
160  return false;
161  }
162  if (!leg1.getMode().equals(leg2.getMode())) {
163  return false;
164  }
165  if (!isBothUndefinedOrWithinDelta(leg1.getTravelTime(), leg2.getTravelTime(), delta)) {
166  return false;
167  }
168  } else {
169  return false;
170  }
171  } else if (o1 instanceof Activity activity1) {
172  if (o2 instanceof Activity activity2) {
173  if (!isBothUndefinedOrWithinDelta(activity1.getEndTime(), activity2.getEndTime(), delta)) {
174  return false;
175  }
176  if (!isBothUndefinedOrWithinDelta(activity1.getStartTime(), activity2.getStartTime(), delta)) {
177  return false;
178  }
179  } else {
180  return false;
181  }
182  } else {
183  throw new RuntimeException("Unexpected PlanElement");
184  }
185  return true;
186  }
187 }
static boolean equals(List< PlanElement > planElements, List< PlanElement > planElements2, double delta)
static boolean isBothUndefinedOrWithinDelta(OptionalTime time1, OptionalTime time2, double delta)
Map< Id< Person >,? extends Person > getPersons()
static boolean equals(List< PlanElement > planElements, List< PlanElement > planElements2)
static Result compare(Population population1, Population population2)
static Result compare(Population population1, Population population2, double delta)
List< PlanElement > getPlanElements()
static boolean equals(PlanElement o1, PlanElement o2, double delta)
static boolean isWithinDelta(double double1, double double2, double delta)
abstract List<? extends T > getPlans()