LCOV - code coverage report
Current view: top level - src/activitygen/activities - AGActivities.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 84 97 86.6 %
Date: 2024-04-28 15:39:05 Functions: 7 8 87.5 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2010-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    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           0 : AGActivities::addTrip(AGTrip t, std::list<AGTrip>* tripSet) {
      43             :     tripSet->push_back(t);
      44           0 : }
      45             : 
      46             : void
      47        4516 : AGActivities::addTrips(std::list<AGTrip> t, std::list<AGTrip>* tripSet) {
      48             :     std::list<AGTrip>::iterator it;
      49        8184 :     for (it = t.begin(); it != t.end(); ++it) {
      50             :         tripSet->push_back(*it);
      51             :     }
      52        4516 : }
      53             : 
      54             : void
      55           9 : AGActivities::generateActivityTrips() {
      56             :     int numbErr;
      57             :     /**
      58             :      * trips due to public transportation
      59             :      */
      60             :     numbErr = 0;
      61             :     std::list<AGBusLine>::iterator itBL;
      62          20 :     for (itBL = myCity->busLines.begin(); itBL != myCity->busLines.end(); ++itBL) {
      63          11 :         if (! generateBusTraffic(*itBL)) {
      64           0 :             ++numbErr;
      65             :         }
      66             :     }
      67           9 :     if (numbErr != 0) {
      68           0 :         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        1514 :     for (itHH = myCity->households.begin(); itHH != myCity->households.end(); ++itHH) {
      81        1506 :         if (! generateTrips(*itHH)) {
      82           0 :             ++numbErr;
      83             :         }
      84             :     }
      85           8 :     if (numbErr != 0) {
      86           0 :         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           8 :     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           8 :     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           8 : }
     115             : 
     116             : bool
     117        1506 : AGActivities::generateTrips(AGHousehold& hh) {
     118             :     int iteration = 0;
     119             :     bool generated = false;
     120             :     std::list<AGTrip> temporaTrips;
     121        3011 :     while (!generated && iteration < REBUILD_ITERATION_LIMIT) {
     122        1506 :         if (!temporaTrips.empty()) {
     123             :             temporaTrips.clear();
     124             :         }
     125             :         // Work and school activities
     126        1506 :         AGWorkAndSchool ws(&hh, &(myCity->statData), &temporaTrips);
     127        1506 :         generated = ws.generateTrips();
     128        1506 :         if (!generated) {
     129           0 :             hh.regenerate();
     130           0 :             ++iteration;
     131           0 :             continue;
     132             :         }
     133        1506 :         addTrips(ws.getPartialActivityTrips(), &temporaTrips);
     134             : 
     135             :         // free time activities
     136        1506 :         AGFreeTime ft(&hh, &(myCity->statData), &temporaTrips, nbrDays);
     137        1506 :         generated = ft.generateTrips();
     138        1505 :         if (!generated) {
     139           0 :             hh.regenerate();
     140           0 :             ++iteration;
     141             :             continue;
     142             :         }
     143        1505 :         addTrips(ft.getPartialActivityTrips(), &temporaTrips);
     144             :         //cout << "after this hh: " << temporaTrips.size() << " we have: " << trips.size() << endl;
     145             :         //trips of all activities generated:
     146        3011 :         addTrips(temporaTrips, &trips);
     147        1506 :     }
     148        1505 :     return generated;
     149             : }
     150             : 
     151             : bool
     152          11 : 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         516 :     for (itB = bl.buses.begin(); itB != bl.buses.end(); ++itB) {
     159         505 :         if (bl.stations.size() < 1) {
     160           0 :             return false;
     161             :         }
     162        1010 :         AGTrip t(bl.stations.front(), bl.stations.back(), *itB, itB->getDeparture());
     163        4491 :         for (itS = bl.stations.begin(); itS != bl.stations.end(); ++itS) {
     164        7467 :             if (*itS == t.getDep() || *itS == t.getArr()) {
     165        1010 :                 continue;
     166             :             }
     167        2976 :             t.addLayOver(*itS);
     168             :         }
     169         505 :         trips.push_back(t);
     170         505 :     }
     171             :     /**
     172             :      * Buses in the return direction
     173             :      */
     174             :     //verify that buses return back to the beginning
     175          11 :     if (bl.revStations.empty()) {
     176             :         return true;    //in this case, no return way: everything is ok.
     177             :     }
     178         516 :     for (itB = bl.revBuses.begin(); itB != bl.revBuses.end(); ++itB) {
     179         505 :         if (bl.revStations.size() < 1) {
     180           0 :             return false;
     181             :         }
     182        1010 :         AGTrip t(bl.revStations.front(), bl.revStations.back(), *itB, itB->getDeparture());
     183        4491 :         for (itS = bl.revStations.begin(); itS != bl.revStations.end(); ++itS) {
     184        7467 :             if (*itS == t.getDep() || *itS == t.getArr()) {
     185        1010 :                 continue;
     186             :             }
     187        2976 :             t.addLayOver(*itS);
     188             :         }
     189         505 :         trips.push_back(t);
     190         505 :     }
     191             :     return true;
     192             : }
     193             : 
     194             : bool
     195           8 : 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           8 :     if (myCity->peopleIncoming.empty()) {
     202             :         return true;
     203             :     }
     204           3 :     if (myCity->cityGates.empty()) {
     205             :         return false;
     206             :     }
     207             :     int num = 1;
     208             :     std::list<AGAdult>::iterator itA;
     209             : 
     210         402 :     for (itA = myCity->peopleIncoming.begin(); itA != myCity->peopleIncoming.end(); ++itA) {
     211         400 :         int posi = myCity->statData.getRandomCityGateByIncoming();
     212         800 :         std::string nom(generateName(num, "carIn"));
     213         800 :         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         400 :         wayTrip.setDepTime(wayTrip.estimateDepTime(wayTrip.getTime(), myCity->statData.speedTimePerKm));
     216         800 :         AGTrip retTrip(itA->getWorkPosition().getPosition(), myCity->cityGates[posi], nom, itA->getWorkPosition().getClosing());
     217         400 :         trips.push_back(wayTrip);
     218             :         trips.push_back(retTrip);
     219         400 :         ++num;
     220         400 :     }
     221             :     return true;
     222             : }
     223             : 
     224             : std::string
     225        1925 : AGActivities::generateName(int i, std::string prefix) {
     226        1925 :     std::ostringstream os;
     227        1925 :     os << i;
     228        3850 :     return prefix + os.str();
     229        1925 : }
     230             : 
     231             : bool
     232           8 : 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        3404 :     for (it = trips.begin(); it != trips.end(); ++it) {
     237        3396 :         if (it->isDaily()) {
     238        2744 :             ++ttDailyTrips;
     239             :         } else {
     240         652 :             ++ttOneDayTrips;
     241             :         }
     242             :     }
     243           8 :     totalTrips = ttOneDayTrips + ttDailyTrips * nbrDays;
     244             :     //TESTS
     245             :     std::cout << "Before Random traffic generation (days are still entire):" << std::endl;
     246           8 :     std::cout << "- Total number of trips: " << totalTrips << std::endl;
     247           8 :     std::cout << "- Total daily trips: " << ttDailyTrips << std::endl;
     248           8 :     std::cout << "- Total one-day trips: " << ttOneDayTrips << std::endl;
     249             :     //END OF TESTS
     250             : 
     251             :     //random uniform distribution:
     252           8 :     int nbrRandUni = (int)((float)totalTrips * myCity->statData.uniformRandomTrafficRate / (1.0f - myCity->statData.uniformRandomTrafficRate));
     253             :     //TESTS
     254           8 :     std::cout << "added uniform random trips: " << nbrRandUni << std::endl;
     255             :     //END OF TESTS
     256        1533 :     for (int i = 0; i < nbrRandUni; ++i) {
     257        1525 :         AGPosition dep(myCity->getRandomStreet());
     258        1525 :         AGPosition arr(myCity->getRandomStreet());
     259        1525 :         AGTime depTime(RandHelper::rand(nbrDays * 86400));
     260        1525 :         AGTrip rdtr(dep, arr, generateName(i, "randUni"), depTime.getTime() % 86400, depTime.getDay() + 1);
     261        1525 :         rdtr.setType("random");
     262        1525 :         trips.push_back(rdtr);
     263        1525 :     }
     264             : 
     265             :     //random proportional distribution:
     266             :     //float proportionalPercentage = 0.05f;
     267             :     //TODO generate a proportionally distributed random traffic
     268             : 
     269           8 :     return true;
     270             : }
     271             : 
     272             : 
     273             : /****************************************************************************/

Generated by: LCOV version 1.14