Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/activitygen/city/AGDataAndStatistics.cpp
169678 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 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
AGDataAndStatistics::getDataAndStatistics() {
40
static AGDataAndStatistics ds;
41
return ds;
42
}
43
44
int
45
AGDataAndStatistics::getRandom(int n, int m) {
46
if (m < n) {
47
return 0;
48
}
49
int num = RandHelper::rand(m - n);
50
num += n;
51
return num;
52
}
53
54
int
55
AGDataAndStatistics::getRandomPopDistributed(int n, int m) {
56
if (m < n || n >= limitEndAge) {
57
return -1;
58
}
59
if (m > limitEndAge) {
60
m = limitEndAge;
61
}
62
const double alea = RandHelper::rand(getPropYoungerThan(n), getPropYoungerThan(m));
63
for (int a = n; a < m; ++a) {
64
if (alea < getPropYoungerThan(a + 1)) {
65
return a;
66
}
67
}
68
return -1;
69
}
70
71
int
72
AGDataAndStatistics::getPoissonsNumberOfChildren(double mean) {
73
double alea = RandHelper::rand();
74
double cumul = 0;
75
for (int nbr = 0; nbr < LIMIT_CHILDREN_NUMBER; ++nbr) {
76
cumul += poisson(mean, nbr);
77
if (cumul > alea) {
78
return nbr;
79
}
80
}
81
return LIMIT_CHILDREN_NUMBER;
82
}
83
84
double
85
AGDataAndStatistics::poisson(double mean, int occ) {
86
return exp(-mean) * pow(mean, occ) / (double)factorial(occ);
87
}
88
89
int
90
AGDataAndStatistics::factorial(int fact) {
91
if (fact > 0) {
92
return fact * factorial(fact - 1);
93
}
94
return 1;
95
}
96
97
void
98
AGDataAndStatistics::consolidateStat() {
99
normalizeMapProb(&beginWorkHours);
100
normalizeMapProb(&endWorkHours);
101
normalizeMapProb(&population);
102
normalizeMapProb(&incoming);
103
normalizeMapProb(&outgoing);
104
limitEndAge = population.rbegin()->first;
105
106
oldAgeHhProb = (double)getPeopleOlderThan(limitAgeRetirement) / (double)getPeopleOlderThan(limitAgeChildren);
107
secondPersProb = (double)(getPeopleOlderThan(limitAgeChildren) - households) / (double)households;
108
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
}
113
114
double
115
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
for (it = population.begin(); it != population.end(); ++it) {
122
if (it->first < age) {
123
sum += it->second;
124
} else if (it->first >= age && previousAge < age) {
125
prop = ((double)(age - previousAge) / (double)(it->first - previousAge));
126
sum += prop * it->second;
127
break;
128
}
129
previousAge = it->first;
130
}
131
return sum;
132
}
133
134
int
135
AGDataAndStatistics::getPeopleYoungerThan(int age) {
136
return (int)((double)inhabitants * getPropYoungerThan(age) + .5);
137
}
138
139
int
140
AGDataAndStatistics::getPeopleOlderThan(int age) {
141
return (inhabitants - getPeopleYoungerThan(age));
142
}
143
144
void
145
AGDataAndStatistics::normalizeMapProb(std::map<int, double>* myMap) {
146
double sum = 0;
147
std::map<int, double>::iterator it;
148
for (it = myMap->begin(); it != myMap->end(); ++it) {
149
sum += it->second;
150
}
151
if (sum == 0) {
152
return;
153
}
154
for (it = myMap->begin(); it != myMap->end(); ++it) {
155
it->second = it->second / sum;
156
}
157
}
158
159
double
160
AGDataAndStatistics::getInverseExpRandomValue(double mean, double maxVar) {
161
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
double scale = exp((-1) * maxVar);
167
//new p: scaled
168
p = p * (1 - scale) + scale; // p = [scale; 1) ==> (1-p) = (0; 1-scale]
169
170
double variation = (-1) * log(p);
171
//decide the side of the mean value
172
if (RandHelper::rand(1000) < 500) {
173
return mean + variation;
174
} else {
175
return mean - variation;
176
}
177
178
}
179
180
int
181
AGDataAndStatistics::getRandomCityGateByIncoming() {
182
double alea = RandHelper::rand();
183
double total = 0;
184
std::map<int, double>::iterator it;
185
for (it = incoming.begin(); it != incoming.end(); ++it) {
186
total += it->second;
187
if (alea < total) {
188
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
AGDataAndStatistics::getRandomCityGateByOutgoing() {
197
double alea = RandHelper::rand();
198
double total = 0;
199
std::map<int, double>::iterator it;
200
for (it = outgoing.begin(); it != outgoing.end(); ++it) {
201
total += it->second;
202
if (alea < total) {
203
return it->first;
204
}
205
}
206
std::cout << "ERROR: outgoing at city gates not normalized" << std::endl;
207
return 0;
208
}
209
210
211
/****************************************************************************/
212
213