RORouteDef_Alternatives.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // A route with alternative routes
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright 2001-2010 DLR (http://www.dlr.de/) and contributors
00011 /****************************************************************************/
00012 //
00013 //   This program is free software; you can redistribute it and/or modify
00014 //   it under the terms of the GNU General Public License as published by
00015 //   the Free Software Foundation; either version 2 of the License, or
00016 //   (at your option) any later version.
00017 //
00018 /****************************************************************************/
00019 
00020 
00021 // ===========================================================================
00022 // included modules
00023 // ===========================================================================
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029 
00030 #include <iomanip>
00031 #include <string>
00032 #include <vector>
00033 #include <cmath>
00034 #include <math.h>
00035 #include <cassert>
00036 #include <limits>
00037 #include <iostream>
00038 #include "ROEdge.h"
00039 #include "RORouteDef.h"
00040 #include "RORoute.h"
00041 #include "ROVehicle.h"
00042 #include "ROHelper.h"
00043 #include <utils/common/SUMOAbstractRouter.h>
00044 #include "RORouteDef_Alternatives.h"
00045 #include <utils/common/StdDefs.h>
00046 #include <utils/common/RandHelper.h>
00047 #include <utils/common/UtilExceptions.h>
00048 #include <utils/iodevices/OutputDevice.h>
00049 
00050 #ifdef CHECK_MEMORY_LEAKS
00051 #include <foreign/nvwa/debug_new.h>
00052 #endif // CHECK_MEMORY_LEAKS
00053 
00054 #ifdef _MSC_VER
00055 #define ISNAN _isnan
00056 #else
00057 #define ISNAN isnan
00058 #endif
00059 
00060 // ===========================================================================
00061 // method definitions
00062 // ===========================================================================
00063 RORouteDef_Alternatives::RORouteDef_Alternatives(const std::string &id,
00064         unsigned int lastUsed,
00065         SUMOReal gawronBeta,
00066         SUMOReal gawronA,
00067         int maxRoutes) throw()
00068         : RORouteDef(id, 0), myLastUsed((int) lastUsed),
00069         myGawronBeta(gawronBeta), myGawronA(gawronA), myMaxRouteNumber(maxRoutes) {
00070 }
00071 
00072 
00073 RORouteDef_Alternatives::~RORouteDef_Alternatives() throw() {
00074     for (AlternativesVector::iterator i=myAlternatives.begin(); i!=myAlternatives.end(); i++) {
00075         delete *i;
00076     }
00077 }
00078 
00079 
00080 void
00081 RORouteDef_Alternatives::addLoadedAlternative(RORoute *alt) {
00082     myAlternatives.push_back(alt);
00083 }
00084 
00085 
00086 
00087 RORoute *
00088 RORouteDef_Alternatives::buildCurrentRoute(SUMOAbstractRouter<ROEdge,ROVehicle> &router,
00089         SUMOTime begin, const ROVehicle &veh) const {
00090     // recompute duration of the last route used
00091     // build a new route to test whether it is better
00092     std::vector<const ROEdge*> edges;
00093     router.compute(myAlternatives[0]->getFirst(), myAlternatives[0]->getLast(), &veh, begin, edges);
00094     RORoute *opt = new RORoute(myID, 0, 1, edges, copyColorIfGiven());
00095     SUMOReal costs = router.recomputeCosts(opt->getEdgeVector(), &veh, begin);
00096     // check whether the same route was already used
00097     myLastUsed = findRoute(opt);
00098     myNewRoute = true;
00099     // delete the route when it already existed
00100     if (myLastUsed>=0) {
00101         delete opt;
00102         myNewRoute = false;
00103         myAlternatives[myLastUsed]->setCosts(costs);
00104         return myAlternatives[myLastUsed];
00105     }
00106     // return the built route
00107     opt->setCosts(costs);
00108     return opt;
00109 }
00110 
00111 
00112 int
00113 RORouteDef_Alternatives::findRoute(RORoute *opt) const {
00114     for (unsigned int i=0; i<myAlternatives.size(); i++) {
00115         if (opt->getEdgeVector() == myAlternatives[i]->getEdgeVector()) {
00116             return (int) i;
00117         }
00118     }
00119     return -1;
00120 }
00121 
00122 
00123 void
00124 RORouteDef_Alternatives::addAlternative(SUMOAbstractRouter<ROEdge,ROVehicle> &router,
00125                                         const ROVehicle *const veh, RORoute *current, SUMOTime begin) {
00126     // add the route when it's new
00127     if (myLastUsed<0) {
00128         myAlternatives.push_back(current);
00129         myLastUsed = (int) myAlternatives.size() - 1;
00130     }
00131     // recompute the costs and (when a new route was added) the probabilities
00132     AlternativesVector::iterator i;
00133     for (i=myAlternatives.begin(); i!=myAlternatives.end(); i++) {
00134         RORoute *alt = *i;
00135         // apply changes for old routes only
00136         //  (the costs for the current were computed already)
00137         if ((*i)!=current||!myNewRoute) {
00138             // recompute the costs for old routes
00139             SUMOReal oldCosts = alt->getCosts();
00140             SUMOReal newCosts = router.recomputeCosts(alt->getEdgeVector(), veh, begin);
00141             if (newCosts<0) {
00142                 throw ProcessError("Route '" + current->getID() + "' (vehicle '" + veh->getID() + "') is not valid.");
00143             }
00144             alt->setCosts(myGawronBeta * newCosts + ((SUMOReal) 1.0 - myGawronBeta) * oldCosts);
00145         }
00146         assert(myAlternatives.size()!=0);
00147         if (myNewRoute) {
00148             if ((*i)!=current) {
00149                 alt->setProbability(
00150                     alt->getProbability()
00151                     * SUMOReal(myAlternatives.size()-1)
00152                     / SUMOReal(myAlternatives.size()));
00153             } else {
00154                 alt->setProbability((SUMOReal)(1.0 / (SUMOReal) myAlternatives.size()));
00155             }
00156         }
00157     }
00158     assert(myAlternatives.size()!=0);
00159     // compute the probabilities
00160     for (i=myAlternatives.begin(); i!=myAlternatives.end()-1; i++) {
00161         RORoute *pR = *i;
00162         for (AlternativesVector::iterator j=i+1; j!=myAlternatives.end(); j++) {
00163             RORoute *pS = *j;
00164             // see [Gawron, 1998] (4.2)
00165             SUMOReal delta =
00166                 (pS->getCosts() - pR->getCosts()) /
00167                 (pS->getCosts() + pR->getCosts());
00168             // see [Gawron, 1998] (4.3a, 4.3b)
00169             SUMOReal newPR = gawronF(pR->getProbability(), pS->getProbability(), delta);
00170             SUMOReal newPS = pR->getProbability() + pS->getProbability() - newPR;
00171             if (ISNAN(newPR)||ISNAN(newPS)) {
00172                 newPR = pS->getCosts() > pR->getCosts()
00173                         ? (SUMOReal) 1. : 0;
00174                 newPS = pS->getCosts() > pR->getCosts()
00175                         ? 0 : (SUMOReal) 1.;
00176             }
00177             newPR = MIN2((SUMOReal) MAX2(newPR, (SUMOReal) 0), (SUMOReal) 1);
00178             newPS = MIN2((SUMOReal) MAX2(newPS, (SUMOReal) 0), (SUMOReal) 1);
00179             pR->setProbability(newPR);
00180             pS->setProbability(newPS);
00181         }
00182     }
00183     // remove with probability of 0 (not mentioned in Gawron)
00184     for (i=myAlternatives.begin(); i!=myAlternatives.end();) {
00185         if ((*i)->getProbability()==0) {
00186             i = myAlternatives.erase(i);
00187         } else {
00188             i++;
00189         }
00190     }
00191     // find the route to use
00192     SUMOReal chosen = RandHelper::rand();
00193     int pos = 0;
00194     for (i=myAlternatives.begin(); i!=myAlternatives.end()-1; i++, pos++) {
00195         chosen = chosen - (*i)->getProbability();
00196         if (chosen<=0) {
00197             myLastUsed = pos;
00198             return;
00199         }
00200     }
00201     myLastUsed = pos;
00202 }
00203 
00204 
00205 SUMOReal
00206 RORouteDef_Alternatives::gawronF(SUMOReal pdr, SUMOReal pds, SUMOReal x) {
00207     if (((pdr*gawronG(myGawronA, x)+pds)==0)) {
00208         return std::numeric_limits<SUMOReal>::max();
00209     }
00210     return (pdr*(pdr+pds)*gawronG(myGawronA, x)) /
00211            (pdr*gawronG(myGawronA, x)+pds);
00212 }
00213 
00214 
00215 SUMOReal
00216 RORouteDef_Alternatives::gawronG(SUMOReal a, SUMOReal x) {
00217     if (((1.0-(x*x))==0)) {
00218         return std::numeric_limits<SUMOReal>::max();
00219     }
00220     return (SUMOReal) exp((a*x)/(1.0-(x*x)));
00221 }
00222 
00223 
00224 RORouteDef *
00225 RORouteDef_Alternatives::copy(const std::string &id) const {
00226     RORouteDef_Alternatives *ret = new RORouteDef_Alternatives(id,
00227             myLastUsed, myGawronBeta, myGawronA, myMaxRouteNumber);
00228     for (std::vector<RORoute*>::const_iterator i=myAlternatives.begin(); i!=myAlternatives.end(); i++) {
00229         ret->addLoadedAlternative(new RORoute(*(*i)));
00230     }
00231     return ret;
00232 }
00233 
00234 
00235 void
00236 RORouteDef_Alternatives::invalidateLast() {
00237     myLastUsed = -1;
00238 }
00239 
00240 
00241 void
00242 RORouteDef_Alternatives::removeLast() {
00243     assert(myAlternatives.size()>=2);
00244     myAlternatives.erase(myAlternatives.end()-1);
00245     myLastUsed = (int) myAlternatives.size() - 1;
00246     // !!! recompute probabilities
00247 }
00248 
00249 
00250 OutputDevice &
00251 RORouteDef_Alternatives::writeXMLDefinition(SUMOAbstractRouter<ROEdge,ROVehicle> &router,
00252         OutputDevice &dev, const ROVehicle * const veh,
00253         bool asAlternatives, bool withExitTimes) const {
00254     // (optional) alternatives header
00255     if (asAlternatives) {
00256         dev.openTag("routeDistribution") << " last=\"" << myLastUsed << "\">\n";
00257         for (size_t i=0; i!=myAlternatives.size(); i++) {
00258             const RORoute &alt = *(myAlternatives[i]);
00259             dev.openTag("route") << " cost=\"" << alt.getCosts();
00260             dev.setPrecision(8);
00261             dev << "\" probability=\"" << alt.getProbability();
00262             dev.setPrecision();
00263             if (alt.getColor()!=0) {
00264                 dev << "\" color=\"" << *alt.getColor();
00265             } else if (myColor!=0) {
00266                 dev << "\" color=\"" << *myColor;
00267             }
00268             dev << "\" edges=\"" << alt.getEdgeVector();
00269             if (withExitTimes) {
00270                 SUMOReal time = (SUMOReal) veh->getDepartureTime();
00271                 dev << "\" exitTimes=\"";
00272                 std::vector<const ROEdge*>::const_iterator i = alt.getEdgeVector().begin();
00273                 for (; i!=alt.getEdgeVector().end(); ++i) {
00274                     if (i != alt.getEdgeVector().begin()) {
00275                         dev << " ";
00276                     }
00277                     time += (*i)->getTravelTime(veh, (SUMOTime) time);
00278                     dev << time;
00279                 }
00280             }
00281             (dev << "\"").closeTag(true);
00282         }
00283         dev.closeTag();
00284         return dev;
00285     } else {
00286         return myAlternatives[myLastUsed]->writeXMLDefinition(router, dev, veh, asAlternatives, withExitTimes);
00287     }
00288 }
00289 
00290 
00291 
00292 /****************************************************************************/
00293 

Generated on Wed May 5 00:06:36 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6