From 08b0685ad1f1d87d3c43fcd16520af9a7d36c7f5 Mon Sep 17 00:00:00 2001 From: Alexander Held Date: Tue, 13 Oct 2020 20:27:20 +0200 Subject: [PATCH] Optional transit line penalties when no explicit line was given (#19) * Enable transit line penalties also when no explicit line was given Currently, if no transit line is given, all edges get penalty factor 0 regardless of whether there are transit lines following the edge or not. The change introduced in this commit will give penalty factor 0 if there is at least one transit line following the edge and penalty factor 1 if there are no tranist lines at all following the edge. Behavior in the case when a transit line is given is untouched. This should improve routing results by preferring edges with associated transit lines. This used to be the behaviour before some refactoring. Maybe it was broken unintentionally. --- pfaedle.cfg | 30 ++++++++++++++++++++++++++ src/pfaedle/config/MotConfigReader.cpp | 6 ++++++ src/pfaedle/router/Misc.h | 6 +++++- src/pfaedle/router/Router.cpp | 15 +++++++------ src/pfaedle/router/Router.h | 4 ++-- 5 files changed, 52 insertions(+), 9 deletions(-) diff --git a/pfaedle.cfg b/pfaedle.cfg index 346f463..8840534 100644 --- a/pfaedle.cfg +++ b/pfaedle.cfg @@ -411,6 +411,11 @@ routing_one_way_meter_punish_fac: 1 # information routing_line_unmatched_punish_fac: 1 +# Punishment factor for every meter a vehicle +# travels through an edge without any line +# information when no specific line was requested +# routing_no_lines_punish_fac: 0 + # special line normalization for trains line_normalize_chain: , -> ' '; @@ -793,6 +798,11 @@ routing_one_way_edge_punish: 5000 # information # routing_line_unmatched_punish_fac: 1.75 +# Punishment factor for every meter a vehicle +# travels through an edge without any line +# information when no specific line was requested +# routing_no_lines_punish_fac: 0 + [coach] # OSM entities to keep on different levels, as k=v. Applies @@ -1011,6 +1021,11 @@ routing_one_way_meter_punish_fac: 1 # information routing_line_unmatched_punish_fac: 0.5 +# Punishment factor for every meter a vehicle +# travels through an edge without any line +# information when no specific line was requested +# routing_no_lines_punish_fac: 0 + [gondola] # OSM entities to keep on different levels, as k=v. Applies @@ -1152,6 +1167,11 @@ routing_one_way_meter_punish_fac: 1 # information routing_line_unmatched_punish_fac: 0.5 +# Punishment factor for every meter a vehicle +# travels through an edge without any line +# information when no specific line was requested +# routing_no_lines_punish_fac: 0 + [funicular] # OSM entities to keep on different levels, as k=v. Applies @@ -1324,6 +1344,11 @@ routing_one_way_meter_punish_fac: 1 # information routing_line_unmatched_punish_fac: 0.5 +# Punishment factor for every meter a vehicle +# travels through an edge without any line +# information when no specific line was requested +# routing_no_lines_punish_fac: 0 + [ferry] # OSM entities to keep on different levels, as k=v. Applies @@ -1425,3 +1450,8 @@ routing_one_way_meter_punish_fac: 1 # information routing_line_unmatched_punish_fac: 0.5 +# Punishment factor for every meter a vehicle +# travels through an edge without any line +# information when no specific line was requested +# routing_no_lines_punish_fac: 0 + diff --git a/src/pfaedle/config/MotConfigReader.cpp b/src/pfaedle/config/MotConfigReader.cpp index bffe3a7..96fce0e 100644 --- a/src/pfaedle/config/MotConfigReader.cpp +++ b/src/pfaedle/config/MotConfigReader.cpp @@ -331,6 +331,12 @@ void MotConfigReader::parse(const std::vector& paths) { p.getDouble(secStr, "routing_line_unmatched_punish_fac"); } + if (p.hasKey(secStr, "routing_no_lines_punish_fac")) { + procedKeys.insert("routing_no_lines_punish_fac"); + curCfg.routingOpts.noLinesPunishFact = + p.getDouble(secStr, "routing_no_lines_punish_fac"); + } + if (p.hasKey(secStr, "routing_platform_unmatched_punish")) { procedKeys.insert("routing_platform_unmatched_punish"); curCfg.routingOpts.platformUnmatchedPen = diff --git a/src/pfaedle/router/Misc.h b/src/pfaedle/router/Misc.h index 5cb1862..1c69c40 100644 --- a/src/pfaedle/router/Misc.h +++ b/src/pfaedle/router/Misc.h @@ -39,6 +39,7 @@ struct RoutingOpts { oneWayPunishFac(1), oneWayEdgePunish(0), lineUnmatchedPunishFact(0.5), + noLinesPunishFact(0), platformUnmatchedPen(0), stationDistPenFactor(0), popReachEdge(true), @@ -49,6 +50,7 @@ struct RoutingOpts { double oneWayPunishFac; double oneWayEdgePunish; double lineUnmatchedPunishFact; + double noLinesPunishFact; double platformUnmatchedPen; double stationDistPenFactor; double nonOsmPen; @@ -65,6 +67,7 @@ inline bool operator==(const RoutingOpts& a, const RoutingOpts& b) { fabs(a.oneWayPunishFac - b.oneWayPunishFac) < 0.01 && fabs(a.oneWayEdgePunish - b.oneWayEdgePunish) < 0.01 && fabs(a.lineUnmatchedPunishFact - b.lineUnmatchedPunishFact) < 0.01 && + fabs(a.noLinesPunishFact - b.noLinesPunishFact) < 0.01 && fabs(a.platformUnmatchedPen - b.platformUnmatchedPen) < 0.01 && fabs(a.stationDistPenFactor - b.stationDistPenFactor) < 0.01 && fabs(a.nonOsmPen - b.nonOsmPen) < 0.01 && @@ -86,7 +89,7 @@ struct EdgeCost { double mDistLvl4, double mDistLvl5, double mDistLvl6, double mDistLvl7, uint32_t fullTurns, int32_t passThru, double oneWayMeters, size_t oneWayEdges, double lineUnmatchedMeters, - double reachPen, const RoutingOpts* o) { + double noLinesMeters, double reachPen, const RoutingOpts* o) { if (!o) { _cost = mDist + reachPen; } else { @@ -97,6 +100,7 @@ struct EdgeCost { oneWayMeters * o->oneWayPunishFac + oneWayEdges * o->oneWayEdgePunish + lineUnmatchedMeters * o->lineUnmatchedPunishFact + + noLinesMeters * o->noLinesPunishFact + fullTurns * o->fullTurnPunishFac + passThru * o->passThruStationsPunish + reachPen; } diff --git a/src/pfaedle/router/Router.cpp b/src/pfaedle/router/Router.cpp index 38e49c7..c2e0055 100644 --- a/src/pfaedle/router/Router.cpp +++ b/src/pfaedle/router/Router.cpp @@ -60,7 +60,7 @@ EdgeCost NCostFunc::operator()(const trgraph::Node* from, e->pl().lvl() == 5 ? e->pl().getLength() : 0, e->pl().lvl() == 6 ? e->pl().getLength() : 0, e->pl().lvl() == 7 ? e->pl().getLength() : 0, 0, stationSkip, - e->pl().getLength() * oneway, oneway, 0, 0, &_rOpts); + e->pl().getLength() * oneway, oneway, 0, 0, 0, &_rOpts); } // _____________________________________________________________________________ @@ -92,6 +92,8 @@ EdgeCost CostFunc::operator()(const trgraph::Edge* from, const trgraph::Node* n, } double transitLinePen = transitLineCmp(from->pl()); + bool noLines = (_rAttrs.shortName.empty() && _rAttrs.toString.empty() && + _rAttrs.fromString.empty() && from->pl().getLines().empty()); return EdgeCost(from->pl().lvl() == 0 ? from->pl().getLength() : 0, from->pl().lvl() == 1 ? from->pl().getLength() : 0, @@ -102,7 +104,8 @@ EdgeCost CostFunc::operator()(const trgraph::Edge* from, const trgraph::Node* n, from->pl().lvl() == 6 ? from->pl().getLength() : 0, from->pl().lvl() == 7 ? from->pl().getLength() : 0, fullTurns, stationSkip, from->pl().getLength() * oneway, oneway, - from->pl().getLength() * transitLinePen, 0, &_rOpts); + from->pl().getLength() * transitLinePen, + noLines ? from->pl().getLength() : 0, 0, &_rOpts); } // _____________________________________________________________________________ @@ -173,7 +176,7 @@ EdgeCost DistHeur::operator()(const trgraph::Edge* a, double cur = webMercMeterDist(*a->getFrom()->pl().getGeom(), _center) * _rOpts.levelPunish[_lvl]; - return EdgeCost(cur - _maxCentD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + return EdgeCost(cur - _maxCentD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); } // _____________________________________________________________________________ @@ -182,7 +185,7 @@ EdgeCost NDistHeur::operator()(const trgraph::Node* a, UNUSED(b); double cur = webMercMeterDist(*a->pl().getGeom(), _center); - return EdgeCost(cur - _maxCentD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + return EdgeCost(cur - _maxCentD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); } // _____________________________________________________________________________ @@ -407,7 +410,7 @@ EdgeListHops Router::route(const EdgeCandRoute& route, nodes[e] = cgraph->addNd(route[0][i].e->getFrom()); cgraph->addEdg(source, nodes[e]) ->pl() - .setCost(EdgeCost(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + .setCost(EdgeCost(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, route[0][i].pen, 0)); } @@ -474,7 +477,7 @@ EdgeListHops Router::route(const EdgeCandRoute& route, << TOOK(t1, TIME()) << "ms (tput: " << itPerSec << " its/ms)"; for (auto& kv : edges) { kv.second->pl().setCost( - EdgeCost(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pens[kv.first], 0) + + EdgeCost(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pens[kv.first], 0) + costs[kv.first]); if (rOpts.popReachEdge && kv.second->pl().getEdges()->size()) { diff --git a/src/pfaedle/router/Router.h b/src/pfaedle/router/Router.h index cdd72f4..74bf581 100644 --- a/src/pfaedle/router/Router.h +++ b/src/pfaedle/router/Router.h @@ -54,7 +54,7 @@ struct CostFunc _rOpts(rOpts), _res(res), _tgGrp(tgGrp), - _inf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, max, 0) {} + _inf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, max, 0) {} const RoutingAttrs& _rAttrs; const RoutingOpts& _rOpts; @@ -77,7 +77,7 @@ struct NCostFunc _rOpts(rOpts), _res(res), _tgGrp(tgGrp), - _inf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + _inf(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, std::numeric_limits::infinity(), 0) {} const RoutingAttrs& _rAttrs;