SUMO - Simulation of Urban MObility
ROCostCalculator.cpp
Go to the documentation of this file.
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 /****************************************************************************/
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines