Eclipse SUMO - Simulation of Urban MObility
LogitCalculator.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 /****************************************************************************/
20 // Calculators for route costs and probabilities
21 /****************************************************************************/
22 #pragma once
23 #include <config.h>
24 
25 #include <vector>
26 #include <map>
27 
28 
29 // ===========================================================================
30 // class definitions
31 // ===========================================================================
36 template<class R, class E, class V>
37 class LogitCalculator : public RouteCostCalculator<R, E, V> {
38 public:
40  LogitCalculator(const double beta, const double gamma,
41  const double theta) : myBeta(beta), myGamma(gamma), myTheta(theta) {}
42 
44  virtual ~LogitCalculator() {}
45 
46  void setCosts(R* route, const double costs, const bool /* isActive */) const {
47  route->setCosts(costs);
48  }
49 
51  void calculateProbabilities(std::vector<R*> alternatives, const V* const veh, const SUMOTime time) {
52  const double theta = myTheta >= 0 ? myTheta : getThetaForCLogit(alternatives);
53  const double beta = myBeta >= 0 ? myBeta : getBetaForCLogit(alternatives);
54  const double t = STEPS2TIME(time);
55  if (beta > 0) {
56  // calculate commonalities
57  for (const R* const pR : alternatives) {
58  double lengthR = 0;
59  const std::vector<const E*>& edgesR = pR->getEdgeVector();
60  for (const E* const edge : edgesR) {
61  //@todo we should use costs here
62  lengthR += edge->getTravelTime(veh, t);
63  }
64  double overlapSum = 0;
65  for (const R* const pS : alternatives) {
66  double overlapLength = 0.;
67  double lengthS = 0;
68  for (const E* const edge : pS->getEdgeVector()) {
69  lengthS += edge->getTravelTime(veh, t);
70  if (std::find(edgesR.begin(), edgesR.end(), edge) != edgesR.end()) {
71  overlapLength += edge->getTravelTime(veh, t);
72  }
73  }
74  overlapSum += pow(overlapLength / sqrt(lengthR * lengthS), myGamma);
75  }
76  myCommonalities[pR] = beta * log(overlapSum);
77  }
78  }
79  for (R* const pR : alternatives) {
80  double weightedSum = 0;
81  for (const R* const pS : alternatives) {
82  weightedSum += exp(theta * (pR->getCosts() - pS->getCosts() + myCommonalities[pR] - myCommonalities[pS]));
83  }
84  pR->setProbability(1. / weightedSum);
85  }
86  }
87 
88 
89 private:
91  double getBetaForCLogit(const std::vector<R*> alternatives) const {
92  double min = std::numeric_limits<double>::max();
93  for (const R* const pR : alternatives) {
94  const double cost = pR->getCosts() / 3600.;
95  if (cost < min) {
96  min = cost;
97  }
98  }
99  return min;
100  }
101 
103  double getThetaForCLogit(const std::vector<R*> alternatives) const {
104  // @todo this calculation works for travel times only
105  double sum = 0.;
106  double diff = 0.;
107  double min = std::numeric_limits<double>::max();
108  for (const R* const pR : alternatives) {
109  const double cost = pR->getCosts() / 3600.;
110  sum += cost;
111  if (cost < min) {
112  min = cost;
113  }
114  }
115  const double meanCost = sum / double(alternatives.size());
116  for (const R* const pR : alternatives) {
117  diff += pow(pR->getCosts() / 3600. - meanCost, 2);
118  }
119  const double cvCost = sqrt(diff / double(alternatives.size())) / meanCost;
120  // @todo re-evaluate function
121  if (cvCost > 0) { // all Magic numbers from Lohse book, original says this should be cvCost > 0.04
122  return 3.1415926535897932384626433832795 / (sqrt(6.) * cvCost * (min + 1.1)) / 3600.;
123  }
124  return 1. / 3600.;
125  }
126 
127 
128 private:
130  const double myBeta;
131 
133  const double myGamma;
134 
136  const double myTheta;
137 
139  std::map<const R*, double> myCommonalities;
140 
141 private:
144 
145 };
long long int SUMOTime
Definition: GUI.h:35
#define STEPS2TIME(x)
Definition: SUMOTime.h:55
Cost calculation with c-logit or logit method.
LogitCalculator(const double beta, const double gamma, const double theta)
Constructor.
double getBetaForCLogit(const std::vector< R * > alternatives) const
calculate the scaling factor in the logit model
void setCosts(R *route, const double costs, const bool) const
void calculateProbabilities(std::vector< R * > alternatives, const V *const veh, const SUMOTime time)
calculate the probabilities in the logit model
double getThetaForCLogit(const std::vector< R * > alternatives) const
calculate the scaling factor in the logit model
const double myGamma
logit gamma - value
const double myBeta
logit beta - value
std::map< const R *, double > myCommonalities
The route commonality factors for c-logit.
const double myTheta
logit theta - value
LogitCalculator & operator=(const LogitCalculator &s)
invalidated assignment operator
virtual ~LogitCalculator()
Destructor.
Abstract base class providing static factory method.