SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00010 // Contains various data, statistical values and functions from input used 00011 // by various objects 00012 /****************************************************************************/ 00013 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00014 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors 00015 // activitygen module 00016 // Copyright 2010 TUM (Technische Universitaet Muenchen, http://www.tum.de/) 00017 /****************************************************************************/ 00018 // 00019 // This file is part of SUMO. 00020 // SUMO is free software: you can redistribute it and/or modify 00021 // it under the terms of the GNU General Public License as published by 00022 // the Free Software Foundation, either version 3 of the License, or 00023 // (at your option) any later version. 00024 // 00025 /****************************************************************************/ 00026 00027 00028 // =========================================================================== 00029 // included modules 00030 // =========================================================================== 00031 #ifdef _MSC_VER 00032 #include <windows_config.h> 00033 #else 00034 #include <config.h> 00035 #endif 00036 00037 #include "AGDataAndStatistics.h" 00038 #include <utils/common/RandHelper.h> 00039 #include <cmath> 00040 #include <iomanip> 00041 #define LIMIT_CHILDREN_NUMBER 3 00042 00043 00044 // =========================================================================== 00045 // method definitions 00046 // =========================================================================== 00047 AGDataAndStatistics& 00048 AGDataAndStatistics::getDataAndStatistics() { 00049 static AGDataAndStatistics ds; 00050 return ds; 00051 } 00052 00053 int 00054 AGDataAndStatistics::getRandom(int n, int m) { 00055 if (m < n) { 00056 return 0; 00057 } 00058 int num = RandHelper::rand(m - n); 00059 num += n; 00060 return num; 00061 } 00062 00063 int 00064 AGDataAndStatistics::getRandomPopDistributed(int n, int m) { 00065 if (m < n || n >= limitEndAge) { 00066 return -1; 00067 } 00068 if (m > limitEndAge) { 00069 m = limitEndAge; 00070 } 00071 SUMOReal alea = RandHelper::rand(); 00072 SUMOReal beginProp = getPropYoungerThan(n); 00073 SUMOReal total = getPropYoungerThan(m) - beginProp; 00074 if (total <= 0) { 00075 return -1; 00076 } 00081 alea = alea * total + beginProp; 00082 for (int a = n ; a < m ; ++a) { 00083 if (alea < getPropYoungerThan(a + 1)) { 00084 return a; 00085 } 00086 } 00087 return -1; 00088 } 00089 00090 int 00091 AGDataAndStatistics::getPoissonsNumberOfChildren(SUMOReal mean) { 00092 SUMOReal alea = RandHelper::rand(); 00093 SUMOReal cumul = 0; 00094 for (int nbr = 0 ; nbr < LIMIT_CHILDREN_NUMBER ; ++nbr) { 00095 cumul += poisson(mean, nbr); 00096 if (cumul > alea) { 00097 return nbr; 00098 } 00099 } 00100 return LIMIT_CHILDREN_NUMBER; 00101 } 00102 00103 SUMOReal 00104 AGDataAndStatistics::poisson(SUMOReal mean, int occ) { 00105 SUMOReal proba = exp(-mean); 00106 proba *= pow(mean, occ); 00107 proba /= (SUMOReal)factorial(occ); 00108 return proba; 00109 } 00110 00111 int 00112 AGDataAndStatistics::factorial(int fact) { 00113 if (fact > 0) { 00114 return fact * factorial(fact - 1); 00115 } 00116 return 1; 00117 } 00118 00119 void 00120 AGDataAndStatistics::consolidateStat() { 00121 normalizeMapProb(&beginWorkHours); 00122 normalizeMapProb(&endWorkHours); 00123 normalizeMapProb(&population); 00124 normalizeMapProb(&incoming); 00125 normalizeMapProb(&outgoing); 00126 limitEndAge = population.rbegin()->first; 00127 00128 oldAgeHhProb = (SUMOReal)getPeopleOlderThan(limitAgeRetirement) / (SUMOReal)getPeopleOlderThan(limitAgeChildren); 00129 secondPersProb = (SUMOReal)(getPeopleOlderThan(limitAgeChildren) - households) / (SUMOReal)households; 00130 meanNbrChildren = (SUMOReal)getPeopleYoungerThan(limitAgeChildren) / ((1 - oldAgeHhProb) * (SUMOReal)households); 00131 //cout << " --> oldAgeHhProb = " << setprecision(3) << oldAgeHhProb << " - retAge? " << getPeopleOlderThan(limitAgeRetirement) << " adAge? " << getPeopleOlderThan(limitAgeChildren) << endl; 00132 //cout << " --> secondPersProb = " << setprecision(3) << secondPersProb << " - adAge? " << getPeopleOlderThan(limitAgeChildren) << " hh?" << households << endl; 00133 //cout << " --> meanNbrChildren = " << setprecision(3) << meanNbrChildren << " - chAge? " << getPeopleYoungerThan(limitAgeChildren) << endl; 00134 } 00135 00136 SUMOReal 00137 AGDataAndStatistics::getPropYoungerThan(int age) { 00138 std::map<int, SUMOReal>::iterator it; 00139 SUMOReal sum = 0; 00140 int previousAge = 0; 00141 SUMOReal prop = 0; 00142 00143 for (it = population.begin() ; it != population.end() ; ++it) { 00144 if (it->first < age) { 00145 sum += it->second; 00146 } else if (it->first >= age && previousAge < age) { 00147 prop = ((SUMOReal)(age - previousAge) / (SUMOReal)(it->first - previousAge)); 00148 sum += prop * it->second; 00149 break; 00150 } 00151 previousAge = it->first; 00152 } 00153 return sum; 00154 } 00155 00156 int 00157 AGDataAndStatistics::getPeopleYoungerThan(int age) { 00158 return (int)((SUMOReal)inhabitants * getPropYoungerThan(age)); 00159 } 00160 00161 int 00162 AGDataAndStatistics::getPeopleOlderThan(int age) { 00163 return (inhabitants - getPeopleYoungerThan(age)); 00164 } 00165 00166 void 00167 AGDataAndStatistics::normalizeMapProb(std::map<int, SUMOReal> *myMap) { 00168 SUMOReal sum = 0; 00169 std::map<int, SUMOReal>::iterator it; 00170 for (it = myMap->begin() ; it != myMap->end() ; ++it) { 00171 sum += it->second; 00172 } 00173 if (sum == 0) { 00174 return; 00175 } 00176 for (it = myMap->begin() ; it != myMap->end() ; ++it) { 00177 it->second = it->second / sum; 00178 } 00179 } 00180 00181 SUMOReal 00182 AGDataAndStatistics::getInverseExpRandomValue(SUMOReal mean, SUMOReal maxVar) { 00183 if (maxVar <= 0) { 00184 return mean; 00185 } 00186 SUMOReal p = RandHelper::rand(static_cast<SUMOReal>(0.0001), static_cast<SUMOReal>(1)); 00187 //we have to scale the distribution because maxVar is different from INF 00188 SUMOReal scale = exp((-1) * maxVar); 00189 //new p: scaled 00190 p = p * (1 - scale) + scale; // p = [scale ; 1) ==> (1-p) = (0 ; 1-scale] 00191 00192 SUMOReal variation = (-1) * log(p); 00193 //decide the side of the mean value 00194 if (RandHelper::rand(1000) < 500) { 00195 return mean + variation; 00196 } else { 00197 return mean - variation; 00198 } 00199 00200 } 00201 00202 int 00203 AGDataAndStatistics::getRandomCityGateByIncoming() { 00204 SUMOReal alea = RandHelper::rand(); 00205 SUMOReal total = 0; 00206 std::map<int, SUMOReal>::iterator it; 00207 for (it = incoming.begin() ; it != incoming.end() ; ++it) { 00208 total += it->second; 00209 if (alea < total) { 00210 return it->first; 00211 } 00212 } 00213 std::cout << "ERROR: incoming at city gates not normalized" << std::endl; 00214 return 0; 00215 } 00216 00217 int 00218 AGDataAndStatistics::getRandomCityGateByOutgoing() { 00219 SUMOReal alea = RandHelper::rand(); 00220 SUMOReal total = 0; 00221 std::map<int, SUMOReal>::iterator it; 00222 for (it = outgoing.begin() ; it != outgoing.end() ; ++it) { 00223 total += it->second; 00224 if (alea < total) { 00225 return it->first; 00226 } 00227 } 00228 std::cout << "ERROR: outgoing at city gates not normalized" << std::endl; 00229 return 0; 00230 } 00231 00232 00233 00234 /****************************************************************************/