Path: blob/main/src/activitygen/activities/AGActivities.cpp
169678 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2010-2025 German Aerospace Center (DLR) and others.3// activitygen module4// Copyright 2010 TUM (Technische Universitaet Muenchen, http://www.tum.de/)5// This program and the accompanying materials are made available under the6// terms of the Eclipse Public License 2.0 which is available at7// https://www.eclipse.org/legal/epl-2.0/8// This Source Code may also be made available under the following Secondary9// Licenses when the conditions for such availability set forth in the Eclipse10// Public License 2.0 are satisfied: GNU General Public License, version 211// or later which is available at12// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html13// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later14/****************************************************************************/15/// @file AGActivities.cpp16/// @author Piotr Woznica17/// @author Daniel Krajzewicz18/// @author Walter Bamberger19/// @author Michael Behrisch20/// @date July 201021///22// Main class that manages activities taken in account and generates the23// inhabitants' trip list.24/****************************************************************************/25#include <config.h>2627#include <sstream>28#include <utils/common/RandHelper.h>29#include <activitygen/city/AGTime.h>30#include "AGWorkAndSchool.h"31#include "AGFreeTime.h"32#include "AGActivities.h"3334#define REBUILD_ITERATION_LIMIT 2353637// ===========================================================================38// method definitions39// ===========================================================================40void41AGActivities::addTrip(AGTrip t, std::list<AGTrip>* tripSet) {42tripSet->push_back(t);43}4445void46AGActivities::addTrips(std::list<AGTrip> t, std::list<AGTrip>* tripSet) {47std::list<AGTrip>::iterator it;48for (it = t.begin(); it != t.end(); ++it) {49tripSet->push_back(*it);50}51}5253void54AGActivities::generateActivityTrips() {55int numbErr;56/**57* trips due to public transportation58*/59numbErr = 0;60std::list<AGBusLine>::iterator itBL;61for (itBL = myCity->busLines.begin(); itBL != myCity->busLines.end(); ++itBL) {62if (! generateBusTraffic(*itBL)) {63++numbErr;64}65}66if (numbErr != 0) {67std::cerr << "ERROR: " << numbErr << " bus lines couldn't been completely generated ( " << (float)numbErr * 100.0 / (float)myCity->busLines.size() << "% )..." << std::endl;68} else {69std::cout << "no problem during bus line trip generation..." << std::endl;70}7172std::cout << "after public transportation: " << trips.size() << std::endl;73/**74* trips due to activities in the city75* @NOTICE: includes people working in work positions out of the city76*/77numbErr = 0;78std::list<AGHousehold>::iterator itHH;79for (itHH = myCity->households.begin(); itHH != myCity->households.end(); ++itHH) {80if (! generateTrips(*itHH)) {81++numbErr;82}83}84if (numbErr != 0) {85std::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;86} else {87std::cout << "no problem during households' trips generation..." << std::endl;88}8990std::cout << "after household activities: " << trips.size() << std::endl;91/**92* trips due to incoming and outgoing traffic93* @WARNING: the outgoing traffic is already done: households in which someone works on a work position that is out of the city.94*/95if (! generateInOutTraffic()) {96std::cerr << "ERROR while generating in/Out traffic..." << std::endl;97} else {98std::cout << "no problem during in/out traffic generation..." << std::endl;99}100101std::cout << "after incoming/outgoing traffic: " << trips.size() << std::endl;102/**103* random traffic trips104* @NOTICE: this includes uniform and proportional random traffic105*/106if (! generateRandomTraffic()) {107std::cerr << "ERROR while generating random traffic..." << std::endl;108} else {109std::cout << "no problem during random traffic generation..." << std::endl;110}111112std::cout << "after random traffic: " << trips.size() << std::endl;113}114115bool116AGActivities::generateTrips(AGHousehold& hh) {117int iteration = 0;118bool generated = false;119std::list<AGTrip> temporaTrips;120while (!generated && iteration < REBUILD_ITERATION_LIMIT) {121if (!temporaTrips.empty()) {122temporaTrips.clear();123}124// Work and school activities125AGWorkAndSchool ws(&hh, &(myCity->statData), &temporaTrips);126generated = ws.generateTrips();127if (!generated) {128hh.regenerate();129++iteration;130continue;131}132addTrips(ws.getPartialActivityTrips(), &temporaTrips);133134// free time activities135AGFreeTime ft(&hh, &(myCity->statData), &temporaTrips, nbrDays);136generated = ft.generateTrips();137if (!generated) {138hh.regenerate();139++iteration;140continue;141}142addTrips(ft.getPartialActivityTrips(), &temporaTrips);143//cout << "after this hh: " << temporaTrips.size() << " we have: " << trips.size() << endl;144//trips of all activities generated:145addTrips(temporaTrips, &trips);146}147return generated;148}149150bool151AGActivities::generateBusTraffic(AGBusLine bl) {152std::list<AGBus>::iterator itB;153std::list<AGPosition>::iterator itS;154/**155* Buses in the first direction156*/157for (itB = bl.buses.begin(); itB != bl.buses.end(); ++itB) {158if (bl.stations.size() < 1) {159return false;160}161AGTrip t(bl.stations.front(), bl.stations.back(), *itB, itB->getDeparture());162for (itS = bl.stations.begin(); itS != bl.stations.end(); ++itS) {163if (*itS == t.getDep() || *itS == t.getArr()) {164continue;165}166t.addLayOver(*itS);167}168trips.push_back(t);169}170/**171* Buses in the return direction172*/173//verify that buses return back to the beginning174if (bl.revStations.empty()) {175return true; //in this case, no return way: everything is ok.176}177for (itB = bl.revBuses.begin(); itB != bl.revBuses.end(); ++itB) {178if (bl.revStations.size() < 1) {179return false;180}181AGTrip t(bl.revStations.front(), bl.revStations.back(), *itB, itB->getDeparture());182for (itS = bl.revStations.begin(); itS != bl.revStations.end(); ++itS) {183if (*itS == t.getDep() || *itS == t.getArr()) {184continue;185}186t.addLayOver(*itS);187}188trips.push_back(t);189}190return true;191}192193bool194AGActivities::generateInOutTraffic() {195/**196* outgoing traffic already done by generateTrips():197* people who work out of the city.198* Here are people from outside the city coming to work.199*/200if (myCity->peopleIncoming.empty()) {201return true;202}203if (myCity->cityGates.empty()) {204return false;205}206int num = 1;207std::list<AGAdult>::iterator itA;208209for (itA = myCity->peopleIncoming.begin(); itA != myCity->peopleIncoming.end(); ++itA) {210int posi = myCity->statData.getRandomCityGateByIncoming();211std::string nom(generateName(num, "carIn"));212AGTrip wayTrip(myCity->cityGates[posi], itA->getWorkPosition().getPosition(), nom, itA->getWorkPosition().getOpening());213//now we put the estimated time of entrance in the city.214wayTrip.setDepTime(wayTrip.estimateDepTime(wayTrip.getTime(), myCity->statData.speedTimePerKm));215AGTrip retTrip(itA->getWorkPosition().getPosition(), myCity->cityGates[posi], nom, itA->getWorkPosition().getClosing());216trips.push_back(wayTrip);217trips.push_back(retTrip);218++num;219}220return true;221}222223std::string224AGActivities::generateName(int i, std::string prefix) {225std::ostringstream os;226os << i;227return prefix + os.str();228}229230bool231AGActivities::generateRandomTraffic() {232//total number of trips during the whole simulation233int totalTrips = 0, ttOneDayTrips = 0, ttDailyTrips = 0;234std::list<AGTrip>::iterator it;235for (it = trips.begin(); it != trips.end(); ++it) {236if (it->isDaily()) {237++ttDailyTrips;238} else {239++ttOneDayTrips;240}241}242totalTrips = ttOneDayTrips + ttDailyTrips * nbrDays;243//TESTS244std::cout << "Before Random traffic generation (days are still entire):" << std::endl;245std::cout << "- Total number of trips: " << totalTrips << std::endl;246std::cout << "- Total daily trips: " << ttDailyTrips << std::endl;247std::cout << "- Total one-day trips: " << ttOneDayTrips << std::endl;248//END OF TESTS249250//random uniform distribution:251int nbrRandUni = (int)((float)totalTrips * myCity->statData.uniformRandomTrafficRate / (1.0f - myCity->statData.uniformRandomTrafficRate));252//TESTS253std::cout << "added uniform random trips: " << nbrRandUni << std::endl;254//END OF TESTS255for (int i = 0; i < nbrRandUni; ++i) {256AGPosition dep(myCity->getRandomStreet());257AGPosition arr(myCity->getRandomStreet());258AGTime depTime(RandHelper::rand(nbrDays * 86400));259AGTrip rdtr(dep, arr, generateName(i, "randUni"), depTime.getTime() % 86400, depTime.getDay() + 1);260rdtr.setType("random");261trips.push_back(rdtr);262}263264//random proportional distribution:265//float proportionalPercentage = 0.05f;266//TODO generate a proportionally distributed random traffic267268return true;269}270271272/****************************************************************************/273274275