00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
00091
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
00097 myLastUsed = findRoute(opt);
00098 myNewRoute = true;
00099
00100 if (myLastUsed>=0) {
00101 delete opt;
00102 myNewRoute = false;
00103 myAlternatives[myLastUsed]->setCosts(costs);
00104 return myAlternatives[myLastUsed];
00105 }
00106
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
00127 if (myLastUsed<0) {
00128 myAlternatives.push_back(current);
00129 myLastUsed = (int) myAlternatives.size() - 1;
00130 }
00131
00132 AlternativesVector::iterator i;
00133 for (i=myAlternatives.begin(); i!=myAlternatives.end(); i++) {
00134 RORoute *alt = *i;
00135
00136
00137 if ((*i)!=current||!myNewRoute) {
00138
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
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
00165 SUMOReal delta =
00166 (pS->getCosts() - pR->getCosts()) /
00167 (pS->getCosts() + pR->getCosts());
00168
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
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
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
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
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