MATSIM
RunCustomScoringExample.java
Go to the documentation of this file.
1 package tutorial.programming.example16customscoring;
2 
3 import java.util.HashMap;
4 import java.util.Map;
5 
6 import org.matsim.api.core.v01.Id;
31 import org.matsim.vehicles.Vehicle;
32 
33 import javax.inject.Inject;
34 
36 
37  static class RainOnPersonEvent extends Event implements HasPersonId {
38 
39  private Id<Person> personId;
40 
41  public RainOnPersonEvent(double time, Id<Person> personId) {
42  super(time);
43  this.personId = personId;
44  }
45 
46  @Override
47  public Id<Person> getPersonId() {
48  return personId;
49  }
50 
51  @Override
52  public String getEventType() {
53  return "rain";
54  }
55 
56  @Override
57  public Map<String, String> getAttributes() {
58  final Map<String, String> attributes = super.getAttributes();
59  attributes.put("person", getPersonId().toString());
60  return attributes;
61  }
62 
63  }
64 
65  public static void main(String[] args) {
66  String configFile = "examples/tutorial/config/example5-config.xml" ;
67  final Scenario scenario = ScenarioUtils.loadScenario(ConfigUtils.loadConfig(configFile));
68 
69  // Every second person gets a special property which influences their score.
70  // ObjectAttributes can be written to and read from files, so in reality,
71  // this would come from a census, a pre-processing step, or from anywhere else,
72  // but for this example I just make it up.
73  final String DISLIKES_LEAVING_EARLY_AND_COMING_HOME_LATE = "DISLIKES_LEAVING_EARLY_AND_COMING_HOME_LATE";
74  final ObjectAttributes personAttributes = scenario.getPopulation().getPersonAttributes();
75  for (Person person : scenario.getPopulation().getPersons().values()) {
76  if (Integer.parseInt(person.getId().toString()) % 2 == 0) {
77  personAttributes.putAttribute(person.getId().toString(), DISLIKES_LEAVING_EARLY_AND_COMING_HOME_LATE, true);
78  } else {
79  personAttributes.putAttribute(person.getId().toString(), DISLIKES_LEAVING_EARLY_AND_COMING_HOME_LATE, false);
80  }
81  }
82 
83  Controler controler = new Controler(scenario);
84  controler.addOverridingModule(new AbstractModule() {
85  @Override
86  public void install() {
87  // We add a class which reacts on people who enter a link and lets it rain on them
88  // if we are within a certain time window.
89  // The class registers itself as an EventHandler and also produces events by itself.
90  bind(RainEngine.class).asEagerSingleton();
91  }
92  });
94 
95  @Override
96  public ScoringFunction createNewScoringFunction(Person person) {
97  SumScoringFunction sumScoringFunction = new SumScoringFunction();
98 
99  // Score activities, legs, payments and being stuck
100  // with the default MATSim scoring based on utility parameters in the config file.
101  final CharyparNagelScoringParameters params =
102  new CharyparNagelScoringParameters.Builder(scenario, person.getId()).build();
103  sumScoringFunction.addScoringFunction(new CharyparNagelActivityScoring(params));
104  sumScoringFunction.addScoringFunction(new CharyparNagelLegScoring(params, scenario.getNetwork()));
105  sumScoringFunction.addScoringFunction(new CharyparNagelMoneyScoring(params));
106  sumScoringFunction.addScoringFunction(new CharyparNagelAgentStuckScoring(params));
107 
108  // Some people (not all) really do not like leaving home early or coming home late. These people
109  // get extra penalties if that should happen.
110  // This property is not directly attached to the Person object. I have to look it up through my
111  // custom attribute table which I defined above.
112  if ((Boolean) personAttributes.getAttribute(person.getId().toString(), DISLIKES_LEAVING_EARLY_AND_COMING_HOME_LATE)) {
113  sumScoringFunction.addScoringFunction(new SumScoringFunction.ActivityScoring() {
114  private double score;
115  @Override public void handleFirstActivity(Activity act) {
116  if (act.getEndTime() < (6 * 60 * 60)) {
117  score -= 300.0;
118  }
119  }
120  @Override public void handleActivity(Activity act) {} // Not doing anything on mid-day activities.
121  @Override public void handleLastActivity(Activity act) {
122  if (act.getStartTime() > (20.0 * 60 * 60)) {
123  score -= 100.0;
124  }
125  }
126  @Override public void finish() {}
127  @Override
128  public double getScore() {
129  return score;
130  }
131  });
132  }
133 
135  private double score;
136  @Override
137  public void handleEvent(Event event) {
138  if (event instanceof RainOnPersonEvent) {
139  score -= 1000.0;
140  }
141  }
142  @Override public void finish() {}
143  @Override
144  public double getScore() {
145  return score;
146  }
147  });
148 
149  return sumScoringFunction;
150  }
151 
152  });
153  controler.run();
154  }
155 
156  static class RainEngine implements PersonEntersVehicleEventHandler, LinkEnterEventHandler {
157 
158  private EventsManager eventsManager;
159 
160  private Map<Id<Vehicle>, Id<Person>> vehicle2driver = new HashMap<>();
161 
162  @Inject
163  RainEngine(EventsManager eventsManager) {
164  this.eventsManager = eventsManager;
165  this.eventsManager.addHandler(this);
166  }
167 
168  @Override
169  public void reset(int iteration) {}
170 
171  @Override
172  public void handleEvent(PersonEntersVehicleEvent event) {
173  vehicle2driver.put(event.getVehicleId(), event.getPersonId());
174  }
175 
176  @Override
177  public void handleEvent(LinkEnterEvent event) {
178  if (rainingAt(event.getTime(), event.getLinkId())) {
179  eventsManager.processEvent(new RainOnPersonEvent(event.getTime(), vehicle2driver.get(event.getVehicleId())));
180  }
181  }
182 
183  // It starts raining on link 1 at 7:30.
184  private boolean rainingAt(double time, Id<Link> linkId) {
185  if (time > (7.5 * 60.0 * 60.0) && linkId.toString().equals("1")) {
186  return true;
187  } else {
188  return false;
189  }
190  }
191 
192  }
193 
194 }
final void setScoringFunctionFactory(final ScoringFunctionFactory scoringFunctionFactory)
Definition: Controler.java:376
Object putAttribute(final String objectId, final String attribute, final Object value)
void addScoringFunction(BasicScoring scoringFunction)
final void addOverridingModule(AbstractModule abstractModule)
Definition: Controler.java:410
Attributes getAttributes()
Definition: LinkImpl.java:323
Map< Id< Person >,?extends Person > getPersons()
void addHandler(final EventHandler handler)
Object getAttribute(final String objectId, final String attribute)
static Config loadConfig(final String filename, ConfigGroup...customModules)
static Scenario loadScenario(final Config config)