Line data Source code
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 : /****************************************************************************/
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 :
29 : // ===========================================================================
30 : // class definitions
31 : // ===========================================================================
32 : /**
33 : * @class LogitCalculator
34 : * @brief Cost calculation with c-logit or logit method.
35 : */
36 : template<class R, class E, class V>
37 : class LogitCalculator : public RouteCostCalculator<R, E, V> {
38 : public:
39 : /// Constructor
40 49 : LogitCalculator(const double beta, const double gamma,
41 49 : const double theta) : myBeta(beta), myGamma(gamma), myTheta(theta) {}
42 :
43 : /// Destructor
44 49 : virtual ~LogitCalculator() {}
45 :
46 27813 : void setCosts(R* route, const double costs, const bool /* isActive */) const {
47 27813 : route->setCosts(costs);
48 27813 : }
49 :
50 : /** @brief calculate the probabilities in the logit model */
51 11727 : void calculateProbabilities(std::vector<R*> alternatives, const V* const veh, const SUMOTime time) {
52 11727 : const double theta = myTheta >= 0 ? myTheta : getThetaForCLogit(alternatives);
53 12595 : const double beta = myBeta >= 0 ? myBeta : getBetaForCLogit(alternatives);
54 11727 : const double t = STEPS2TIME(time);
55 11727 : if (beta > 0) {
56 : // calculate commonalities
57 39545 : for (const R* const pR : alternatives) {
58 : double lengthR = 0;
59 : const std::vector<const E*>& edgesR = pR->getEdgeVector();
60 183810 : for (const E* const edge : edgesR) {
61 : //@todo we should use costs here
62 155988 : lengthR += edge->getTravelTime(veh, t);
63 : }
64 : double overlapSum = 0;
65 99022 : for (const R* const pS : alternatives) {
66 : double overlapLength = 0.;
67 : double lengthS = 0;
68 474355 : for (const E* const edge : pS->getEdgeVector()) {
69 403155 : lengthS += edge->getTravelTime(veh, t);
70 403155 : if (std::find(edgesR.begin(), edgesR.end(), edge) != edgesR.end()) {
71 289230 : overlapLength += edge->getTravelTime(veh, t);
72 : }
73 : }
74 71200 : overlapSum += pow(overlapLength / sqrt(lengthR * lengthS), myGamma);
75 : }
76 27822 : myCommonalities[pR] = beta * log(overlapSum);
77 : }
78 : }
79 39565 : for (R* const pR : alternatives) {
80 : double weightedSum = 0;
81 99102 : for (const R* const pS : alternatives) {
82 71264 : weightedSum += exp(theta * (pR->getCosts() - pS->getCosts() + myCommonalities[pR] - myCommonalities[pS]));
83 : }
84 27838 : pR->setProbability(1. / weightedSum);
85 : }
86 11727 : }
87 :
88 :
89 : private:
90 : /** @brief calculate the scaling factor in the logit model */
91 : double getBetaForCLogit(const std::vector<R*> alternatives) const {
92 : double min = std::numeric_limits<double>::max();
93 2220 : for (const R* const pR : alternatives) {
94 1352 : const double cost = pR->getCosts() / 3600.;
95 1352 : if (cost < min) {
96 : min = cost;
97 : }
98 : }
99 : return min;
100 : }
101 :
102 : /** @brief calculate the scaling factor in the logit model */
103 11648 : 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 39325 : for (const R* const pR : alternatives) {
109 27677 : const double cost = pR->getCosts() / 3600.;
110 27677 : sum += cost;
111 27677 : if (cost < min) {
112 : min = cost;
113 : }
114 : }
115 11648 : const double meanCost = sum / double(alternatives.size());
116 39325 : for (const R* const pR : alternatives) {
117 27677 : diff += pow(pR->getCosts() / 3600. - meanCost, 2);
118 : }
119 11648 : const double cvCost = sqrt(diff / double(alternatives.size())) / meanCost;
120 : // @todo re-evaluate function
121 11648 : if (cvCost > 0) { // all Magic numbers from Lohse book, original says this should be cvCost > 0.04
122 10448 : return 3.1415926535897932384626433832795 / (sqrt(6.) * cvCost * (min + 1.1)) / 3600.;
123 : }
124 : return 1. / 3600.;
125 : }
126 :
127 :
128 : private:
129 : /// @brief logit beta - value
130 : const double myBeta;
131 :
132 : /// @brief logit gamma - value
133 : const double myGamma;
134 :
135 : /// @brief logit theta - value
136 : const double myTheta;
137 :
138 : /// @brief The route commonality factors for c-logit
139 : std::map<const R*, double> myCommonalities;
140 :
141 : private:
142 : /** @brief invalidated assignment operator */
143 : LogitCalculator& operator=(const LogitCalculator& s);
144 :
145 : };
|