MATSIM
SumScoringFunction.java
Go to the documentation of this file.
1 
2 /* *********************************************************************** *
3  * project: org.matsim.*
4  * SumScoringFunction.java
5  * *
6  * *********************************************************************** *
7  * *
8  * copyright : (C) 2019 by the members listed in the COPYING, *
9  * LICENSE and WARRANTY file. *
10  * email : info at matsim dot org *
11  * *
12  * *********************************************************************** *
13  * *
14  * This program is free software; you can redistribute it and/or modify *
15  * it under the terms of the GNU General Public License as published by *
16  * the Free Software Foundation; either version 2 of the License, or *
17  * (at your option) any later version. *
18  * See also COPYING, LICENSE and WARRANTY file *
19  * *
20  * *********************************************************************** */
21 
22  package org.matsim.core.scoring;
23 
24 import java.util.ArrayList;
25 import java.util.List;
26 
27 import org.apache.logging.log4j.LogManager;
28 import org.apache.logging.log4j.Logger;
33 
34 public final class SumScoringFunction implements ScoringFunction {
35 
36  public interface BasicScoring {
37  void finish();
38  double getScore();
39 
43  default void explainScore(StringBuilder out) {
44  }
45  }
46 
47  public interface ActivityScoring extends BasicScoring {
48  void handleFirstActivity(final Activity act);
49  void handleActivity(final Activity act);
50  void handleLastActivity(final Activity act);
51  }
52 
53  public interface LegScoring extends BasicScoring {
54  void handleLeg(final Leg leg);
55  }
56 
57  public interface TripScoring extends BasicScoring{
58  void handleTrip(final Trip trip) ;
59  }
60 
61  public interface MoneyScoring extends BasicScoring {
62  void addMoney(final double amount);
63  }
64 
65  public interface ScoreScoring extends BasicScoring {
66  void addScore(final double amount);
67  }
68 
69  public interface AgentStuckScoring extends BasicScoring {
70  void agentStuck(final double time);
71  }
72 
84  public interface ArbitraryEventScoring extends BasicScoring {
85  void handleEvent( final Event event ) ;
86  }
87 
88  private static final Logger log = LogManager.getLogger(SumScoringFunction.class);
89 
90  private final List<BasicScoring> basicScoringFunctions = new ArrayList<>();
91  private final List<ActivityScoring> activityScoringFunctions = new ArrayList<>();
92  private final List<MoneyScoring> moneyScoringFunctions = new ArrayList<>();
93  private final List<ScoreScoring> scoreScoringFunctions = new ArrayList<>();
94  private final List<LegScoring> legScoringFunctions = new ArrayList<>();
95  private final List<TripScoring> tripScoringFunctions = new ArrayList<>();
96  private final List<AgentStuckScoring> agentStuckScoringFunctions = new ArrayList<>();
97  private final List<ArbitraryEventScoring> arbitraryEventScoringFunctions = new ArrayList<>() ;
98 
99  @Override
100  public final void handleActivity(Activity activity) {
101  if (activity.getStartTime().isUndefined() && activity.getEndTime().isDefined()) {
102  for (ActivityScoring activityScoringFunction : this.activityScoringFunctions) {
103  activityScoringFunction.handleFirstActivity(activity);
104  }
105  } else if (activity.getStartTime().isDefined() && activity.getEndTime().isDefined()) {
106  for (ActivityScoring activityScoringFunction : this.activityScoringFunctions) {
107  activityScoringFunction.handleActivity(activity);
108  }
109  } else if (activity.getStartTime().isDefined() && activity.getEndTime().isUndefined()) {
110  for (ActivityScoring activityScoringFunction : this.activityScoringFunctions) {
111  activityScoringFunction.handleLastActivity(activity);
112  }
113  } else {
114  throw new RuntimeException(
115  "Trying to score an activity without start or end time. Should not happen. Activity=" + activity);
116  }
117  }
118 
119  @Override
120  public final void handleLeg(Leg leg) {
121  for (LegScoring legScoringFunction : this.legScoringFunctions) {
122  legScoringFunction.handleLeg(leg);
123  }
124  }
125 
126  @Override
127  public final void handleTrip(Trip trip) {
128  for (TripScoring tripScoringFunction : this.tripScoringFunctions) {
129  tripScoringFunction.handleTrip(trip);
130  }
131  }
132 
133  @Override
134  public void addMoney(double amount) {
135  for (MoneyScoring moneyScoringFunction : this.moneyScoringFunctions) {
136  moneyScoringFunction.addMoney(amount);
137  }
138  }
139 
140  @Override
141  public void addScore(double amount) {
142  for (ScoreScoring scoreScoringFunction : this.scoreScoringFunctions) {
143  scoreScoringFunction.addScore(amount);
144  }
145  }
146 
147  @Override
148  public void agentStuck(double time) {
149  for (AgentStuckScoring agentStuckScoringFunction : this.agentStuckScoringFunctions) {
150  agentStuckScoringFunction.agentStuck(time);
151  }
152  }
153 
154  @Override
155  public void handleEvent(Event event) {
156  for (ArbitraryEventScoring eventScoringFunction : this.arbitraryEventScoringFunctions) {
157  eventScoringFunction.handleEvent(event) ;
158  }
159  }
160 
161  @Override
162  public void finish() {
163  for (BasicScoring basicScoringFunction : this.basicScoringFunctions) {
164  basicScoringFunction.finish();
165  }
166  }
167 
171  @Override
172  public double getScore() {
173  double score = 0.0;
174  for (BasicScoring basicScoringFunction : this.basicScoringFunctions) {
175  double contribution = basicScoringFunction.getScore();
176  if (log.isTraceEnabled()) {
177  log.trace("Contribution of scoring function: " + basicScoringFunction.getClass().getName() + " is: " + contribution);
178  }
179  if ( Double.isNaN( contribution ) ) {
180  // I consider this dangerous enough to justify a crash. If somebody has strong arguments for NaN scores,
181  // one might change this to "log.error(...)". td june 15
182  throw new RuntimeException( "Contribution of scoring function: " + basicScoringFunction.getClass().getName() + " is NaN! Behavior with NaN scores is undefined." );
183  }
184  score += contribution;
185  }
186  return score;
187  }
188 
189 
190  @Override
191  public void explainScore(StringBuilder out) {
192 
193  for (BasicScoring s : basicScoringFunctions) {
194 
195  // If something was already written, a delimiter needs to be placed
196  if (!out.isEmpty())
197  out.append(SCORE_DELIMITER);
198 
199  s.explainScore(out);
200  }
201  }
202 
203  public void addScoringFunction(BasicScoring scoringFunction) {
204  this.basicScoringFunctions.add(scoringFunction);
205 
206  if (scoringFunction instanceof ActivityScoring) {
207  this.activityScoringFunctions.add((ActivityScoring) scoringFunction);
208  }
209 
210  if (scoringFunction instanceof AgentStuckScoring) {
211  this.agentStuckScoringFunctions.add((AgentStuckScoring) scoringFunction);
212  }
213 
214  if (scoringFunction instanceof LegScoring) {
215  this.legScoringFunctions.add((LegScoring) scoringFunction);
216  }
217 
218  if (scoringFunction instanceof TripScoring) {
219  this.tripScoringFunctions.add((TripScoring) scoringFunction);
220  }
221 
222  if (scoringFunction instanceof MoneyScoring) {
223  this.moneyScoringFunctions.add((MoneyScoring) scoringFunction);
224  }
225 
226  if (scoringFunction instanceof ScoreScoring) {
227  this.scoreScoringFunctions.add((ScoreScoring) scoringFunction);
228  }
229 
230  if (scoringFunction instanceof ArbitraryEventScoring) {
231  this.arbitraryEventScoringFunctions.add((ArbitraryEventScoring) scoringFunction);
232  }
233 
234  }
235 
236 
237 }
void addScoringFunction(BasicScoring scoringFunction)
final List< ArbitraryEventScoring > arbitraryEventScoringFunctions
final List< BasicScoring > basicScoringFunctions
final List< AgentStuckScoring > agentStuckScoringFunctions
final List< ScoreScoring > scoreScoringFunctions
final List< ActivityScoring > activityScoringFunctions
final List< MoneyScoring > moneyScoringFunctions
final void handleActivity(Activity activity)