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