Eclipse SUMO - Simulation of Urban MObility
FareModul.h
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2002-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
18 // Fare Modul for calculating prices during intermodal routing
19 /****************************************************************************/
20 #pragma once
21 #include <config.h>
22 
23 #include <cassert>
24 #include <string>
25 #include <vector>
26 #include "EffortCalculator.h"
27 #include "FareToken.h"
28 #include "FareZones.h"
29 
30 
31 // ===========================================================================
32 // class definitions
33 // ===========================================================================
34 class ZoneCounter {
35 public:
36 
37  explicit ZoneCounter(unsigned int ct) :
38  myCount(ct) {
39 
40  }
41 
42  inline void addZone(int zoneNumber) {
43  zoneNumber = getOverlayZone(zoneNumber);
44  if (zoneNumber == 0) {
45  return;
46  }
47  long long int repNum = fareZoneToRep[zoneNumber];
48  //assert power of 2
49  if (bitcount(repNum) == 0) {
50  return;
51  }
52  myCount = myCount | repNum;
53  }
54 
55 
56  int numZones() const {
57  return bitcount(myCount);
58  }
59 
60 
61 private:
62  inline int bitcount(long long int intVal) const {
63  int count = 0;
64  long long int counter = intVal;
65 
66  while (counter != 0) {
67  counter = counter & (counter - 1);
68  ++count;
69  }
70  return count;
71  }
72 
73 private:
74  long long int myCount;
75 
76 
77 };
78 
79 
80 
85 struct FareState {
86  friend class FareModul;
87 
88 public:
89 
91  explicit FareState():
93  myCounter(std::numeric_limits<int>::max()),
94  myTravelledDistance(std::numeric_limits<double>::max()),
95  myVisistedStops(std::numeric_limits<int>::max()),
96  myPriceDiff(0) {
97  };
98 
103  explicit FareState(FareToken token):
104  myFareToken(token),
105  myCounter(0),
107  myVisistedStops(0),
108  myPriceDiff(0) {}
109 
111  ~FareState() = default;
112 
117  bool isValid() const {
118  return !(myFareToken == FareToken::None);
119  }
120 
121 private:
122 
132  double myPriceDiff;
133 
134 };
135 
136 
137 
138 struct Prices {
139 
140 
141 
143  std::vector<double> zonePrices = std::vector<double> {1.9, 3.4, 4.9, 6.2, 7.7, 9.2};
144  double halle = 2.3;
145  double leipzig = 2.7;
146  double t1 = 1.5;
147  double t2 = 1.6;
148  double t3 = 1.6;
149  double shortTrip = 1.6;
150  double shortTripLeipzig = 1.9;
151  double shortTripHalle = 1.7;
152  double maxPrice = 10.6;
153 };
154 
155 
159 class FareModul : public EffortCalculator {
160 public:
161 
164  myFareStates()
165  {};
166 
168  void init(const std::vector<std::string>& edges) override {
169  myEdges = edges;
170  myFareStates.resize(edges.size());
171  }
172 
173  void addStop(const int stopEdge, const Parameterised& params) override {
174  myStopFareZone[stopEdge] = StringUtils::toInt(params.getParameter("fareZone"));
175  myStopFareToken[stopEdge] = FareUtil::stringToToken(params.getParameter("fareToken"));
176  myStopStartToken[stopEdge] = FareUtil::stringToToken(params.getParameter("startToken"));
177  }
178 
180  double getEffort(const int numericalID) const override {
181  double effort = 0;
182  FareState const& state = myFareStates.at(numericalID);
183  if (state.isValid()) {
184  effort = state.myPriceDiff;
185  } else {
186  effort = std::numeric_limits<double>::max();
187  }
188  return effort;
189  }
190 
192  void update(const int edge, const int prev, const double length) override {
193 
194  std::string const& edgeType = myEdges[edge];
195 
196  //get propagated fare state
197  FareState& state = myFareStates.at(prev);
198 
199  double oldPr;
200  if (state.myFareToken == FareToken::START) {
201  oldPr = 0;
202  } else {
203  oldPr = computePrice(state);
204  }
205  //treat public transport edges
206  if (edgeType.c_str()[0] != '!') {
207  updateFareStatePublic(state, edge, length);
208  } else if (edgeType == "!stop") {
209  updateFareStateStop(state, edge);
210  } else if (edgeType == "!ped") {
211  updateFareStatePedestrian(state, edge);
212  } else if (edgeType == "!access") {
213  updateFareStateAccess(state, edge, prev);
214  } else {
215  updateFareState(state, edge);
216  }
217  FareState& stateAtE = myFareStates[edge];
218  double newPr = computePrice(stateAtE);
219  stateAtE.myPriceDiff = newPr - oldPr;
220 
221  assert(stateAtE.myPriceDiff >= 0);
222 
223  }
224 
227  void setInitialState(const int edge) override {
228 // assert( edge->getLine() == "!connector");
229 
231 
232  }
233 
234 
235 private:
237  std::vector<FareState> myFareStates;
238 
240  std::vector<std::string> myEdges;
241 
243  std::map<int, int> myStopFareZone;
244 
246  std::map<int, FareToken> myStopFareToken;
247 
249  std::map<int, FareToken> myStopStartToken;
250 
253 
254  double computePrice(FareState const& fareState) const {
255  switch (fareState.myFareToken) {
256  case FareToken ::H:
257  return prices.halle;
258  case FareToken ::L:
259  return prices.leipzig;
260  case FareToken ::T1:
261  return prices.t1;
262  case FareToken ::T2:
263  return prices.t2;
264  case FareToken ::T3:
265  return prices.t3;
266  case FareToken::U:
267  return prices.zonePrices[0];
268  case FareToken ::Z:
269  return prices.zonePrices[fareState.myCounter.numZones() - 1];
270  case FareToken ::M:
271  return prices.maxPrice;
272  case FareToken ::K:
273  return prices.shortTrip;
274  case FareToken ::KL:
275  case FareToken ::KLZ:
276  case FareToken ::KLU:
277  return prices.shortTripLeipzig;
278  case FareToken ::KH:
279  case FareToken ::KHU:
280  case FareToken ::KHZ:
281  return prices.shortTripHalle;
282  case FareToken::Free:
283  return 1.4;
284  case FareToken ::START:
285  return 0;
286  case FareToken::ZU:
287  case FareToken::None:
288  assert(false);
289 
290  }
291  return std::numeric_limits<double>::max();
292  }
293 
294 
295 
296  std::string output(const int edge) const override {
297 
298  FareState const& my = myFareStates[edge];
299  std::stringstream msg;
300  /*
301  msg << "Final fare state at edge of type: " << myEdges[edge] << std::endl;
302  msg << "Faretoken" << FareUtil::tokenToString(my.myFareToken) << std::endl;
303  msg << "Price:" << computePrice(my) << std::endl;
304  msg << "Zones " << my.myCounter.numZones() << std::endl;
305  msg << "Stations: " << my.myVisistedStops << std::endl;
306  msg << "Distance:" << my.myTravelledDistance << std::endl;
307  */
308  msg << FareUtil::tokenToTicket(my.myFareToken) << " ";
309  if (my.myFareToken == FareToken::Z) {
310  msg << my.myCounter.numZones() << " ";
311  if (my.myCounter.numZones() == 1) {
312  msg << "Zone";
313  } else {
314  msg << "Zonen";
315  }
316 
317  } else if (my.myFareToken == FareToken::U) {
318  msg << my.myCounter.numZones() << "1 Zone";
319 
320  }
321  msg << ":" << computePrice(my);
322  return msg.str();
323  }
324 
325  void updateFareStateStop(FareState const& currentFareState, const int stopEdge) {
326 
327  FareToken collectedToken = myStopFareToken[stopEdge];
328 
329  //if station has no fare information, just propagate
330  if (collectedToken == FareToken::None) {
331  std::cout << "Propagating fare state for stop w/o a price!" << std::endl;
332  return;
333  }
334 
335  FareToken const& token = currentFareState.myFareToken;
336 
337  FareState& stateAtE = myFareStates[stopEdge];
338 
339  stateAtE = currentFareState;
340 
341  stateAtE.myCounter.addZone(myStopFareZone[stopEdge]);
342 
343  stateAtE.myVisistedStops++;
344 
345  switch (token) {
346  case FareToken ::Free:
347  stateAtE.myFareToken = myStopStartToken[stopEdge];
348  break;
349  case FareToken::M :
350  break;
351 
352  case FareToken::Z :
353  if (stateAtE.myCounter.numZones() > 6) {
354  stateAtE.myFareToken = FareToken::M;
355  }
356  break;
357 
358  case FareToken::T1 :
359  case FareToken::T2 :
360  case FareToken::T3 :
361  if (collectedToken == FareToken::Z) {
362  stateAtE.myFareToken = stateAtE.myTravelledDistance <= 4000 ? FareToken::K : FareToken::Z;
363  }
364  break;
365  case FareToken::U :
366  if (collectedToken == FareToken::H) {
367  stateAtE.myFareToken = FareToken::H;
368  }
369  if (collectedToken == FareToken::L) {
370  stateAtE.myFareToken = FareToken::L;
371  }
372  if (collectedToken == FareToken::Z) {
373  stateAtE.myFareToken = FareToken::Z;
374  }
375  break;
376  case FareToken::H:
377  case FareToken::L:
378  if (collectedToken == FareToken::Z) {
379  stateAtE.myFareToken = FareToken::Z;
380  }
381  break;
382  case FareToken::KH:
383  if (stateAtE.myVisistedStops <= 4) {
384  if (collectedToken == FareToken::U) {
385  stateAtE.myFareToken = FareToken::KHU;
386  }
387  if (collectedToken == FareToken::Z) {
388  stateAtE.myFareToken = FareToken::KHZ;
389  }
390  } else {
391  if (collectedToken == FareToken::H) {
392  stateAtE.myFareToken = FareToken ::H;
393  }
394  if (collectedToken == FareToken::Z) {
395  stateAtE.myFareToken = FareToken ::Z;
396  }
397  if (collectedToken == FareToken::U) {
398  stateAtE.myFareToken = FareToken ::U;
399  }
400  }
401  break;
402  case FareToken::KL:
403  if (stateAtE.myVisistedStops <= 4) {
404  if (collectedToken == FareToken::U) {
405  stateAtE.myFareToken = FareToken::KLU;
406  }
407  if (collectedToken == FareToken::Z) {
408  stateAtE.myFareToken = FareToken::KLZ;
409  }
410  } else {
411  if (collectedToken == FareToken::L) {
412  stateAtE.myFareToken = FareToken ::L;
413  }
414  if (collectedToken == FareToken::Z) {
415  stateAtE.myFareToken = FareToken ::Z;
416  }
417  if (collectedToken == FareToken::U) {
418  stateAtE.myFareToken = FareToken ::U;
419  }
420  }
421  break;
422  case FareToken::K:
423  if (stateAtE.myTravelledDistance > 4000) {
424  if (collectedToken == FareToken::U) {
425  stateAtE.myFareToken = FareToken ::U;
426  }
427  if (collectedToken == FareToken::Z) {
428  stateAtE.myFareToken = FareToken ::Z;
429  }
430  }
431  break;
432  case FareToken::KHU :
433  case FareToken::KLU :
434  if (stateAtE.myVisistedStops > 4) {
435  if (collectedToken == FareToken::U) {
436  stateAtE.myFareToken = FareToken::U;
437  }
438  }
439  break;
440 
441  case FareToken::KLZ:
442  case FareToken::KHZ:
443  if (stateAtE.myVisistedStops > 4) {
444  if (collectedToken == FareToken::Z) {
445  stateAtE.myFareToken = FareToken::Z;
446  }
447  }
448  break;
449  case FareToken::ZU :
450  assert(false);
451  if (collectedToken == FareToken::U) {
452  stateAtE.myFareToken = FareToken::U;
453  } else {
454  stateAtE.myFareToken = FareToken::Z;
455  }
456 
457  break;
458  default:
459  std::cout << "Reached invalid position in fareToken selection!" << std::endl;
460  assert(false);
461  break;
462  }
463  }
464 
465  void updateFareStatePedestrian(FareState const& currentFareState, const int pedestrianEdge) {
466 
467  //only propagates the fare state
468  FareState& stateAtE = myFareStates[pedestrianEdge];
469 
470  stateAtE = currentFareState;
471 
472  if (currentFareState.myFareToken == FareToken::START) {
473  stateAtE.myFareToken = FareToken::Free;
474  }
475 
476  }
477 
478 
479  void updateFareStatePublic(FareState const& currentFareState, const int publicTransportEdge, const double length) {
480 
481 
482  if (currentFareState.myFareToken == FareToken::None) {
483  return;
484  }
485 
486  FareState& stateAtE = myFareStates[publicTransportEdge];
487 
488  stateAtE = currentFareState;
489  stateAtE.myTravelledDistance += length;
490  }
491 
492  void updateFareState(FareState const& currentFareState, const int intermodalEdge) {
493 
494  if (currentFareState.myFareToken == FareToken::None) {
495  return;
496  }
497 
498  FareState& stateAtE = myFareStates[intermodalEdge];
499 
500  stateAtE = currentFareState;
501 
502  if (currentFareState.myFareToken == FareToken::START) {
503  stateAtE.myFareToken = FareToken::Free;
504  }
505 
506  }
507 
508  void updateFareStateAccess(FareState const& currentFareState, const int accessEdge, const int prev) {
509 
510  FareToken const& token = currentFareState.myFareToken;
511 
512  FareState& stateAtE = myFareStates[accessEdge];
513 
514  stateAtE = currentFareState;
515 
516  if (currentFareState.myFareToken == FareToken::START) {
517  stateAtE.myFareToken = FareToken::Free;
518  }
519 
520  if (myEdges[prev] == "!ped") {
521  switch (token) {
522 
523  case FareToken::Free ://we have not yet taken public transport
524  break;
525  case FareToken::K :
526  if (currentFareState.myCounter.numZones() == 0) {
527  stateAtE.myFareToken = FareToken::U;
528  } else {
529  stateAtE.myFareToken = FareToken::Z;
530  }
531  break;
532  case FareToken::KH :
533  stateAtE.myFareToken = FareToken::H;
534  break;
535  case FareToken::KL :
536  stateAtE.myFareToken = FareToken::L;
537  break;
538  case FareToken::KLU :
539  stateAtE.myFareToken = FareToken::L;
540  break;
541  case FareToken::KHU:
542  stateAtE.myFareToken = FareToken::H;
543  break;
544  case FareToken::KLZ :
545  stateAtE.myFareToken = FareToken::Z;
546  break;
547  case FareToken::KHZ:
548  stateAtE.myFareToken = FareToken::Z;
549  break;
550  default:
551  return;
552  }
553  }
554 
555  }
556 };
FareToken
Definition: FareToken.h:23
static std::unordered_map< int, long long int > fareZoneToRep
Definition: FareZones.h:92
int getOverlayZone(int zoneNumber)
Definition: FareZones.h:162
the effort calculator interface
double getEffort(const int numericalID) const override
Definition: FareModul.h:180
void setInitialState(const int edge) override
Definition: FareModul.h:227
void updateFareStatePublic(FareState const &currentFareState, const int publicTransportEdge, const double length)
Definition: FareModul.h:479
void updateFareStatePedestrian(FareState const &currentFareState, const int pedestrianEdge)
Definition: FareModul.h:465
void addStop(const int stopEdge, const Parameterised &params) override
Definition: FareModul.h:173
Prices prices
Definition: FareModul.h:252
std::vector< FareState > myFareStates
Definition: FareModul.h:237
std::vector< std::string > myEdges
Definition: FareModul.h:240
std::map< int, int > myStopFareZone
Definition: FareModul.h:243
std::map< int, FareToken > myStopStartToken
Definition: FareModul.h:249
void init(const std::vector< std::string > &edges) override
Definition: FareModul.h:168
void updateFareStateStop(FareState const &currentFareState, const int stopEdge)
Definition: FareModul.h:325
std::string output(const int edge) const override
Definition: FareModul.h:296
void updateFareStateAccess(FareState const &currentFareState, const int accessEdge, const int prev)
Definition: FareModul.h:508
void updateFareState(FareState const &currentFareState, const int intermodalEdge)
Definition: FareModul.h:492
std::map< int, FareToken > myStopFareToken
Definition: FareModul.h:246
void update(const int edge, const int prev, const double length) override
Definition: FareModul.h:192
double computePrice(FareState const &fareState) const
Definition: FareModul.h:254
An upper class for objects with additional parameters.
Definition: Parameterised.h:41
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
ZoneCounter(unsigned int ct)
Definition: FareModul.h:37
long long int myCount
Definition: FareModul.h:74
int bitcount(long long int intVal) const
Definition: FareModul.h:62
int numZones() const
Definition: FareModul.h:56
void addZone(int zoneNumber)
Definition: FareModul.h:42
std::string tokenToTicket(FareToken const &token)
Definition: FareToken.h:93
FareToken stringToToken(std::string str)
Definition: FareToken.h:137
Definition: json.hpp:4471
int myVisistedStops
Definition: FareModul.h:130
double myTravelledDistance
Definition: FareModul.h:128
FareState()
Definition: FareModul.h:91
double myPriceDiff
Definition: FareModul.h:132
FareToken myFareToken
Definition: FareModul.h:124
~FareState()=default
bool isValid() const
Definition: FareModul.h:117
ZoneCounter myCounter
Definition: FareModul.h:126
FareState(FareToken token)
Definition: FareModul.h:103
double shortTripHalle
Definition: FareModul.h:151
double halle
Definition: FareModul.h:144
double shortTrip
Definition: FareModul.h:149
std::vector< double > zonePrices
Definition: FareModul.h:143
double t3
Definition: FareModul.h:148
double shortTripLeipzig
Definition: FareModul.h:150
double leipzig
Definition: FareModul.h:145
double t2
Definition: FareModul.h:147
double maxPrice
Definition: FareModul.h:152
double t1
Definition: FareModul.h:146