From f6228ee7a223936d57ea319cb94d36b6e73f9825 Mon Sep 17 00:00:00 2001 From: Patrick Brosi Date: Fri, 13 Oct 2023 22:49:37 +0200 Subject: [PATCH] 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 --- src/pfaedle/router/Router.tpp | 34 ++++++++++++++++++++--------- src/pfaedle/router/ShapeBuilder.cpp | 4 ++-- src/pfaedle/router/Weights.cpp | 4 ++-- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/pfaedle/router/Router.tpp b/src/pfaedle/router/Router.tpp index 693f0a4..f9b2a7b 100644 --- a/src/pfaedle/router/Router.tpp +++ b/src/pfaedle/router/Router.tpp @@ -52,6 +52,15 @@ std::map RouterImpl::route( size_t frTrNid = st.top(); st.pop(); 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) { CostMatrix costM, dists; const auto& toTrNd = trie->getNd(toTrNid); @@ -76,11 +85,15 @@ std::map RouterImpl::route( double hopDist = 0; - if (TW::NEED_DIST) - hopDist = util::geo::haversine(frTrNd.lat, frTrNd.lng, toTrNd.lat, - toTrNd.lng); + hopDist = util::geo::haversine(frTrNd.lat, frTrNd.lng, toTrNd.lat, + 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; bool found = false; @@ -239,7 +252,6 @@ std::map RouterImpl::route( const double c = EDijkstra::shortestPath(fr.e, to.e, cost, distH, &edgs); - // c += costPr(to.e, 0, 0) * to.progr; if (c < maxCostRtInt) { // a path was found, use it @@ -370,7 +382,6 @@ void RouterImpl::hops(const EdgeCandGroup& froms, const EdgeCandGroup& tos, for (size_t toId = 0; toId < tos.size(); toId++) { auto to = tos[toId]; if (!to.e) continue; - auto costTo = costF(to.e, 0, 0); uint32_t c = ecm[fr.e][to.e]; @@ -381,6 +392,7 @@ void RouterImpl::hops(const EdgeCandGroup& froms, const EdgeCandGroup& tos, if (fr.e == to.e) { if (fr.progr <= to.progr) { + auto costTo = costF(to.e, 0, 0); const uint32_t progrCFr = costFr * fr.progr; const uint32_t progrCTo = costTo * to.progr; @@ -401,13 +413,14 @@ void RouterImpl::hops(const EdgeCandGroup& froms, const EdgeCandGroup& tos, // add progression cost on last edge if (to.progr > 0) { + const auto costTo = costF(to.e, 0, 0); const uint32_t progrCTo = costTo * to.progr; c += progrCTo; if (TW::NEED_DIST) dist += to.e->pl().getLength() * to.progr; } } - if (c < maxCost) { + if (c < maxCost - maxProgrStart) { rCosts->push_back({{frId, toId}, c}); if (TW::NEED_DIST) dists->push_back({{frId, toId}, static_cast(dist)}); @@ -429,6 +442,7 @@ void RouterImpl::hopsFast(const EdgeCandGroup& froms, std::set eFrs, eTos; std::map> eFrCands, eToCands; + double maxSpeed = 0; for (size_t frId = 0; frId < froms.size(); frId++) { if (rawInitCosts[frId] >= DBL_INF || !connected(froms[frId], tos)) continue; @@ -557,9 +571,9 @@ void RouterImpl::hopsFast(const EdgeCandGroup& froms, } } - if (wrCost >= maxCost - maxProgrStart) continue; - - rCosts->push_back({{frId, toId}, wrCost}); + if (wrCost < maxCost - maxProgrStart) { + rCosts->push_back({{frId, toId}, wrCost}); + } } } } diff --git a/src/pfaedle/router/ShapeBuilder.cpp b/src/pfaedle/router/ShapeBuilder.cpp index aa27cca..5b72b2d 100644 --- a/src/pfaedle/router/ShapeBuilder.cpp +++ b/src/pfaedle/router/ShapeBuilder.cpp @@ -965,8 +965,8 @@ std::vector ShapeBuilder::getGeom( // no hop was found, use the fallback geometry if (hop.start) { - auto l = getLine(hop.start); if (hop.progrStart > 0) { + auto l = getLine(hop.start); PolyLine pl(l); const auto& seg = pl.getSegment(hop.progrStart, 1); ret.push_back({seg.getLine().front(), hop.pointEnd}); @@ -974,8 +974,8 @@ std::vector ShapeBuilder::getGeom( ret.push_back({*hop.start->getFrom()->pl().getGeom(), hop.pointEnd}); } } else if (hop.end) { - auto l = getLine(hop.end); if (hop.progrEnd > 0) { + auto l = getLine(hop.end); PolyLine pl(l); const auto& seg = pl.getSegment(0, hop.progrEnd); ret.push_back({hop.pointStart, seg.getLine().back()}); diff --git a/src/pfaedle/router/Weights.cpp b/src/pfaedle/router/Weights.cpp index 750cad7..4b96918 100644 --- a/src/pfaedle/router/Weights.cpp +++ b/src/pfaedle/router/Weights.cpp @@ -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) { - return std::round((c / rOpts.transitionPen) * 10); + return std::round((c / rOpts.transitionPen) * 10.0); } // _____________________________________________________________________________ uint32_t ExpoTransWeight::maxCost(double tTime, const RoutingOpts& rOpts) { // abort after 3 times the scheduled time, but assume a min time of // 1 minute! - return std::ceil(fmax(tTime, 60) * 3 * rOpts.lineUnmatchedPunishFact * + return std::ceil(fmax(tTime, 60) * 3.0 * rOpts.lineUnmatchedPunishFact * rOpts.lineNameToUnmatchedPunishFact * rOpts.lineNameFromUnmatchedPunishFact * 10); }