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.
This commit is contained in:
Alexander Held 2020-10-13 20:27:20 +02:00 committed by GitHub
parent e06c15656b
commit 08b0685ad1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 9 deletions

View file

@ -411,6 +411,11 @@ routing_one_way_meter_punish_fac: 1
# information # information
routing_line_unmatched_punish_fac: 1 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 # special line normalization for trains
line_normalize_chain: line_normalize_chain:
, -> ' '; , -> ' ';
@ -793,6 +798,11 @@ routing_one_way_edge_punish: 5000
# information # information
# routing_line_unmatched_punish_fac: 1.75 # 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] [coach]
# OSM entities to keep on different levels, as k=v. Applies # OSM entities to keep on different levels, as k=v. Applies
@ -1011,6 +1021,11 @@ routing_one_way_meter_punish_fac: 1
# information # information
routing_line_unmatched_punish_fac: 0.5 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] [gondola]
# OSM entities to keep on different levels, as k=v. Applies # OSM entities to keep on different levels, as k=v. Applies
@ -1152,6 +1167,11 @@ routing_one_way_meter_punish_fac: 1
# information # information
routing_line_unmatched_punish_fac: 0.5 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] [funicular]
# OSM entities to keep on different levels, as k=v. Applies # OSM entities to keep on different levels, as k=v. Applies
@ -1324,6 +1344,11 @@ routing_one_way_meter_punish_fac: 1
# information # information
routing_line_unmatched_punish_fac: 0.5 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] [ferry]
# OSM entities to keep on different levels, as k=v. Applies # OSM entities to keep on different levels, as k=v. Applies
@ -1425,3 +1450,8 @@ routing_one_way_meter_punish_fac: 1
# information # information
routing_line_unmatched_punish_fac: 0.5 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

View file

