LCOV - code coverage report
Current view: top level - src/activitygen/activities - AGFreeTime.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 101 101
Test Date: 2024-11-22 15:46:21 Functions: 100.0 % 9 9

            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    AGFreeTime.cpp
      17              : /// @author  Piotr Woznica
      18              : /// @author  Daniel Krajzewicz
      19              : /// @author  Walter Bamberger
      20              : /// @author  Michael Behrisch
      21              : /// @date    July 2010
      22              : ///
      23              : // Generates trips related to after-work activities
      24              : // like visiting the family or party.
      25              : /****************************************************************************/
      26              : #include <config.h>
      27              : 
      28              : #include <cmath>
      29              : #include <utils/common/RandHelper.h>
      30              : #include <utils/common/StdDefs.h>
      31              : #include <activitygen/city/AGCity.h>
      32              : #include <activitygen/city/AGTime.h>
      33              : #include "AGFreeTime.h"
      34              : 
      35              : 
      36              : // ===========================================================================
      37              : // static member definitions
      38              : // ===========================================================================
      39              : const int AGFreeTime::DAY = 1;
      40              : const int AGFreeTime::EVENING = 2;
      41              : const int AGFreeTime::NIGHT = 4;
      42              : 
      43              : const int AGFreeTime::TB_DAY = AGTime(0, 8, 0).getTime();
      44              : const int AGFreeTime::TE_DAY = AGTime(0, 18, 0).getTime();
      45              : const int AGFreeTime::TB_EVENING = AGTime(0, 19, 0).getTime();
      46              : const int AGFreeTime::TE_EVENING = AGTime(0, 23, 59).getTime();
      47              : const int AGFreeTime::TB_NIGHT = AGTime(0, 23, 0).getTime();
      48              : const int AGFreeTime::TE_NIGHT = AGTime(1, 5, 0).getTime();
      49              : 
      50              : 
      51              : // ===========================================================================
      52              : // method definitions
      53              : // ===========================================================================
      54              : int
      55         3011 : AGFreeTime::decideTypeOfTrip() {
      56         3011 :     if (myHousehold->getAdults().front().decide(freqOut)) {
      57              :         int num_poss = 0; //(possibleType % 2) + (possibleType / 4) + ((possibleType / 2) % 2);
      58          454 :         if (possibleType & DAY) {
      59              :             ++num_poss;
      60              :         }
      61          454 :         if (possibleType & EVENING) {
      62          454 :             ++num_poss;
      63              :         }
      64          454 :         if (possibleType & NIGHT) {
      65           94 :             ++num_poss;
      66              :         }
      67              : 
      68          454 :         if (num_poss == 0) {
      69              :             return 0;
      70              :         }
      71          454 :         double alea = RandHelper::rand(); //(float)(rand() % 1000) / 1000.0;
      72          454 :         int decision = (int)floor(alea * (double)num_poss);
      73              : 
      74          454 :         if (possibleType & DAY) {
      75          122 :             if (decision == 0) {
      76              :                 return DAY;
      77              :             } else {
      78           58 :                 --decision;
      79              :             }
      80              :         }
      81          390 :         if (possibleType & EVENING) {
      82          390 :             if (decision == 0) {
      83              :                 return EVENING;
      84              :             } else {
      85           50 :                 --decision;
      86              :             }
      87              :         }
      88           50 :         if (possibleType & NIGHT) {
      89           50 :             if (decision == 0) {
      90              :                 return NIGHT;
      91              :             }
      92              :         }
      93              :     }
      94              :     return 0;
      95              : }
      96              : 
      97              : int
      98         1506 : AGFreeTime::possibleTypeOfTrip() {
      99              :     int val = 0;
     100         1506 :     if (myHousehold->getAdults().front().getAge() >= myStatData->limitAgeRetirement && tReady == 0) {
     101              :         val += DAY + EVENING;
     102              :     } else {
     103         1072 :         if (myHousehold->getPeopleNbr() > myHousehold->getAdultNbr()) {
     104              :             val += NIGHT;
     105              :         }
     106              : 
     107              :         std::list<AGAdult>::const_iterator itA;
     108              :         bool noBodyWorks = true;
     109         2799 :         for (itA = myHousehold->getAdults().begin(); itA != myHousehold->getAdults().end(); ++itA) {
     110         1727 :             if (itA->isWorking()) {
     111              :                 noBodyWorks = false;
     112              :             }
     113              :         }
     114         1072 :         if (noBodyWorks) {
     115           25 :             val += DAY;
     116              :         }
     117              : 
     118         1072 :         if (tReady < AGTime(0, 22, 0).getTime()) {
     119         1072 :             val += EVENING;
     120              :         }
     121              :     }
     122         1506 :     return val;
     123              : }
     124              : 
     125              : bool
     126           64 : AGFreeTime::typeFromHomeDay(int day) {
     127           64 :     int backHome = whenBackHomeThisDay(day);
     128           64 :     if (myHousehold->getCars().empty()) {
     129              :         return true;
     130              :     }
     131           51 :     AGPosition destination(myHousehold->getTheCity()->getRandomStreet());
     132           50 :     int depTime = randomTimeBetween(MAX2(backHome, TB_DAY), (TB_DAY + TE_DAY) / 2);
     133           50 :     int arrTime = this->arrHour(myHousehold->getPosition(), destination, depTime);
     134           50 :     int retTime = randomTimeBetween(arrTime, TE_DAY);
     135           50 :     if (depTime < 0 || retTime < 0) {
     136              :         return true;    // not enough time during the day
     137              :     }
     138           50 :     AGTrip depTrip(myHousehold->getPosition(), destination, myHousehold->getCars().front().getName(), depTime, day);
     139           50 :     AGTrip retTrip(destination, myHousehold->getPosition(), myHousehold->getCars().front().getName(), retTime, day);
     140              : 
     141           50 :     myPartialActivityTrips.push_back(depTrip);
     142              :     myPartialActivityTrips.push_back(retTrip);
     143              :     return true;
     144           50 : }
     145              : 
     146              : bool
     147          340 : AGFreeTime::typeFromHomeEvening(int day) {
     148          340 :     int backHome = whenBackHomeThisDay(day);
     149          340 :     if (myHousehold->getCars().empty()) {
     150              :         return true;
     151              :     }
     152          235 :     AGPosition destination(myHousehold->getTheCity()->getRandomStreet());
     153          235 :     int depTime = randomTimeBetween(MAX2(backHome, TB_EVENING), TE_EVENING);
     154          235 :     int arrTime = this->arrHour(myHousehold->getPosition(), destination, depTime);
     155          235 :     int retTime = randomTimeBetween(arrTime, TE_EVENING);
     156          235 :     if (depTime < 0 || retTime < 0) {
     157              :         return true;    // not enough time during the day
     158              :     }
     159          235 :     AGTrip depTrip(myHousehold->getPosition(), destination, myHousehold->getCars().front().getName(), depTime, day);
     160          235 :     AGTrip retTrip(destination, myHousehold->getPosition(), myHousehold->getCars().front().getName(), retTime, day);
     161              : 
     162          235 :     myPartialActivityTrips.push_back(depTrip);
     163              :     myPartialActivityTrips.push_back(retTrip);
     164              :     return true;
     165          235 : }
     166              : 
     167              : bool
     168           50 : AGFreeTime::typeFromHomeNight(int day) {
     169           50 :     int backHome = whenBackHomeThisDay(day);
     170           50 :     int ActivitiesNextDay = whenBeginActivityNextDay(day); // is equal to 2 days if there is nothing the next day
     171              :     int nextDay = 0;
     172           50 :     if (myHousehold->getCars().empty()) {
     173              :         return true;
     174              :     }
     175           41 :     AGPosition destination(myHousehold->getTheCity()->getRandomStreet());
     176              : 
     177           41 :     int depTime = randomTimeBetween(MAX2(backHome, TB_NIGHT), TE_NIGHT);
     178           41 :     int arrTime = this->arrHour(myHousehold->getPosition(), destination, depTime);
     179              :     //we have to go back home before the beginning of next day activities.
     180           41 :     int lastRetTime = this->depHour(destination, myHousehold->getPosition(), MIN2(TE_NIGHT, ActivitiesNextDay));
     181           41 :     int retTime = randomTimeBetween(arrTime, lastRetTime);
     182           41 :     if (depTime < 0 || retTime < 0) {
     183              :         return true;    // not enough time during the day
     184              :     }
     185              : 
     186              :     AGTime departureTime(depTime);
     187           41 :     nextDay = departureTime.getDay();
     188           41 :     departureTime.setDay(0);
     189           41 :     AGTrip depTrip(myHousehold->getPosition(), destination, myHousehold->getCars().front().getName(), departureTime.getTime(), day + nextDay);
     190              : 
     191              :     AGTime returnTime(depTime);
     192           41 :     nextDay = returnTime.getDay();
     193           41 :     returnTime.setDay(0);
     194           41 :     AGTrip retTrip(destination, myHousehold->getPosition(), myHousehold->getCars().front().getName(), returnTime.getTime(), day + nextDay);
     195              : 
     196           41 :     myPartialActivityTrips.push_back(depTrip);
     197              :     myPartialActivityTrips.push_back(retTrip);
     198              :     return true;
     199           41 : }
     200              : 
     201              : bool
     202         1506 : AGFreeTime::generateTrips() {
     203         1506 :     tReady = whenBackHome();
     204         1506 :     possibleType = possibleTypeOfTrip();
     205              :     int type;
     206              : 
     207         4516 :     for (int day = 1; day <= nbrDays; ++day) {
     208         3011 :         type = decideTypeOfTrip();
     209         3011 :         if (type == 0) {
     210         2557 :             continue;
     211          454 :         } else if (type == DAY) {
     212           64 :             if (!typeFromHomeDay(day)) {
     213              :                 return false;
     214              :             }
     215          390 :         } else if (type == EVENING) {
     216          340 :             if (!typeFromHomeEvening(day)) {
     217              :                 return false;
     218              :             }
     219           50 :         } else if (type == NIGHT) {
     220           50 :             if (!typeFromHomeNight(day)) {
     221              :                 return false;
     222              :             }
     223              :         }
     224              :     }
     225         1505 :     genDone = true;
     226         1505 :     return genDone;
     227              : }
     228              : 
     229              : int
     230         1506 : AGFreeTime::whenBackHome() {
     231              :     int timeBack = 0;
     232         2688 :     for (std::list<AGTrip>::iterator itT = myPreviousTrips->begin(); itT != myPreviousTrips->end(); ++itT) {
     233         1182 :         if (timeBack < itT->getArrTime(this->timePerKm) && itT->isDaily()) {
     234         1105 :             timeBack = itT->getArrTime(this->timePerKm);
     235              :         }
     236              :     }
     237         1506 :     return timeBack;
     238              : }
     239              : 
     240              : int
     241          454 : AGFreeTime::whenBackHomeThisDay(int day) {
     242              :     int timeBack = 0;
     243          829 :     for (std::list<AGTrip>::iterator itT = myPreviousTrips->begin(); itT != myPreviousTrips->end(); ++itT) {
     244          375 :         if (timeBack < itT->getArrTime(this->timePerKm) && (itT->getDay() == day || itT->isDaily())) {
     245          352 :             timeBack = itT->getArrTime(this->timePerKm);
     246              :         }
     247              :     }
     248          454 :     return timeBack;
     249              : }
     250              : 
     251              : int
     252           50 : AGFreeTime::whenBeginActivityNextDay(int day) {
     253              :     AGTime timeBack(1, 0, 0);
     254          136 :     for (std::list<AGTrip>::iterator itT = myPreviousTrips->begin(); itT != myPreviousTrips->end(); ++itT) {
     255           86 :         if (timeBack.getTime() > itT->getTime() && (itT->getDay() == (day + 1) || itT->isDaily())) {
     256           38 :             timeBack.setTime(itT->getTime());
     257              :         }
     258              :     }
     259           50 :     timeBack.addDays(1); // this the beginning of activities of the next day
     260           50 :     return timeBack.getTime();
     261              : }
     262              : 
     263              : 
     264              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1