SUMO - Simulation of Urban MObility
|
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 /****************************************************************************/