@ -331,6 +331,12 @@ void MotConfigReader::parse(const std::vector<std::string>& paths) {
p.getDouble(secStr, "routing_line_unmatched_punish_fac"); 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")) { if (p.hasKey(secStr, "routing_platform_unmatched_punish")) {
procedKeys.insert("routing_platform_unmatched_punish"); procedKeys.insert("routing_platform_unmatched_punish");
curCfg.routingOpts.platformUnmatchedPen = curCfg.routingOpts.platformUnmatchedPen =

View file

@ -39,6 +39,7 @@ struct RoutingOpts {
oneWayPunishFac(1), oneWayPunishFac(1),
oneWayEdgePunish(0), oneWayEdgePunish(0),
lineUnmatchedPunishFact(0.5), lineUnmatchedPunishFact(0.5),
noLinesPunishFact(0),
platformUnmatchedPen(0), platformUnmatchedPen(0),
stationDistPenFactor(0), stationDistPenFactor(0),
popReachEdge(true), popReachEdge(true),
@ -49,6 +50,7 @@ struct RoutingOpts {
double oneWayPunishFac; double oneWayPunishFac;
double oneWayEdgePunish; double oneWayEdgePunish;
double lineUnmatchedPunishFact; double lineUnmatchedPunishFact;
double noLinesPunishFact;
double platformUnmatchedPen; double platformUnmatchedPen;
double stationDistPenFactor; double stationDistPenFactor;
double nonOsmPen; double nonOsmPen;
@ -65,6 +67,7 @@ inline bool operator==(const RoutingOpts& a, const RoutingOpts& b) {
fabs(a.oneWayPunishFac - b.oneWayPunishFac) < 0.01 && fabs(a.oneWayPunishFac - b.oneWayPunishFac) < 0.01 &&
fabs(a.oneWayEdgePunish - b.oneWayEdgePunish) < 0.01 && fabs(a.oneWayEdgePunish - b.oneWayEdgePunish) < 0.01 &&
fabs(a.lineUnmatchedPunishFact - b.lineUnmatchedPunishFact) < 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.platformUnmatchedPen - b.platformUnmatchedPen) < 0.01 &&
fabs(a.stationDistPenFactor - b.stationDistPenFactor) < 0.01 && fabs(a.stationDistPenFactor - b.stationDistPenFactor) < 0.01 &&
fabs(a.nonOsmPen - b.nonOsmPen) < 0.01 && fabs(a.nonOsmPen - b.nonOsmPen) < 0.01 &&
@ -86,7 +89,7 @@ struct EdgeCost {
double mDistLvl4, double mDistLvl5, double mDistLvl6, double mDistLvl4, double mDistLvl5, double mDistLvl6,
double mDistLvl7, uint32_t fullTurns, int32_t passThru, double mDistLvl7, uint32_t fullTurns, int32_t passThru,
double oneWayMeters, size_t oneWayEdges, double lineUnmatchedMeters, double oneWayMeters, size_t oneWayEdges, double lineUnmatchedMeters,
double reachPen, const RoutingOpts* o) { double noLinesMeters, double reachPen, const RoutingOpts* o) {
if (!o) { if (!o) {
_cost = mDist + reachPen; _cost = mDist + reachPen;
} else { } else {
@ -97,6 +100,7 @@ struct EdgeCost {
oneWayMeters * o->oneWayPunishFac + oneWayMeters * o->oneWayPunishFac +
oneWayEdges * o->oneWayEdgePunish + oneWayEdges * o->oneWayEdgePunish +
lineUnmatchedMeters * o->lineUnmatchedPunishFact + lineUnmatchedMeters * o->lineUnmatchedPunishFact +
noLinesMeters * o->noLinesPunishFact +
fullTurns * o->fullTurnPunishFac + fullTurns * o->fullTurnPunishFac +
passThru * o->passThruStationsPunish + reachPen; passThru * o->passThruStationsPunish + reachPen;
} }

View file

@ -60,7 +60,7 @@ EdgeCost NCostFunc::operator()(const trgraph::Node* from,
e->pl().lvl() == 5 ? e->pl().getLength() : 0, e->pl().lvl() == 5 ? e->pl().getLength() : 0,
e->pl().lvl() == 6 ? e->pl().getLength() : 0, e->pl().lvl() == 6 ? e->pl().getLength() : 0,
e->pl().lvl() == 7 ? e->pl().getLength() : 0, 0, stationSkip, 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()); 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, return EdgeCost(from->pl().lvl() == 0 ? from->pl().getLength() : 0,
from->pl().lvl() == 1 ? 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() == 6 ? from->pl().getLength() : 0,
from->pl().lvl() == 7 ? from->pl().getLength() : 0, fullTurns, from->pl().lvl() == 7 ? from->pl().getLength() : 0, fullTurns,
stationSkip, from->pl().getLength() * oneway, oneway, 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) * double cur = webMercMeterDist(*a->getFrom()->pl().getGeom(), _center) *
_rOpts.levelPunish[_lvl]; _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); UNUSED(b);
double cur = webMercMeterDist(*a->pl().getGeom(), _center); 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()); nodes[e] = cgraph->addNd(route[0][i].e->getFrom());
cgraph->addEdg(source, nodes[e]) cgraph->addEdg(source, nodes[e])
->pl() ->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)); route[0][i].pen, 0));
} }
@ -474,7 +477,7 @@ EdgeListHops Router::route(const EdgeCandRoute& route,
<< TOOK(t1, TIME()) << "ms (tput: " << itPerSec << " its/ms)"; << TOOK(t1, TIME()) << "ms (tput: " << itPerSec << " its/ms)";
for (auto& kv : edges) { for (auto& kv : edges) {
kv.second->pl().setCost( 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]); costs[kv.first]);
if (rOpts.popReachEdge && kv.second->pl().getEdges()->size()) { if (rOpts.popReachEdge && kv.second->pl().getEdges()->size()) {

View file

@ -54,7 +54,7 @@ struct CostFunc
_rOpts(rOpts), _rOpts(rOpts),
_res(res), _res(res),
_tgGrp(tgGrp), _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 RoutingAttrs& _rAttrs;
const RoutingOpts& _rOpts; const RoutingOpts& _rOpts;
@ -77,7 +77,7 @@ struct NCostFunc
_rOpts(rOpts), _rOpts(rOpts),
_res(res), _res(res),
_tgGrp(tgGrp), _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<double>::infinity(), 0) {} std::numeric_limits<double>::infinity(), 0) {}
const RoutingAttrs& _rAttrs; const RoutingAttrs& _rAttrs;