Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/activitygen/activities/AGActivities.cpp
169678 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2010-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 AGActivities.cpp
17
/// @author Piotr Woznica
18
/// @author Daniel Krajzewicz
19
/// @author Walter Bamberger
20
/// @author Michael Behrisch
21
/// @date July 2010
22
///
23
// Main class that manages activities taken in account and generates the
24
// inhabitants' trip list.
25
/****************************************************************************/
26
#include <config.h>
27
28
#include <sstream>
29
#include <utils/common/RandHelper.h>
30
#include <activitygen/city/AGTime.h>
31
#include "AGWorkAndSchool.h"
32
#include "AGFreeTime.h"
33
#include "AGActivities.h"
34
35
#define REBUILD_ITERATION_LIMIT 2
36
37
38
// ===========================================================================
39
// method definitions
40
// ===========================================================================
41
void
42
AGActivities::addTrip(AGTrip t, std::list<AGTrip>* tripSet) {
43
tripSet->push_back(t);
44
}
45
46
void
47
AGActivities::addTrips(std::list<AGTrip> t, std::list<AGTrip>* tripSet) {
48
std::list<AGTrip>::iterator it;
49
for (it = t.begin(); it != t.end(); ++it) {
50
tripSet->push_back(*it);
51
}
52
}
53
54
void
55
AGActivities::generateActivityTrips() {
56
int numbErr;
57
/**
58
* trips due to public transportation
59
*/
60
numbErr = 0;
61
std::list<AGBusLine>::iterator itBL;
62
for (itBL = myCity->busLines.begin(); itBL != myCity->busLines.end(); ++itBL) {
63
if (! generateBusTraffic(*itBL)) {
64
++numbErr;
65
}
66
}
67
if (numbErr != 0) {
68
std::cerr << "ERROR: " << numbErr << " bus lines couldn't been completely generated ( " << (float)numbErr * 100.0 / (float)myCity->busLines.size() << "% )..." << std::endl;
69
} else {
70
std::cout << "no problem during bus line trip generation..." << std::endl;
71
}
72
73
std::cout << "after public transportation: " << trips.size() << std::endl;
74
/**
75
* trips due to activities in the city
76
* @NOTICE: includes people working in work positions out of the city
77
*/
78
numbErr = 0;
79
std::list<AGHousehold>::iterator itHH;
80
for (itHH = myCity->households.begin(); itHH != myCity->households.end(); ++itHH) {
81
if (! generateTrips(*itHH)) {
82
++numbErr;
83
}
84
}
85
if (numbErr != 0) {
86
std::cout << "WARNING: " << numbErr << " ( " << (float)numbErr * 100.0 / (float)myCity->households.size() << "% ) households' trips haven't been generated: would probably need more iterations for rebuilding..." << std::endl;
87
} else {
88
std::cout << "no problem during households' trips generation..." << std::endl;
89
}
90
91
std::cout << "after household activities: " << trips.size() << std::endl;
92
/**
93
* trips due to incoming and outgoing traffic
94
* @WARNING: the outgoing traffic is already done: households in which someone works on a work position that is out of the city.
95
*/
96
if (! generateInOutTraffic()) {
97
std::cerr << "ERROR while generating in/Out traffic..." << std::endl;
98
} else {
99
std::cout << "no problem during in/out traffic generation..." << std::endl;
100
}
101
102
std::cout << "after incoming/outgoing traffic: " << trips.size() << std::endl;
103
/**
104
* random traffic trips
105
* @NOTICE: this includes uniform and proportional random traffic
106
*/
107
if (! generateRandomTraffic()) {
108
std::cerr << "ERROR while generating random traffic..." << std::endl;
109
} else {
110
std::cout << "no problem during random traffic generation..." << std::endl;
111
}
112
113
std::cout << "after random traffic: " << trips.size() << std::endl;
114
}
115
116
bool
117
AGActivities::generateTrips(AGHousehold& hh) {
118
int iteration = 0;
119
bool generated = false;
120
std::list<AGTrip> temporaTrips;
121
while (!generated && iteration < REBUILD_ITERATION_LIMIT) {
122
if (!temporaTrips.empty()) {
123
temporaTrips.clear();
124
}
125
// Work and school activities
126
AGWorkAndSchool ws(&hh, &(myCity->statData), &temporaTrips);
127
generated = ws.generateTrips();
128
if (!generated) {
129
hh.regenerate();
130
++iteration;
131
continue;
132
}
133
addTrips(ws.getPartialActivityTrips(), &temporaTrips);
134
135
// free time activities
136
AGFreeTime ft(&hh, &(myCity->statData), &temporaTrips, nbrDays);
137
generated = ft.generateTrips();
138
if (!generated) {
139
hh.regenerate();
140
++iteration;
141
continue;
142
}
143
addTrips(ft.getPartialActivityTrips(), &temporaTrips);
144
//cout << "after this hh: " << temporaTrips.size() << " we have: " << trips.size() << endl;
145
//trips of all activities generated:
146
addTrips(temporaTrips, &trips);
147
}
148
return generated;
149
}
150
151
bool
152
AGActivities::generateBusTraffic(AGBusLine bl) {
153
std::list<AGBus>::iterator itB;
154
std::list<AGPosition>::iterator itS;
155
/**
156
* Buses in the first direction
157
*/
158
for (itB = bl.buses.begin(); itB != bl.buses.end(); ++itB) {
159
if (bl.stations.size() < 1) {
160
return false;
161
}
162
AGTrip t(bl.stations.front(), bl.stations.back(), *itB, itB->getDeparture());
163
for (itS = bl.stations.begin(); itS != bl.stations.end(); ++itS) {
164
if (*itS == t.getDep() || *itS == t.getArr()) {
165
continue;
166
}
167
t.addLayOver(*itS);
168
}
169
trips.push_back(t);
170
}
171
/**
172
* Buses in the return direction
173
*/
174
//verify that buses return back to the beginning
175
if (bl.revStations.empty()) {
176
return true; //in this case, no return way: everything is ok.
177
}
178
for (itB = bl.revBuses.begin(); itB != bl.revBuses.end(); ++itB) {
179
if (bl.revStations.size() < 1) {
180
return false;
181
}
182
AGTrip t(bl.revStations.front(), bl.revStations.back(), *itB, itB->getDeparture());
183
for (itS = bl.revStations.begin(); itS != bl.revStations.end(); ++itS) {
184
if (*itS == t.getDep() || *itS == t.getArr()) {
185
continue;
186
}
187
t.addLayOver(*itS);
188
}
189
trips.push_back(t);
190
}
191
return true;
192
}
193
194
bool
195
AGActivities::generateInOutTraffic() {
196
/**
197
* outgoing traffic already done by generateTrips():
198
* people who work out of the city.
199
* Here are people from outside the city coming to work.
200
*/
201
if (myCity->peopleIncoming.empty()) {
202
return true;
203
}
204
if (myCity->cityGates.empty()) {
205
return false;
206
}
207
int num = 1;
208
std::list<AGAdult>::iterator itA;
209
210
for (itA = myCity->peopleIncoming.begin(); itA != myCity->peopleIncoming.end(); ++itA) {
211
int posi = myCity->statData.getRandomCityGateByIncoming();
212
std::string nom(generateName(num, "carIn"));
213
AGTrip wayTrip(myCity->cityGates[posi], itA->getWorkPosition().getPosition(), nom, itA->getWorkPosition().getOpening());
214
//now we put the estimated time of entrance in the city.
215
wayTrip.setDepTime(wayTrip.estimateDepTime(wayTrip.getTime(), myCity->statData.speedTimePerKm));
216
AGTrip retTrip(itA->getWorkPosition().getPosition(), myCity->cityGates[posi], nom, itA->getWorkPosition().getClosing());
217
trips.push_back(wayTrip);
218
trips.push_back(retTrip);
219
++num;
220
}
221
return true;
222
}
223
224
std::string
225
AGActivities::generateName(int i, std::string prefix) {
226
std::ostringstream os;
227
os << i;
228
return prefix + os.str();
229
}
230
231
bool
232
AGActivities::generateRandomTraffic() {
233
//total number of trips during the whole simulation
234
int totalTrips = 0, ttOneDayTrips = 0, ttDailyTrips = 0;
235
std::list<AGTrip>::iterator it;
236
for (it = trips.begin(); it != trips.end(); ++it) {
237
if (it->isDaily()) {
238
++ttDailyTrips;
239
} else {
240
++ttOneDayTrips;
241
}
242
}
243
totalTrips = ttOneDayTrips + ttDailyTrips * nbrDays;
244
//TESTS
245
std::cout << "Before Random traffic generation (days are still entire):" << std::endl;
246
std::cout << "- Total number of trips: " << totalTrips << std::endl;
247
std::cout << "- Total daily trips: " << ttDailyTrips << std::endl;
248
std::cout << "- Total one-day trips: " << ttOneDayTrips << std::endl;
249
//END OF TESTS
250
251
//random uniform distribution:
252
int nbrRandUni = (int)((float)totalTrips * myCity->statData.uniformRandomTrafficRate / (1.0f - myCity->statData.uniformRandomTrafficRate));
253
//TESTS
254
std::cout << "added uniform random trips: " << nbrRandUni << std::endl;
255
//END OF TESTS
256
for (int i = 0; i < nbrRandUni; ++i) {
257
AGPosition dep(myCity->getRandomStreet());
258
AGPosition arr(myCity->getRandomStreet());
259
AGTime depTime(RandHelper::rand(nbrDays * 86400));
260
AGTrip rdtr(dep, arr, generateName(i, "randUni"), depTime.getTime() % 86400, depTime.getDay() + 1);
261
rdtr.setType("random");
262
trips.push_back(rdtr);
263
}
264
265
//random proportional distribution:
266
//float proportionalPercentage = 0.05f;
267
//TODO generate a proportionally distributed random traffic
268
269
return true;
270
}
271
272
273
/****************************************************************************/
274
275