66template<
class E,
class V>
82 bool havePermissions =
false,
const bool haveRestrictions =
false,
double maxTrainLength = 5000,
83 double reversalPenalty = 60) :
84 SUMOAbstractRouter<E, V>(
"RailwayRouter", unbuildIsWarning, effortOperation, ttOperation, havePermissions, haveRestrictions),
91 for (
const E*
const edge : edges) {
107 bool compute(
const E* from,
const E* to,
const V*
const vehicle,
SUMOTime msTime, std::vector<const E*>& into,
bool silent =
false) {
110 WRITE_WARNINGF(
"Vehicle '%' with length % exceeds configured value of --railway.max-train-length %",
113 return _compute(from, to, vehicle, msTime, into, silent,
false);
118 std::map<const _RailEdge*, double> railEdges;
119 for (
auto item : toProhibit) {
120 railEdges[item.first->getRailwayRoutingEdge()] = item.second;
124#ifdef RailwayRouter_DEBUG_ROUTES
125 std::cout <<
"RailRouter numProhibitions=" << toProhibit.size() <<
"\n";
130 double recomputeCosts(
const std::vector<const E*>& edges,
const V*
const v,
SUMOTime msTime,
double* lengthp =
nullptr)
const {
132 const E* prev =
nullptr;
135 for (
const E*
const e : edges) {
136 if (prev !=
nullptr && e->getBidiEdge() == prev) {
137 if (e->getLength() > v->getLength()) {
140 const double savingsFactor = 1 - v->getLength() / e->getLength();
141 double effortCorrection = 0;
142 double lengthCorrection = 0.;
143 effortCorrection += this->
getEffort(prev, v, timeCorrection);
144 this->
updateViaCost(prev, e, v, timeCorrection, effortCorrection, lengthCorrection);
145 effort -= savingsFactor * effortCorrection;
146 if (lengthp !=
nullptr) {
147 *lengthp -= savingsFactor * lengthCorrection;
179 bool _compute(
const E* from,
const E* to,
const V*
const vehicle,
SUMOTime msTime, std::vector<const E*>& into,
bool silent,
bool avoidUnsafeBackTracking) {
182 std::vector<double> backLengths;
183 double backDist =
myReversalPenalty >= 0 ? vehicle->getLength() - from->getLength() : 0;
184 const E* start = from;
185 while (backDist > 0) {
187 if (prev ==
nullptr) {
188#ifdef RailwayRouter_DEBUG_ROUTES
189 std::cout <<
" Could not determine back edge for vehicle '" << vehicle->getID() <<
"' when routing from edge '" << from->getID() <<
"' at time=" <<
time2string(msTime) <<
"\n";
194 backDist -= prev->getLength();
195 if (avoidUnsafeBackTracking && prev->getSuccessors().size() > 1) {
196 bool foundSwitch =
false;
197 for (
const E* succ : prev->getSuccessors()) {
198 if (succ != start && succ != prev->getBidiEdge()) {
207 backLengths.push_back(prev->getLength() + (backLengths.empty()
208 ?
MIN2(vehicle->getLength(), from->getLength())
209 : backLengths.back()));
213 std::vector<const _RailEdge*> intoTmp;
217 bool success =
myInternalRouter->
compute(start->getRailwayRoutingEdge(), to->getRailwayRoutingEdge(), vehicle, msTime, intoTmp, silent);
219#ifdef RailwayRouter_DEBUG_ROUTES
220 std::cout <<
"RailRouter veh=" << vehicle->getID() <<
" from=" << from->getID() <<
" to=" << to->getID() <<
" t=" <<
time2string(msTime)
221 <<
" safe=" << avoidUnsafeBackTracking <<
" success=" << success <<
" into=" <<
toString(into) <<
"\n";
224 const size_t intoSize = into.size();
225 int backIndex = (int)backLengths.size();
226 for (
const _RailEdge* railEdge : intoTmp) {
227 if (railEdge->getOriginal() !=
nullptr) {
231 const double length = backIndex >= 0 ? backLengths[backIndex] : vehicle->getLength();
232 railEdge->insertOriginalEdges(length, into);
234#ifdef RailwayRouter_DEBUG_ROUTES
235 std::cout <<
"RailRouter: internal result=" <<
toString(intoTmp) <<
"\n";
236 std::cout <<
"RailRouter: expanded result=" <<
toString(into) <<
"\n";
237 std::cout <<
"RailRouter: backLengths=" <<
toString(backLengths) <<
" bls=" << backLengths.size() <<
" intoSize=" << intoSize <<
" final result=" <<
toString(into) <<
"\n";
239 if (backLengths.size() > 0) {
241 into.erase(into.begin() + intoSize, into.begin() + intoSize + backLengths.size());
242 if (*(into.begin() + intoSize) != from) {
243 if (!avoidUnsafeBackTracking) {
246 into.erase(into.begin() + intoSize, into.end());
248 success =
_compute(from, to, vehicle, msTime, into, silent,
true);
251 WRITE_WARNING(
"Railway routing failure due to turn-around on short edge '" + from->getID()
252 +
"' for vehicle '" + vehicle->getID() +
"' time=" +
time2string(msTime) +
".");
258 for (
const E* e : into) {
276 FXMutexLock locker(myLock);
295 std::vector<const E*> repl;
297 assert(repl.size() > 0);
301 for (
const E* e : repl) {
302 result += (*myStaticOperation)(e, veh, time + result);
303 seenDist += e->getLength();
305 const double lengthOnLastEdge =
MAX2(0.0, veh->getLength() - seenDist);
320 const E* result =
nullptr;
321#ifdef RailwayRouter_DEBUG_ROUTES
322 std::cout <<
" getStraightPredecessor edge=" << edge->getID() <<
" prevRouteSize=" << prevRoute.size() <<
" backIndex=" << backIndex <<
"\n";
324 if ((
int)prevRoute.size() > backIndex) {
325 return prevRoute[(int)prevRoute.size() - 1 - backIndex];
327 for (
const E* cand : edge->getPredecessors()) {
328 if (!cand->isInternal() && cand->getBidiEdge() != edge) {
330 if (result ==
nullptr) {
359 mutable FXMutex myLock;
374template<
class E,
class V>
376template<
class E,
class V>
378template<
class E,
class V>
#define WRITE_WARNINGF(...)
#define WRITE_WARNING(msg)
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Computes the shortest path through a network using the Dijkstra algorithm.
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
the edge type representing backward edges
void insertOriginalEdges(double length, std::vector< const E * > &into) const
const E * getOriginal() const
Returns the original edge.
SUMOAbstractRouter< _RailEdge, V > _InternalRouter
static double myReversalPenaltyFactor
RailwayRouter< E, V > *const myOriginal
RailwayRouter(RailwayRouter *other)
DijkstraRouter< _RailEdge, V > _InternalDijkstra
std::vector< _RailEdge * > myInitialEdges
a RailEdge for every existing edge, filled on construction (but not in clones)
RailwayRouter & operator=(const RailwayRouter &s)
Invalidated assignment operator.
std::vector< _RailEdge * > myRailEdges
complete rail network filled on demand (but not in clones)
void prohibit(const Prohibitions &toProhibit)
void setBulkMode(const bool mode)
double recomputeCosts(const std::vector< const E * > &edges, const V *const v, SUMOTime msTime, double *lengthp=nullptr) const
const bool mySilent
whether to suppress warning/error if no route was found
bool compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into, bool silent=false)
Builds the route between the given edges using the minimum effort at the given time The definition of...
_InternalRouter * myInternalRouter
static SUMOAbstractRouter< E, V >::Operation myStaticOperation
The object's operation to perform. (hack)
const double myMaxTrainLength
bool _compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into, bool silent, bool avoidUnsafeBackTracking)
void ensureInternalRouter()
const std::vector< _RailEdge * > & getRailEdges()
RailEdge< E, V > _RailEdge
static double myReversalPenalty
static const E * getStraightPredecessor(const E *edge, std::vector< const E * > &prevRoute, int backIndex)
static double getTravelTimeStatic(const RailEdge< E, V > *const edge, const V *const veh, double time)
std::map< const E *, double > Prohibitions
SUMOAbstractRouter< E, V > * clone()
const E * myLastFrom
track previous edge for correct bulk routing
virtual ~RailwayRouter()
Destructor.
RailwayRouter(const std::vector< E * > &edges, bool unbuildIsWarning, typename SUMOAbstractRouter< E, V >::Operation effortOperation, typename SUMOAbstractRouter< E, V >::Operation ttOperation=nullptr, bool silent=false, bool havePermissions=false, const bool haveRestrictions=false, double maxTrainLength=5000, double reversalPenalty=60)
Constructor.
MsgHandler *const myErrorMsgHandler
the handler for routing errors
const bool myHavePermissions
whether edge permissions need to be considered
virtual void setBulkMode(const bool mode)
void updateViaCost(const E *const prev, const E *const e, const V *const v, double &time, double &effort, double &length) const
double getEffort(const E *const e, const V *const v, double t) const
virtual void prohibit(const Prohibitions &toProhibit)
Prohibitions myProhibited
The list of explicitly prohibited edges and estimated end time of prohibition.
const bool myHaveRestrictions
whether edge restrictions need to be considered
virtual bool compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into, bool silent=false)=0
Builds the route between the given edges using the minimum effort at the given time The definition of...
virtual double recomputeCosts(const std::vector< const E * > &edges, const V *const v, SUMOTime msTime, double *lengthp=nullptr) const