better handling of trip hops with an impossibly small travel time, minor homogenization of edge case behavior of hops() and hopsFast() for hops near maxCost

This commit is contained in:
Patrick Brosi 2023-10-13 22:49:37 +02:00
parent cb606ef75f
commit f6228ee7a2
3 changed files with 28 additions and 14 deletions

View file

@ -52,6 +52,15 @@ std::map<size_t, EdgeListHops> RouterImpl<TW>::route(
size_t frTrNid = st.top(); size_t frTrNid = st.top();
st.pop(); st.pop();
const auto& frTrNd = trie->getNd(frTrNid); const auto& frTrNd = trie->getNd(frTrNid);
// determine the max speed for this hop
double maxSpeed = 0;
for (size_t nid = 0; nid < ecm.at(frTrNid).size(); nid++) {
if (!ecm.at(frTrNid)[nid].e) continue;
if (ecm.at(frTrNid)[nid].e->getFrom()->pl().getComp().maxSpeed > maxSpeed)
maxSpeed = ecm.at(frTrNid)[nid].e->getFrom()->pl().getComp().maxSpeed;
}
for (size_t toTrNid : trie->getNd(frTrNid).childs) { for (size_t toTrNid : trie->getNd(frTrNid).childs) {
CostMatrix costM, dists; CostMatrix costM, dists;
const auto& toTrNd = trie->getNd(toTrNid); const auto& toTrNd = trie->getNd(toTrNid);
@ -76,11 +85,15 @@ std::map<size_t, EdgeListHops> RouterImpl<TW>::route(
double hopDist = 0; double hopDist = 0;
if (TW::NEED_DIST) hopDist = util::geo::haversine(frTrNd.lat, frTrNd.lng, toTrNd.lat,
hopDist = util::geo::haversine(frTrNd.lat, frTrNd.lng, toTrNd.lat, toTrNd.lng);
toTrNd.lng);
uint32_t newMaxCost = TW::maxCost(avgArrT - avgDepT, rOpts); double minTime = hopDist / maxSpeed;
double hopTime = avgArrT - avgDepT;
if (hopTime < minTime) hopTime = minTime;
uint32_t newMaxCost = TW::maxCost(hopTime, rOpts);
uint32_t maxCost = newMaxCost; uint32_t maxCost = newMaxCost;
bool found = false; bool found = false;
@ -239,7 +252,6 @@ std::map<size_t, EdgeListHops> RouterImpl<TW>::route(
const double c = const double c =
EDijkstra::shortestPath(fr.e, to.e, cost, distH, &edgs); EDijkstra::shortestPath(fr.e, to.e, cost, distH, &edgs);
// c += costPr(to.e, 0, 0) * to.progr;
if (c < maxCostRtInt) { if (c < maxCostRtInt) {
// a path was found, use it // a path was found, use it
@ -370,7 +382,6 @@ void RouterImpl<TW>::hops(const EdgeCandGroup& froms, const EdgeCandGroup& tos,
for (size_t toId = 0; toId < tos.size(); toId++) { for (size_t toId = 0; toId < tos.size(); toId++) {
auto to = tos[toId]; auto to = tos[toId];
if (!to.e) continue; if (!to.e) continue;
auto costTo = costF(to.e, 0, 0);
uint32_t c = ecm[fr.e][to.e]; uint32_t c = ecm[fr.e][to.e];
@ -381,6 +392,7 @@ void RouterImpl<TW>::hops(const EdgeCandGroup& froms, const EdgeCandGroup& tos,
if (fr.e == to.e) { if (fr.e == to.e) {
if (fr.progr <= to.progr) { if (fr.progr <= to.progr) {
auto costTo = costF(to.e, 0, 0);
const uint32_t progrCFr = costFr * fr.progr; const uint32_t progrCFr = costFr * fr.progr;
const uint32_t progrCTo = costTo * to.progr; const uint32_t progrCTo = costTo * to.progr;
@ -401,13 +413,14 @@ void RouterImpl<TW>::hops(const EdgeCandGroup& froms, const EdgeCandGroup& tos,
// add progression cost on last edge // add progression cost on last edge
if (to.progr > 0) { if (to.progr > 0) {
const auto costTo = costF(to.e, 0, 0);
const uint32_t progrCTo = costTo * to.progr; const uint32_t progrCTo = costTo * to.progr;
c += progrCTo; c += progrCTo;
if (TW::NEED_DIST) dist += to.e->pl().getLength() * to.progr; if (TW::NEED_DIST) dist += to.e->pl().getLength() * to.progr;
} }
} }
if (c < maxCost) { if (c < maxCost - maxProgrStart) {
rCosts->push_back({{frId, toId}, c}); rCosts->push_back({{frId, toId}, c});
if (TW::NEED_DIST) if (TW::NEED_DIST)
dists->push_back({{frId, toId}, static_cast<uint32_t>(dist)}); dists->push_back({{frId, toId}, static_cast<uint32_t>(dist)});
@ -429,6 +442,7 @@ void RouterImpl<TW>::hopsFast(const EdgeCandGroup& froms,
std::set<trgraph::Edge*> eFrs, eTos; std::set<trgraph::Edge*> eFrs, eTos;
std::map<trgraph::Edge*, std::vector<size_t>> eFrCands, eToCands; std::map<trgraph::Edge*, std::vector<size_t>> eFrCands, eToCands;
double maxSpeed = 0; double maxSpeed = 0;
for (size_t frId = 0; frId < froms.size(); frId++) { for (size_t frId = 0; frId < froms.size(); frId++) {
if (rawInitCosts[frId] >= DBL_INF || !connected(froms[frId], tos)) continue; if (rawInitCosts[frId] >= DBL_INF || !connected(froms[frId], tos)) continue;
@ -557,9 +571,9 @@ void RouterImpl<TW>::hopsFast(const EdgeCandGroup& froms,
} }
} }
if (wrCost >= maxCost - maxProgrStart) continue; if (wrCost < maxCost - maxProgrStart) {
rCosts->push_back({{frId, toId}, wrCost});
rCosts->push_back({{frId, toId}, wrCost}); }
} }
} }
} }

View file

@ -965,8 +965,8 @@ std::vector<LINE> ShapeBuilder::getGeom(
// no hop was found, use the fallback geometry // no hop was found, use the fallback geometry
if (hop.start) { if (hop.start) {
auto l = getLine(hop.start);
if (hop.progrStart > 0) { if (hop.progrStart > 0) {
auto l = getLine(hop.start);
PolyLine<PFDL_PREC> pl(l); PolyLine<PFDL_PREC> pl(l);
const auto& seg = pl.getSegment(hop.progrStart, 1); const auto& seg = pl.getSegment(hop.progrStart, 1);
ret.push_back({seg.getLine().front(), hop.pointEnd}); ret.push_back({seg.getLine().front(), hop.pointEnd});
@ -974,8 +974,8 @@ std::vector<LINE> ShapeBuilder::getGeom(
ret.push_back({*hop.start->getFrom()->pl().getGeom(), hop.pointEnd}); ret.push_back({*hop.start->getFrom()->pl().getGeom(), hop.pointEnd});
} }
} else if (hop.end) { } else if (hop.end) {
auto l = getLine(hop.end);
if (hop.progrEnd > 0) { if (hop.progrEnd > 0) {
auto l = getLine(hop.end);
PolyLine<PFDL_PREC> pl(l); PolyLine<PFDL_PREC> pl(l);
const auto& seg = pl.getSegment(0, hop.progrEnd); const auto& seg = pl.getSegment(0, hop.progrEnd);
ret.push_back({hop.pointStart, seg.getLine().back()}); ret.push_back({hop.pointStart, seg.getLine().back()});

View file

@ -182,14 +182,14 @@ double ExpoTransWeight::weight(uint32_t c, double d, double t0, double d0,
// _____________________________________________________________________________ // _____________________________________________________________________________
uint32_t ExpoTransWeight::invWeight(double c, const RoutingOpts& rOpts) { uint32_t ExpoTransWeight::invWeight(double c, const RoutingOpts& rOpts) {
return std::round((c / rOpts.transitionPen) * 10); return std::round((c / rOpts.transitionPen) * 10.0);
} }
// _____________________________________________________________________________ // _____________________________________________________________________________
uint32_t ExpoTransWeight::maxCost(double tTime, const RoutingOpts& rOpts) { uint32_t ExpoTransWeight::maxCost(double tTime, const RoutingOpts& rOpts) {
// abort after 3 times the scheduled time, but assume a min time of // abort after 3 times the scheduled time, but assume a min time of
// 1 minute! // 1 minute!
return std::ceil(fmax(tTime, 60) * 3 * rOpts.lineUnmatchedPunishFact * return std::ceil(fmax(tTime, 60) * 3.0 * rOpts.lineUnmatchedPunishFact *
rOpts.lineNameToUnmatchedPunishFact * rOpts.lineNameToUnmatchedPunishFact *
rOpts.lineNameFromUnmatchedPunishFact * 10); rOpts.lineNameFromUnmatchedPunishFact * 10);
} }