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

            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 2.0-1