Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2002-2026 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 : /****************************************************************************/
14 : /// @file LogitCalculator.h
15 : /// @author Daniel Krajzewicz
16 : /// @author Michael Behrisch
17 : /// @author Jakob Erdmann
18 : /// @date Sept 2002
19 : ///
20 : // Calculators for route costs and probabilities
21 : /****************************************************************************/
22 : #pragma once
23 : #include <config.h>
24 :
25 : #include <vector>
26 : #include <map>
27 :
28 : #include "RouteCostCalculator.h"
29 :
30 :
31 : // ===========================================================================
32 : // class definitions
33 : // ===========================================================================
34 : /**
35 : * @class LogitCalculator
36 : * @brief Cost calculation with c-logit or logit method.
37 : */
38 : template<class R, class E, class V>
39 : class LogitCalculator : public RouteCostCalculator<R, E, V> {
40 : public:
41 : /// Constructor
42 49 : LogitCalculator(const double beta, const double gamma,
43 49 : const double theta) : myBeta(beta), myGamma(gamma), myTheta(theta) {}
44 :
45 : /// Destructor
46 49 : virtual ~LogitCalculator() {}
47 :
48 28319 : void setCosts(std::shared_ptr<R> route, const double costs, const bool /* isActive */) const {
49 28319 : route->setCosts(costs);
50 28319 : }
51 :
52 : /** @brief calculate the probabilities in the logit model */
53 11727 : void calculateProbabilities(const std::vector<std::shared_ptr<R> >& alternatives, const V* const veh, const SUMOTime time) {
54 11727 : const double theta = myTheta >= 0 ? myTheta : getThetaForCLogit(alternatives);
55 12595 : const double beta = myBeta >= 0 ? myBeta : getBetaForCLogit(alternatives);
56 11727 : const double t = STEPS2TIME(time);
57 11727 : if (beta > 0) {
58 : // calculate commonalities
59 40051 : for (const std::shared_ptr<R>& pR : alternatives) {
60 : double lengthR = 0;
61 : const std::vector<const E*>& edgesR = pR->getEdgeVector();
62 186846 : for (const E* const edge : edgesR) {
63 : //@todo we should use costs here
64 158518 : lengthR += edge->getTravelTime(veh, t);
65 : }
66 : double overlapSum = 0;
67 102552 : for (const std::shared_ptr<R>& pS : alternatives) {
68 : double overlapLength = 0.;
69 : double lengthS = 0;
70 493511 : for (const E* const edge : pS->getEdgeVector()) {
71 419287 : lengthS += edge->getTravelTime(veh, t);
72 419287 : if (std::find(edgesR.begin(), edgesR.end(), edge) != edgesR.end()) {
73 298820 : overlapLength += edge->getTravelTime(veh, t);
74 : }
75 : }
76 74224 : overlapSum += pow(overlapLength / sqrt(lengthR * lengthS), myGamma);
77 : }
78 28328 : myCommonalities[pR.get()] = beta * log(overlapSum);
79 : }
80 : }
81 40071 : for (const std::shared_ptr<R>& pR : alternatives) {
82 : double weightedSum = 0;
83 102632 : for (const std::shared_ptr<R>& pS : alternatives) {
84 74288 : weightedSum += exp(theta * (pR->getCosts() - pS->getCosts() + myCommonalities[pR.get()] - myCommonalities[pS.get()]));
85 : }
86 28344 : pR->setProbability(1. / weightedSum);
87 : }
88 11727 : }
89 :
90 :
91 : private:
92 : /** @brief calculate the scaling factor in the logit model */
93 : double getBetaForCLogit(const std::vector<std::shared_ptr<R> > alternatives) const {
94 : double min = std::numeric_limits<double>::max();
95 2220 : for (const std::shared_ptr<R>& pR : alternatives) {
96 1352 : const double cost = pR->getCosts() / 3600.;
97 1352 : if (cost < min) {
98 : min = cost;
99 : }
100 : }
101 : return min;
102 : }
103 :
104 : /** @brief calculate the scaling factor in the logit model */
105 11648 : double getThetaForCLogit(const std::vector<std::shared_ptr<R> > alternatives) const {
106 : // @todo this calculation works for travel times only
107 : double sum = 0.;
108 : double diff = 0.;
109 : double min = std::numeric_limits<double>::max();
110 39831 : for (const std::shared_ptr<R>& pR : alternatives) {
111 : const double cost = pR->getCosts() / 3600.;
112 28183 : sum += cost;
113 28183 : if (cost < min) {
114 : min = cost;
115 : }
116 : }
117 11648 : const double meanCost = sum / double(alternatives.size());
118 39831 : for (const std::shared_ptr<R>& pR : alternatives) {
119 28183 : diff += pow(pR->getCosts() / 3600. - meanCost, 2);
120 : }
121 11648 : const double cvCost = sqrt(diff / double(alternatives.size())) / meanCost;
122 : // @todo re-evaluate function
123 11648 : if (cvCost > 0) { // all Magic numbers from Lohse book, original says this should be cvCost > 0.04
124 10448 : return 3.1415926535897932384626433832795 / (sqrt(6.) * cvCost * (min + 1.1)) / 3600.;
125 : }
126 : return 1. / 3600.;
127 : }
128 :
129 :
130 : private:
131 : /// @brief logit beta - value
132 : const double myBeta;
133 :
134 : /// @brief logit gamma - value
135 : const double myGamma;
136 :
137 : /// @brief logit theta - value
138 : const double myTheta;
139 :
140 : /// @brief The route commonality factors for c-logit
141 : // we do not use a shared pointer here to avoid lifetime extension of the route object
142 : // TODO this map needs cleanup if we use it a lot or even better we should somehow store the value directly in the route
143 : std::map<const R*, double> myCommonalities;
144 :
145 : private:
146 : /** @brief invalidated assignment operator */
147 : LogitCalculator& operator=(const LogitCalculator& s);
148 :
149 : };
|