SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00008 // Calculators for route costs and probabilities 00009 /****************************************************************************/ 00010 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00011 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors 00012 /****************************************************************************/ 00013 // 00014 // This file is part of SUMO. 00015 // SUMO is free software: you can redistribute it and/or modify 00016 // it under the terms of the GNU General Public License as published by 00017 // the Free Software Foundation, either version 3 of the License, or 00018 // (at your option) any later version. 00019 // 00020 /****************************************************************************/ 00021 00022 00023 // =========================================================================== 00024 // included modules 00025 // =========================================================================== 00026 #ifdef _MSC_VER 00027 #include <windows_config.h> 00028 #else 00029 #include <config.h> 00030 #endif 00031 00032 #include <limits> 00033 #include <utils/common/StdDefs.h> 00034 #include <utils/geom/GeomHelper.h> 00035 #include <utils/common/SUMOTime.h> 00036 #include <utils/options/OptionsCont.h> 00037 #include "ROEdge.h" 00038 #include "RORoute.h" 00039 #include "ROVehicle.h" 00040 #include "ROCostCalculator.h" 00041 00042 #ifdef CHECK_MEMORY_LEAKS 00043 #include <foreign/nvwa/debug_new.h> 00044 #endif // CHECK_MEMORY_LEAKS 00045 00046 00047 // =========================================================================== 00048 // static member definitions 00049 // =========================================================================== 00050 ROCostCalculator* ROCostCalculator::myInstance = 0; 00051 00052 00053 // =========================================================================== 00054 // method definitions 00055 // =========================================================================== 00056 ROCostCalculator::ROCostCalculator() {} 00057 00058 00059 ROCostCalculator::~ROCostCalculator() {} 00060 00061 00062 ROCostCalculator& 00063 ROCostCalculator::getCalculator() { 00064 if (myInstance == 0) { 00065 OptionsCont& oc = OptionsCont::getOptions(); 00066 if (oc.getBool("logit")) { 00067 myInstance = new ROLogitCalculator(oc.getFloat("logit.beta"), oc.getFloat("logit.gamma"), oc.getFloat("logit.theta")); 00068 } else { 00069 myInstance = new ROGawronCalculator(oc.getFloat("gawron.beta"), oc.getFloat("gawron.a")); 00070 } 00071 } 00072 return *myInstance; 00073 } 00074 00075 00076 void 00077 ROCostCalculator::cleanup() { 00078 delete myInstance; 00079 myInstance = 0; 00080 } 00081 00082 00083 ROGawronCalculator::ROGawronCalculator(const SUMOReal beta, const SUMOReal a) 00084 : myBeta(beta), myA(a) {} 00085 00086 00087 ROGawronCalculator::~ROGawronCalculator() {} 00088 00089 00090 void 00091 ROGawronCalculator::setCosts(RORoute* route, const SUMOReal costs, const bool isActive) const { 00092 if (isActive) { 00093 route->setCosts(costs); 00094 } else { 00095 route->setCosts(myBeta * costs + ((SUMOReal) 1.0 - myBeta) * route->getCosts()); 00096 } 00097 } 00098 00099 00100 void 00101 ROGawronCalculator::calculateProbabilities(const ROVehicle* const veh, std::vector<RORoute*> alternatives) { 00102 for (std::vector<RORoute*>::iterator i = alternatives.begin(); i != alternatives.end() - 1; i++) { 00103 RORoute* pR = *i; 00104 for (std::vector<RORoute*>::iterator j = i + 1; j != alternatives.end(); j++) { 00105 RORoute* pS = *j; 00106 // see [Gawron, 1998] (4.2) 00107 const SUMOReal delta = 00108 (pS->getCosts() - pR->getCosts()) / 00109 (pS->getCosts() + pR->getCosts()); 00110 // see [Gawron, 1998] (4.3a, 4.3b) 00111 SUMOReal newPR = gawronF(pR->getProbability(), pS->getProbability(), delta); 00112 SUMOReal newPS = pR->getProbability() + pS->getProbability() - newPR; 00113 if (ISNAN(newPR) || ISNAN(newPS)) { 00114 newPR = pS->getCosts() > pR->getCosts() 00115 ? (SUMOReal) 1. : 0; 00116 newPS = pS->getCosts() > pR->getCosts() 00117 ? 0 : (SUMOReal) 1.; 00118 } 00119 newPR = MIN2((SUMOReal) MAX2(newPR, (SUMOReal) 0), (SUMOReal) 1); 00120 newPS = MIN2((SUMOReal) MAX2(newPS, (SUMOReal) 0), (SUMOReal) 1); 00121 pR->setProbability(newPR); 00122 pS->setProbability(newPS); 00123 } 00124 } 00125 } 00126 00127 00128 SUMOReal 00129 ROGawronCalculator::gawronF(const SUMOReal pdr, const SUMOReal pds, const SUMOReal x) const { 00130 if (pdr * gawronG(myA, x) + pds == 0) { 00131 return std::numeric_limits<SUMOReal>::max(); 00132 } 00133 return (pdr * (pdr + pds) * gawronG(myA, x)) / 00134 (pdr * gawronG(myA, x) + pds); 00135 } 00136 00137 00138 SUMOReal 00139 ROGawronCalculator::gawronG(const SUMOReal a, const SUMOReal x) const { 00140 if (((1.0 - (x * x)) == 0)) { 00141 return std::numeric_limits<SUMOReal>::max(); 00142 } 00143 return (SUMOReal) exp((a * x) / (1.0 - (x * x))); 00144 } 00145 00146 00147 00148 00149 ROLogitCalculator::ROLogitCalculator(const SUMOReal beta, const SUMOReal gamma, 00150 const SUMOReal theta) 00151 : myBeta(beta), myGamma(gamma), myTheta(theta) {} 00152 00153 00154 ROLogitCalculator::~ROLogitCalculator() {} 00155 00156 00157 void 00158 ROLogitCalculator::setCosts(RORoute* route, const SUMOReal costs, const bool isActive) const { 00159 route->setCosts(costs); 00160 } 00161 00162 00163 void 00164 ROLogitCalculator::calculateProbabilities(const ROVehicle* const veh, std::vector<RORoute*> alternatives) { 00165 const SUMOReal theta = myTheta >= 0 ? myTheta : getThetaForCLogit(alternatives); 00166 const SUMOReal beta = myBeta >= 0 ? myBeta : getBetaForCLogit(alternatives); 00167 if (beta > 0) { 00168 // calculate commonalities 00169 for (std::vector<RORoute*>::const_iterator i = alternatives.begin(); i != alternatives.end(); i++) { 00170 const RORoute* pR = *i; 00171 SUMOReal lengthR = 0; 00172 const std::vector<const ROEdge*> &edgesR = pR->getEdgeVector(); 00173 for (std::vector<const ROEdge*>::const_iterator edge = edgesR.begin(); edge != edgesR.end(); ++edge) { 00174 //@todo we should use costs here 00175 lengthR += (*edge)->getTravelTime(veh, STEPS2TIME(veh->getDepartureTime())); 00176 } 00177 SUMOReal overlapSum = 0; 00178 for (std::vector<RORoute*>::const_iterator j = alternatives.begin(); j != alternatives.end(); j++) { 00179 const RORoute* pS = *j; 00180 SUMOReal overlapLength = 0.; 00181 SUMOReal lengthS = 0; 00182 const std::vector<const ROEdge*> &edgesS = pS->getEdgeVector(); 00183 for (std::vector<const ROEdge*>::const_iterator edge = edgesS.begin(); edge != edgesS.end(); ++edge) { 00184 lengthS += (*edge)->getTravelTime(veh, STEPS2TIME(veh->getDepartureTime())); 00185 if (std::find(edgesR.begin(), edgesR.end(), *edge) != edgesR.end()) { 00186 overlapLength += (*edge)->getTravelTime(veh, STEPS2TIME(veh->getDepartureTime())); 00187 } 00188 } 00189 overlapSum += pow(overlapLength / sqrt(lengthR * lengthS), myGamma); 00190 } 00191 myCommonalities[pR] = beta * log(overlapSum); 00192 } 00193 } 00194 for (std::vector<RORoute*>::iterator i = alternatives.begin(); i != alternatives.end(); i++) { 00195 RORoute* pR = *i; 00196 SUMOReal weightedSum = 0; 00197 for (std::vector<RORoute*>::iterator j = alternatives.begin(); j != alternatives.end(); j++) { 00198 RORoute* pS = *j; 00199 weightedSum += exp(theta * (pR->getCosts() - pS->getCosts() + myCommonalities[pR] - myCommonalities[pS])); 00200 } 00201 pR->setProbability(1. / weightedSum); 00202 } 00203 } 00204 00205 00206 SUMOReal 00207 ROLogitCalculator::getBetaForCLogit(const std::vector<RORoute*> alternatives) const { 00208 SUMOReal min = std::numeric_limits<SUMOReal>::max(); 00209 for (std::vector<RORoute*>::const_iterator i = alternatives.begin(); i != alternatives.end(); i++) { 00210 const SUMOReal cost = (*i)->getCosts()/3600.; 00211 if (cost < min) { 00212 min = cost; 00213 } 00214 } 00215 return min; 00216 } 00217 00218 00219 SUMOReal 00220 ROLogitCalculator::getThetaForCLogit(const std::vector<RORoute*> alternatives) const { 00221 // @todo this calculation works for travel times only 00222 SUMOReal sum = 0.; 00223 SUMOReal diff = 0.; 00224 SUMOReal min = std::numeric_limits<SUMOReal>::max(); 00225 for (std::vector<RORoute*>::const_iterator i = alternatives.begin(); i != alternatives.end(); i++) { 00226 const SUMOReal cost = (*i)->getCosts()/3600.; 00227 sum += cost; 00228 if (cost < min) { 00229 min = cost; 00230 } 00231 } 00232 const SUMOReal meanCost = sum / SUMOReal(alternatives.size()); 00233 for (std::vector<RORoute*>::const_iterator i = alternatives.begin(); i != alternatives.end(); i++) { 00234 diff += pow((*i)->getCosts()/3600. - meanCost, 2); 00235 } 00236 const SUMOReal cvCost = sqrt(diff / SUMOReal(alternatives.size())) / meanCost; 00237 // @todo re-evaluate function 00238 // if (cvCost > 0.04) { // Magic numbers from Lohse book 00239 return PI / (sqrt(6.) * cvCost * (min + 1.1))/3600.; 00240 // } 00241 // return 1./3600.; 00242 } 00243 00244 00245 /****************************************************************************/