#include <config.h>
#include <algorithm>
#include <cassert>
#include <utils/common/MsgHandler.h>
#include <utils/common/RandHelper.h>
#include "ROJTREdge.h"
#include <utils/distribution/RandomDistributor.h>
ROJTREdge::ROJTREdge(const std::string& id, RONode* from, RONode* to, int index, const int priority, const std::string& type) :
ROEdge(id, from, to, index, priority, type),
mySourceFlows(0)
{}
ROJTREdge::~ROJTREdge() {
for (FollowerUsageCont::iterator i = myFollowingDefs.begin(); i != myFollowingDefs.end(); ++i) {
delete (*i).second;
}
}
void
ROJTREdge::addSuccessor(ROEdge* s, ROEdge* via, std::string dir) {
ROEdge::addSuccessor(s, via, dir);
ROJTREdge* js = static_cast<ROJTREdge*>(s);
if (myFollowingDefs.find(js) == myFollowingDefs.end()) {
myFollowingDefs[js] = new ValueTimeLine<double>();
}
}
void
ROJTREdge::addFollowerProbability(ROJTREdge* follower, double begTime,
double endTime, double probability) {
FollowerUsageCont::iterator i = myFollowingDefs.find(follower);
if (i == myFollowingDefs.end()) {
WRITE_ERRORF(TL("The edges '%' and '%' are not connected."), getID(), follower->getID());
return;
}
(*i).second->add(begTime, endTime, probability);
}
ROJTREdge*
ROJTREdge::chooseNext(const ROVehicle* const veh, double time, const std::set<const ROEdge*>& avoid) const {
if (myFollowingEdges.size() == 0 || (veh != nullptr && allFollowersProhibit(veh))) {
return nullptr;
}
RandomDistributor<ROJTREdge*> dist;
for (FollowerUsageCont::const_iterator i = myFollowingDefs.begin(); i != myFollowingDefs.end(); ++i) {
if (avoid.count(i->first) == 0) {
if ((veh == nullptr || !(*i).first->prohibits(veh)) && (*i).second->describesTime(time)) {
dist.add((*i).first, (*i).second->getValue(time));
}
}
}
if (dist.getOverallProb() == 0) {
for (int i = 0; i < (int)myParsedTurnings.size(); ++i) {
if (avoid.count(myFollowingEdges[i]) == 0) {
if (veh == nullptr || !myFollowingEdges[i]->prohibits(veh)) {
dist.add(static_cast<ROJTREdge*>(myFollowingEdges[i]), myParsedTurnings[i]);
}
}
}
}
if (dist.getOverallProb() == 0) {
return nullptr;
}
return dist.get();
}
void
ROJTREdge::setTurnDefaults(const std::vector<double>& defs) {
std::vector<double> tmp(defs.size()*myFollowingEdges.size(), 0);
for (int i = 0; i < (int)defs.size(); ++i) {
for (int j = 0; j < (int)myFollowingEdges.size(); ++j) {
tmp[i * myFollowingEdges.size() + j] = defs[i] / 100. / (double)myFollowingEdges.size();
}
}
for (int i = 0; i < (int)myFollowingEdges.size(); ++i) {
double value = 0;
for (int j = 0; j < (int)defs.size(); ++j) {
value += tmp[i * defs.size() + j];
}
myParsedTurnings.push_back((double) value);
}
}