RORouteDef* RORouteDef::copy(const std::string& id) const { RORouteDef* result = new RORouteDef(id, 0, myTryRepair); for (std::vector<RORoute*>::const_iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) { RORoute* route = *i; RGBColor* col = route->getColor() != 0 ? new RGBColor(*route->getColor()) : 0; result->addLoadedAlternative(new RORoute(id, 0, 1, route->getEdgeVector(), col)); } return result; }
RORouteDef* RORouteDef::copy(const std::string& id, const SUMOTime stopOffset) const { RORouteDef* result = new RORouteDef(id, 0, myTryRepair, myMayBeDisconnected); for (std::vector<RORoute*>::const_iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) { RORoute* route = *i; RGBColor* col = route->getColor() != 0 ? new RGBColor(*route->getColor()) : 0; RORoute* newRoute = new RORoute(id, 0, 1, route->getEdgeVector(), col, route->getStops()); newRoute->addStopOffset(stopOffset); result->addLoadedAlternative(newRoute); } return result; }
void RORouteDef::addAlternative(SUMOAbstractRouter<ROEdge, ROVehicle>& router, const ROVehicle* const veh, RORoute* current, SUMOTime begin) { if (myTryRepair) { if (myNewRoute) { delete myAlternatives[0]; myAlternatives.pop_back(); myAlternatives.push_back(current); } const SUMOReal costs = router.recomputeCosts(current->getEdgeVector(), veh, begin); if (costs < 0) { throw ProcessError("Route '" + getID() + "' (vehicle '" + veh->getID() + "') is not valid."); } current->setCosts(costs); return; } // add the route when it's new if (myNewRoute) { myAlternatives.push_back(current); } // recompute the costs and (when a new route was added) scale the probabilities const SUMOReal scale = SUMOReal(myAlternatives.size() - 1) / SUMOReal(myAlternatives.size()); for (std::vector<RORoute*>::iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) { RORoute* alt = *i; // recompute the costs for all routes const SUMOReal newCosts = router.recomputeCosts(alt->getEdgeVector(), veh, begin); if (newCosts < 0.) { throw ProcessError("Route '" + current->getID() + "' (vehicle '" + veh->getID() + "') is not valid."); } assert(myAlternatives.size() != 0); if (myNewRoute) { if (*i == current) { // set initial probability and costs alt->setProbability((SUMOReal)(1.0 / (SUMOReal) myAlternatives.size())); alt->setCosts(newCosts); } else { // rescale probs for all others alt->setProbability(alt->getProbability() * scale); } } ROCostCalculator::getCalculator().setCosts(alt, newCosts, *i == myAlternatives[myLastUsed]); } assert(myAlternatives.size() != 0); ROCostCalculator::getCalculator().calculateProbabilities(veh, myAlternatives); if (!ROCostCalculator::getCalculator().keepRoutes()) { // remove with probability of 0 (not mentioned in Gawron) for (std::vector<RORoute*>::iterator i = myAlternatives.begin(); i != myAlternatives.end();) { if ((*i)->getProbability() == 0) { delete *i; i = myAlternatives.erase(i); } else { i++; } } } if (myAlternatives.size() > ROCostCalculator::getCalculator().getMaxRouteNumber()) { // only keep the routes with highest probability sort(myAlternatives.begin(), myAlternatives.end(), ComparatorProbability()); for (std::vector<RORoute*>::iterator i = myAlternatives.begin() + ROCostCalculator::getCalculator().getMaxRouteNumber(); i != myAlternatives.end(); i++) { delete *i; } myAlternatives.erase(myAlternatives.begin() + ROCostCalculator::getCalculator().getMaxRouteNumber(), myAlternatives.end()); // rescale probabilities SUMOReal newSum = 0; for (std::vector<RORoute*>::iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) { newSum += (*i)->getProbability(); } assert(newSum > 0); // @note newSum may be larger than 1 for numerical reasons for (std::vector<RORoute*>::iterator i = myAlternatives.begin(); i != myAlternatives.end(); i++) { (*i)->setProbability((*i)->getProbability() / newSum); } } // find the route to use SUMOReal chosen = RandHelper::rand(); int pos = 0; for (std::vector<RORoute*>::iterator i = myAlternatives.begin(); i != myAlternatives.end() - 1; i++, pos++) { chosen -= (*i)->getProbability(); if (chosen <= 0) { myLastUsed = pos; return; } } myLastUsed = pos; }
void ROVehicle::computeRoute(const RORouterProvider& provider, const bool removeLoops, MsgHandler* errorHandler) { SUMOAbstractRouter<ROEdge, ROVehicle>& router = provider.getVehicleRouter(); std::string noRouteMsg = "The vehicle '" + getID() + "' has no valid route."; RORouteDef* const routeDef = getRouteDefinition(); // check if the route definition is valid if (routeDef == nullptr) { errorHandler->inform(noRouteMsg); myRoutingSuccess = false; return; } RORoute* current = routeDef->buildCurrentRoute(router, getDepartureTime(), *this); if (current == nullptr || current->size() == 0) { delete current; errorHandler->inform(noRouteMsg); myRoutingSuccess = false; return; } // check whether we have to evaluate the route for not containing loops if (removeLoops) { const ROEdge* requiredStart = (getParameter().departPosProcedure == DEPART_POS_GIVEN || getParameter().departLaneProcedure == DEPART_LANE_GIVEN ? current->getEdgeVector().front() : 0); const ROEdge* requiredEnd = (getParameter().arrivalPosProcedure == ARRIVAL_POS_GIVEN || getParameter().arrivalLaneProcedure == ARRIVAL_LANE_GIVEN ? current->getEdgeVector().back() : 0); current->recheckForLoops(getMandatoryEdges(requiredStart, requiredEnd)); // check whether the route is still valid if (current->size() == 0) { delete current; errorHandler->inform(noRouteMsg + " (after removing loops)"); myRoutingSuccess = false; return; } } // add built route routeDef->addAlternative(router, this, current, getDepartureTime()); myRoutingSuccess = true; }