|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // Contains various data, statistical values and functions from input used 00008 // by various objects 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 "AGDataAndStatistics.h" 00034 #include <utils/common/RandHelper.h> 00035 #include <cmath> 00036 #include <iomanip> 00037 #define LIMIT_CHILDREN_NUMBER 3 00038 00039 00040 // =========================================================================== 00041 // method definitions 00042 // =========================================================================== 00043 AGDataAndStatistics& 00044 AGDataAndStatistics::getDataAndStatistics() throw() { 00045 static AGDataAndStatistics ds; 00046 return ds; 00047 } 00048 00049 int 00050 AGDataAndStatistics::getRandom(int n, int m) { 00051 if (m<n) { 00052 return 0; 00053 } 00054 int num = RandHelper::rand(m - n); 00055 num += n; 00056 return num; 00057 } 00058 00059 int 00060 AGDataAndStatistics::getRandomPopDistributed(int n, int m) { 00061 if (m<n || n>= limitEndAge) { 00062 return -1; 00063 } 00064 if (m>limitEndAge) { 00065 m=limitEndAge; 00066 } 00067 SUMOReal alea = RandHelper::rand(); 00068 SUMOReal beginProp = getPropYoungerThan(n); 00069 SUMOReal total = getPropYoungerThan(m) - beginProp; 00070 if (total <= 0) { 00071 return -1; 00072 } 00077 alea = alea * total + beginProp; 00078 for (int a=n ; a<m ; ++a) { 00079 if (alea < getPropYoungerThan(a+1)) { 00080 return a; 00081 } 00082 } 00083 return -1; 00084 } 00085 00086 int 00087 AGDataAndStatistics::getPoissonsNumberOfChildren(SUMOReal mean) { 00088 SUMOReal alea = RandHelper::rand(); 00089 SUMOReal cumul = 0; 00090 for (int nbr = 0 ; nbr < LIMIT_CHILDREN_NUMBER ; ++nbr) { 00091 cumul += poisson(mean, nbr); 00092 if (cumul > alea) { 00093 return nbr; 00094 } 00095 } 00096 return LIMIT_CHILDREN_NUMBER; 00097 } 00098 00099 SUMOReal 00100 AGDataAndStatistics::poisson(SUMOReal mean, int occ) { 00101 SUMOReal proba = exp(-mean); 00102 proba *= pow(mean, occ); 00103 proba /= (SUMOReal)factorial(occ); 00104 return proba; 00105 } 00106 00107 int 00108 AGDataAndStatistics::factorial(int fact) { 00109 if (fact > 0) { 00110 return fact * factorial(fact-1); 00111 } 00112 return 1; 00113 } 00114 00115 void 00116 AGDataAndStatistics::consolidateStat() { 00117 normalizeMapProb(&beginWorkHours); 00118 normalizeMapProb(&endWorkHours); 00119 normalizeMapProb(&population); 00120 normalizeMapProb(&incoming); 00121 normalizeMapProb(&outgoing); 00122 limitEndAge = population.rbegin()->first; 00123 00124 oldAgeHhProb = (SUMOReal)getPeopleOlderThan(limitAgeRetirement) / (SUMOReal)getPeopleOlderThan(limitAgeChildren); 00125 secondPersProb = (SUMOReal)(getPeopleOlderThan(limitAgeChildren) - households) / (SUMOReal)households; 00126 meanNbrChildren = (SUMOReal)getPeopleYoungerThan(limitAgeChildren) / ((1 - oldAgeHhProb) * (SUMOReal)households); 00127 //cout << " --> oldAgeHhProb = " << setprecision(3) << oldAgeHhProb << " - retAge? " << getPeopleOlderThan(limitAgeRetirement) << " adAge? " << getPeopleOlderThan(limitAgeChildren) << endl; 00128 //cout << " --> secondPersProb = " << setprecision(3) << secondPersProb << " - adAge? " << getPeopleOlderThan(limitAgeChildren) << " hh?" << households << endl; 00129 //cout << " --> meanNbrChildren = " << setprecision(3) << meanNbrChildren << " - chAge? " << getPeopleYoungerThan(limitAgeChildren) << endl; 00130 } 00131 00132 SUMOReal 00133 AGDataAndStatistics::getPropYoungerThan(int age) { 00134 std::map<int, SUMOReal>::iterator it; 00135 SUMOReal sum = 0; 00136 int previousAge = 0; 00137 SUMOReal prop = 0; 00138 00139 for (it = population.begin() ; it != population.end() ; ++it) { 00140 if (it->first < age) { 00141 sum += it->second; 00142 } else if (it->first >= age && previousAge < age) { 00143 prop = ((SUMOReal)(age - previousAge) / (SUMOReal)(it->first - previousAge)); 00144 sum += prop * it->second; 00145 break; 00146 } 00147 previousAge = it->first; 00148 } 00149 return sum; 00150 } 00151 00152 int 00153 AGDataAndStatistics::getPeopleYoungerThan(int age) { 00154 return (int)((SUMOReal)inhabitants * getPropYoungerThan(age)); 00155 } 00156 00157 int 00158 AGDataAndStatistics::getPeopleOlderThan(int age) { 00159 return (inhabitants - getPeopleYoungerThan(age)); 00160 } 00161 00162 void 00163 AGDataAndStatistics::normalizeMapProb(std::map<int, SUMOReal> *myMap) { 00164 SUMOReal sum = 0; 00165 std::map<int, SUMOReal>::iterator it; 00166 for (it = myMap->begin() ; it != myMap->end() ; ++it) { 00167 sum += it->second; 00168 } 00169 if (sum == 0) { 00170 return; 00171 } 00172 for (it = myMap->begin() ; it != myMap->end() ; ++it) { 00173 it->second = it->second / sum; 00174 } 00175 } 00176 00177 SUMOReal 00178 AGDataAndStatistics::getInverseExpRandomValue(SUMOReal mean, SUMOReal maxVar) { 00179 if (maxVar <= 0) { 00180 return mean; 00181 } 00182 SUMOReal p = RandHelper::rand(static_cast<SUMOReal>(0.0001), static_cast<SUMOReal>(1)); 00183 //we have to scale the distribution because maxVar is different from INF 00184 SUMOReal scale = exp((-1)*maxVar); 00185 //new p: scaled 00186 p = p * (1-scale) + scale; // p = [scale ; 1) ==> (1-p) = (0 ; 1-scale] 00187 00188 SUMOReal variation = (-1)*log(p); 00189 //decide the side of the mean value 00190 if (RandHelper::rand(1000) < 500) { 00191 return mean + variation; 00192 } else { 00193 return mean - variation; 00194 } 00195 00196 } 00197 00198 int 00199 AGDataAndStatistics::getRandomCityGateByIncoming() { 00200 SUMOReal alea = RandHelper::rand(); 00201 SUMOReal total = 0; 00202 std::map<int, SUMOReal>::iterator it; 00203 for (it = incoming.begin() ; it != incoming.end() ; ++it) { 00204 total += it->second; 00205 if (alea < total) { 00206 return it->first; 00207 } 00208 } 00209 std::cout << "ERROR: incoming at city gates not normalized" << std::endl; 00210 return 0; 00211 } 00212 00213 int 00214 AGDataAndStatistics::getRandomCityGateByOutgoing() { 00215 SUMOReal alea = RandHelper::rand(); 00216 SUMOReal total = 0; 00217 std::map<int, SUMOReal>::iterator it; 00218 for (it = outgoing.begin() ; it != outgoing.end() ; ++it) { 00219 total += it->second; 00220 if (alea < total) { 00221 return it->first; 00222 } 00223 } 00224 std::cout << "ERROR: outgoing at city gates not normalized" << std::endl; 00225 return 0; 00226 } 00227 00228 00229 00230 /****************************************************************************/