Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4 : // activitygen module
5 : // Copyright 2010 TUM (Technische Universitaet Muenchen, http://www.tum.de/)
6 : // This program and the accompanying materials are made available under the
7 : // terms of the Eclipse Public License 2.0 which is available at
8 : // https://www.eclipse.org/legal/epl-2.0/
9 : // This Source Code may also be made available under the following Secondary
10 : // Licenses when the conditions for such availability set forth in the Eclipse
11 : // Public License 2.0 are satisfied: GNU General Public License, version 2
12 : // or later which is available at
13 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
14 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
15 : /****************************************************************************/
16 : /// @file AGDataAndStatistics.cpp
17 : /// @author Piotr Woznica
18 : /// @author Daniel Krajzewicz
19 : /// @author Michael Behrisch
20 : /// @author Walter Bamberger
21 : /// @date July 2010
22 : ///
23 : // Contains various data, statistical values and functions from input used
24 : // by various objects
25 : /****************************************************************************/
26 : #include <config.h>
27 :
28 : #include "AGDataAndStatistics.h"
29 : #include <utils/common/RandHelper.h>
30 : #include <cmath>
31 : #include <iomanip>
32 : #define LIMIT_CHILDREN_NUMBER 3
33 :
34 :
35 : // ===========================================================================
36 : // method definitions
37 : // ===========================================================================
38 : AGDataAndStatistics&
39 10 : AGDataAndStatistics::getDataAndStatistics() {
40 10 : static AGDataAndStatistics ds;
41 10 : return ds;
42 : }
43 :
44 : int
45 0 : AGDataAndStatistics::getRandom(int n, int m) {
46 0 : if (m < n) {
47 : return 0;
48 : }
49 0 : int num = RandHelper::rand(m - n);
50 0 : num += n;
51 0 : return num;
52 : }
53 :
54 : int
55 4805 : AGDataAndStatistics::getRandomPopDistributed(int n, int m) {
56 4805 : if (m < n || n >= limitEndAge) {
57 : return -1;
58 : }
59 4805 : if (m > limitEndAge) {
60 : m = limitEndAge;
61 : }
62 4805 : const double alea = RandHelper::rand(getPropYoungerThan(n), getPropYoungerThan(m));
63 125588 : for (int a = n; a < m; ++a) {
64 125588 : if (alea < getPropYoungerThan(a + 1)) {
65 4805 : return a;
66 : }
67 : }
68 : return -1;
69 : }
70 :
71 : int
72 1367 : AGDataAndStatistics::getPoissonsNumberOfChildren(double mean) {
73 1367 : double alea = RandHelper::rand();
74 : double cumul = 0;
75 2127 : for (int nbr = 0; nbr < LIMIT_CHILDREN_NUMBER; ++nbr) {
76 2119 : cumul += poisson(mean, nbr);
77 2119 : if (cumul > alea) {
78 1359 : return nbr;
79 : }
80 : }
81 : return LIMIT_CHILDREN_NUMBER;
82 : }
83 :
84 : double
85 2119 : AGDataAndStatistics::poisson(double mean, int occ) {
86 2119 : return exp(-mean) * pow(mean, occ) / (double)factorial(occ);
87 : }
88 :
89 : int
90 2119 : AGDataAndStatistics::factorial(int fact) {
91 3029 : if (fact > 0) {
92 910 : return fact * factorial(fact - 1);
93 : }
94 : return 1;
95 : }
96 :
97 : void
98 16 : AGDataAndStatistics::consolidateStat() {
99 16 : normalizeMapProb(&beginWorkHours);
100 16 : normalizeMapProb(&endWorkHours);
101 16 : normalizeMapProb(&population);
102 16 : normalizeMapProb(&incoming);
103 16 : normalizeMapProb(&outgoing);
104 16 : limitEndAge = population.rbegin()->first;
105 :
106 16 : oldAgeHhProb = (double)getPeopleOlderThan(limitAgeRetirement) / (double)getPeopleOlderThan(limitAgeChildren);
107 16 : secondPersProb = (double)(getPeopleOlderThan(limitAgeChildren) - households) / (double)households;
108 16 : meanNbrChildren = (double)getPeopleYoungerThan(limitAgeChildren) / ((1 - oldAgeHhProb) * (double)households);
109 : //cout << " --> oldAgeHhProb = " << setprecision(3) << oldAgeHhProb << " - retAge? " << getPeopleOlderThan(limitAgeRetirement) << " adAge? " << getPeopleOlderThan(limitAgeChildren) << endl;
110 : //cout << " --> secondPersProb = " << setprecision(3) << secondPersProb << " - adAge? " << getPeopleOlderThan(limitAgeChildren) << " hh?" << households << endl;
111 : //cout << " --> meanNbrChildren = " << setprecision(3) << meanNbrChildren << " - chAge? " << getPeopleYoungerThan(limitAgeChildren) << endl;
112 16 : }
113 :
114 : double
115 135386 : AGDataAndStatistics::getPropYoungerThan(int age) {
116 : std::map<int, double>::iterator it;
117 : double sum = 0;
118 : int previousAge = 0;
119 : double prop = 0;
120 :
121 234300 : for (it = population.begin(); it != population.end(); ++it) {
122 233540 : if (it->first < age) {
123 96634 : sum += it->second;
124 136906 : } else if (it->first >= age && previousAge < age) {
125 134626 : prop = ((double)(age - previousAge) / (double)(it->first - previousAge));
126 134626 : sum += prop * it->second;
127 134626 : break;
128 : }
129 : previousAge = it->first;
130 : }
131 135386 : return sum;
132 : }
133 :
134 : int
135 188 : AGDataAndStatistics::getPeopleYoungerThan(int age) {
136 188 : return (int)((double)inhabitants * getPropYoungerThan(age) + .5);
137 : }
138 :
139 : int
140 127 : AGDataAndStatistics::getPeopleOlderThan(int age) {
141 127 : return (inhabitants - getPeopleYoungerThan(age));
142 : }
143 :
144 : void
145 80 : AGDataAndStatistics::normalizeMapProb(std::map<int, double>* myMap) {
146 : double sum = 0;
147 : std::map<int, double>::iterator it;
148 220 : for (it = myMap->begin(); it != myMap->end(); ++it) {
149 140 : sum += it->second;
150 : }
151 80 : if (sum == 0) {
152 : return;
153 : }
154 194 : for (it = myMap->begin(); it != myMap->end(); ++it) {
155 140 : it->second = it->second / sum;
156 : }
157 : }
158 :
159 : double
160 0 : AGDataAndStatistics::getInverseExpRandomValue(double mean, double maxVar) {
161 0 : if (maxVar <= 0) {
162 : return mean;
163 : }
164 : double p = RandHelper::rand(static_cast<double>(0.0001), static_cast<double>(1));
165 : //we have to scale the distribution because maxVar is different from INF
166 0 : double scale = exp((-1) * maxVar);
167 : //new p: scaled
168 0 : p = p * (1 - scale) + scale; // p = [scale; 1) ==> (1-p) = (0; 1-scale]
169 :
170 0 : double variation = (-1) * log(p);
171 : //decide the side of the mean value
172 0 : if (RandHelper::rand(1000) < 500) {
173 0 : return mean + variation;
174 : } else {
175 0 : return mean - variation;
176 : }
177 :
178 : }
179 :
180 : int
181 400 : AGDataAndStatistics::getRandomCityGateByIncoming() {
182 400 : double alea = RandHelper::rand();
183 : double total = 0;
184 : std::map<int, double>::iterator it;
185 596 : for (it = incoming.begin(); it != incoming.end(); ++it) {
186 596 : total += it->second;
187 596 : if (alea < total) {
188 400 : return it->first;
189 : }
190 : }
191 : std::cout << "ERROR: incoming at city gates not normalized" << std::endl;
192 : return 0;
193 : }
194 :
195 : int
196 240 : AGDataAndStatistics::getRandomCityGateByOutgoing() {
197 240 : double alea = RandHelper::rand();
198 : double total = 0;
199 : std::map<int, double>::iterator it;
200 354 : for (it = outgoing.begin(); it != outgoing.end(); ++it) {
201 354 : total += it->second;
202 354 : if (alea < total) {
203 240 : return it->first;
204 : }
205 : }
206 : std::cout << "ERROR: outgoing at city gates not normalized" << std::endl;
207 : return 0;
208 : }
209 :
210 :
211 : /****************************************************************************/
|