SUMO - Simulation of Urban MObility
AGFreeTime.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00009 // Generates trips related to after-work activities
00010 // like visiting the family or party.
00011 /****************************************************************************/
00012 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00013 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00014 // activitygen module
00015 // Copyright 2010 TUM (Technische Universitaet Muenchen, http://www.tum.de/)
00016 /****************************************************************************/
00017 //
00018 //   This file is part of SUMO.
00019 //   SUMO is free software: you can redistribute it and/or modify
00020 //   it under the terms of the GNU General Public License as published by
00021 //   the Free Software Foundation, either version 3 of the License, or
00022 //   (at your option) any later version.
00023 //
00024 /****************************************************************************/
00025 
00026 
00027 // ===========================================================================
00028 // included modules
00029 // ===========================================================================
00030 #ifdef _MSC_VER
00031 #include <windows_config.h>
00032 #else
00033 #include <config.h>
00034 #endif
00035 
00036 #include <math.h>
00037 #include <utils/common/RandHelper.h>
00038 #include <utils/common/StdDefs.h>
00039 #include <activitygen/city/AGTime.h>
00040 #include "AGFreeTime.h"
00041 
00042 
00043 // ===========================================================================
00044 // static member definitions
00045 // ===========================================================================
00046 const int AGFreeTime::DAY = 1;
00047 const int AGFreeTime::EVENING = 2;
00048 const int AGFreeTime::NIGHT = 4;
00049 
00050 const int AGFreeTime::TB_DAY = (new AGTime(0, 8, 0))->getTime();
00051 const int AGFreeTime::TE_DAY = (new AGTime(0, 18, 0))->getTime();
00052 const int AGFreeTime::TB_EVENING = (new AGTime(0, 19, 0))->getTime();
00053 const int AGFreeTime::TE_EVENING = (new AGTime(0, 23, 59))->getTime();
00054 const int AGFreeTime::TB_NIGHT = (new AGTime(0, 23, 0))->getTime();
00055 const int AGFreeTime::TE_NIGHT = (new AGTime(1, 5, 0))->getTime();
00056 
00057 
00058 // ===========================================================================
00059 // method definitions
00060 // ===========================================================================
00061 int
00062 AGFreeTime::decideTypeOfTrip() {
00063     if (hh->adults.front().decide(freqOut)) {
00064         int num_poss = 0; //(possibleType % 2) + (possibleType / 4) + ((possibleType / 2) % 2);
00065         if (possibleType & DAY) {
00066             ++num_poss;
00067         }
00068         if (possibleType & EVENING) {
00069             ++num_poss;
00070         }
00071         if (possibleType & NIGHT) {
00072             ++num_poss;
00073         }
00074 
00075         if (num_poss == 0) {
00076             return 0;
00077         }
00078         SUMOReal alea = RandHelper::rand(); //(float)(rand() % 1000) / 1000.0;
00079         int decision = (int)floor(alea * (SUMOReal)num_poss);
00080 
00081         if (possibleType & DAY) {
00082             if (decision == 0) {
00083                 return DAY;
00084             } else {
00085                 --decision;
00086             }
00087         }
00088         if (possibleType & EVENING) {
00089             if (decision == 0) {
00090                 return EVENING;
00091             } else {
00092                 --decision;
00093             }
00094         }
00095         if (possibleType & NIGHT) {
00096             if (decision == 0) {
00097                 return NIGHT;
00098             }
00099         }
00100     }
00101     return 0;
00102 }
00103 
00104 int
00105 AGFreeTime::possibleTypeOfTrip() {
00106     int val = 0;
00107     if (hh->adults.front().getAge() >= ds->limitAgeRetirement && tReady == 0) {
00108         val += DAY + EVENING;
00109     } else {
00110         if (hh->getPeopleNbr() > hh->getAdultNbr()) {
00111             val += NIGHT;
00112         }
00113 
00114         std::list<AGAdult>::iterator itA;
00115         bool noBodyWorks = true;
00116         for (itA = hh->adults.begin() ; itA != hh->adults.end() ; ++itA) {
00117             if (itA->isWorking()) {
00118                 noBodyWorks = false;
00119             }
00120         }
00121         if (noBodyWorks) {
00122             val += DAY;
00123         }
00124 
00125         if (tReady < (*(new AGTime(0, 22, 0))).getTime()) {
00126             val += EVENING;
00127         }
00128     }
00129     return val;
00130 }
00131 
00132 bool
00133 AGFreeTime::typeFromHomeDay(int day) {
00134     int backHome = whenBackHomeThisDay(day);
00135     if (hh->cars.empty()) {
00136         return true;
00137     }
00138     AGPosition destination(hh->getTheCity()->getRandomStreet());
00139     int depTime = randomTimeBetween(MAX2(backHome, TB_DAY), (TB_DAY + TE_DAY) / 2);
00140     int arrTime = this->arrHour(hh->getPosition(), destination, depTime);
00141     int retTime = randomTimeBetween(arrTime, TE_DAY);
00142     if (depTime < 0 || retTime < 0) {
00143         return true;    // not enough time during the day
00144     }
00145     AGTrip depTrip(hh->getPosition(), destination, hh->cars.front().getName(), depTime, day);
00146     AGTrip retTrip(destination, hh->getPosition(), hh->cars.front().getName(), retTime, day);
00147 
00148     this->partialActivityTrips.push_back(depTrip);
00149     this->partialActivityTrips.push_back(retTrip);
00150     return true;
00151 }
00152 
00153 bool
00154 AGFreeTime::typeFromHomeEvening(int day) {
00155     int backHome = whenBackHomeThisDay(day);
00156     if (hh->cars.empty()) {
00157         return true;
00158     }
00159     AGPosition destination(hh->getTheCity()->getRandomStreet());
00160     int depTime = randomTimeBetween(MAX2(backHome, TB_EVENING), TE_EVENING);
00161     int arrTime = this->arrHour(hh->getPosition(), destination, depTime);
00162     int retTime = randomTimeBetween(arrTime, TE_EVENING);
00163     if (depTime < 0 || retTime < 0) {
00164         return true;    // not enough time during the day
00165     }
00166     AGTrip depTrip(hh->getPosition(), destination, hh->cars.front().getName(), depTime, day);
00167     AGTrip retTrip(destination, hh->getPosition(), hh->cars.front().getName(), retTime, day);
00168 
00169     this->partialActivityTrips.push_back(depTrip);
00170     this->partialActivityTrips.push_back(retTrip);
00171     return true;
00172 }
00173 
00174 bool
00175 AGFreeTime::typeFromHomeNight(int day) {
00176     int backHome = whenBackHomeThisDay(day);
00177     int ActivitiesNextDay = whenBeginActivityNextDay(day); // is equal to 2 days if there is nothing the next day
00178     int nextDay = 0;
00179     if (hh->cars.empty()) {
00180         return true;
00181     }
00182     AGPosition destination(hh->getTheCity()->getRandomStreet());
00183 
00184     int depTime = randomTimeBetween(MAX2(backHome, TB_NIGHT), TE_NIGHT);
00185     int arrTime = this->arrHour(hh->getPosition(), destination, depTime);
00186     //we have to go back home before the beginning of next day activities.
00187     int lastRetTime = this->depHour(destination, hh->getPosition(), MIN2(TE_NIGHT, ActivitiesNextDay));
00188     int retTime = randomTimeBetween(arrTime, lastRetTime);
00189     if (depTime < 0 || retTime < 0) {
00190         return true;    // not enough time during the day
00191     }
00192 
00193     AGTime departureTime(depTime);
00194     nextDay = departureTime.getDay();
00195     departureTime.setDay(0);
00196     AGTrip depTrip(hh->getPosition(), destination, hh->cars.front().getName(), departureTime.getTime(), day + nextDay);
00197 
00198     AGTime returnTime(depTime);
00199     nextDay = returnTime.getDay();
00200     returnTime.setDay(0);
00201     AGTrip retTrip(destination, hh->getPosition(), hh->cars.front().getName(), returnTime.getTime(), day + nextDay);
00202 
00203     this->partialActivityTrips.push_back(depTrip);
00204     this->partialActivityTrips.push_back(retTrip);
00205     return true;
00206 }
00207 
00208 bool
00209 AGFreeTime::generateTrips() {
00210     tReady = whenBackHome();
00211     possibleType = possibleTypeOfTrip();
00212     int type;
00213 
00214     for (int day = 1 ; day <= nbrDays ; ++day) {
00215         type = decideTypeOfTrip();
00216         if (type == 0) {
00217             continue;
00218         } else if (type == DAY) {
00219             if (!typeFromHomeDay(day)) {
00220                 return false;
00221             }
00222         } else if (type == EVENING) {
00223             if (!typeFromHomeEvening(day)) {
00224                 return false;
00225             }
00226         } else if (type == NIGHT) {
00227             if (!typeFromHomeNight(day)) {
00228                 return false;
00229             }
00230         }
00231     }
00232     genDone = true;
00233     return genDone;
00234 }
00235 
00236 int
00237 AGFreeTime::whenBackHome() {
00238     int timeBack = 0;
00239     if (!this->previousTrips->empty()) {
00240         std::list<AGTrip>::iterator itT;
00241         for (itT = previousTrips->begin() ; itT != previousTrips->end() ; ++itT) {
00242             if (timeBack < itT->getArrTime(this->timePerKm) && itT->isDaily()) {
00243                 timeBack = itT->getArrTime(this->timePerKm);
00244             }
00245         }
00246     }
00247     return timeBack;
00248 }
00249 
00250 int
00251 AGFreeTime::whenBackHomeThisDay(int day) {
00252     int timeBack = 0;
00253     if (!this->previousTrips->empty()) {
00254         std::list<AGTrip>::iterator itT;
00255         for (itT = previousTrips->begin() ; itT != previousTrips->end() ; ++itT) {
00256             if (timeBack < itT->getArrTime(this->timePerKm) && (itT->getDay() == day || itT->isDaily())) {
00257                 timeBack = itT->getArrTime(this->timePerKm);
00258             }
00259         }
00260     }
00261     return timeBack;
00262 }
00263 
00264 int
00265 AGFreeTime::whenBeginActivityNextDay(int day) {
00266     AGTime timeBack(1, 0, 0);
00267     if (!this->previousTrips->empty()) {
00268         std::list<AGTrip>::iterator itT;
00269         for (itT = previousTrips->begin() ; itT != previousTrips->end() ; ++itT) {
00270             if (timeBack.getTime() > itT->getTime() && (itT->getDay() == (day + 1) || itT->isDaily())) {
00271                 timeBack.setTime(itT->getTime());
00272             }
00273         }
00274     }
00275     timeBack.addDays(1); // this the beginning of activities of the next day
00276     return timeBack.getTime();
00277 }
00278 
00279 /****************************************************************************/
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines