|
19 | 19 |
|
20 | 20 | // Use multipath SPF DAG for spur enumeration |
21 | 21 | #include "netgraph/core/shortest_paths.hpp" |
| 22 | +#include "netgraph/core/cost_utils.hpp" |
22 | 23 |
|
23 | 24 | namespace netgraph::core { |
24 | 25 |
|
@@ -80,7 +81,7 @@ static std::optional<Path> dijkstra_single(const StrictMultiDiGraph& g, NodeId s |
80 | 81 | } |
81 | 82 | } |
82 | 83 | if (best_eid >= 0) { |
83 | | - Cost nd = static_cast<Cost>(d_u + min_edge_cost); |
| 84 | + Cost nd = saturating_cost_add(d_u, min_edge_cost); |
84 | 85 | auto vi = static_cast<std::size_t>(v); |
85 | 86 | if (nd < dist[vi]) { dist[vi] = nd; parent[vi] = u; via[vi] = best_eid; pq.emplace(nd, v); } |
86 | 87 | } |
@@ -197,7 +198,9 @@ std::vector<std::pair<std::vector<Cost>, PredDAG>> k_shortest_paths( |
197 | 198 | dist[static_cast<std::size_t>(P.nodes.front())] = 0; |
198 | 199 | for (std::size_t i = 1; i < P.nodes.size(); ++i) { |
199 | 200 | auto u = P.nodes[i-1]; auto v = P.nodes[i]; auto e = P.edges[i-1]; |
200 | | - dist[static_cast<std::size_t>(v)] = dist[static_cast<std::size_t>(u)] + static_cast<Cost>(cost_view[static_cast<std::size_t>(e)]); |
| 201 | + dist[static_cast<std::size_t>(v)] = saturating_cost_add( |
| 202 | + dist[static_cast<std::size_t>(u)], |
| 203 | + static_cast<Cost>(cost_view[static_cast<std::size_t>(e)])); |
201 | 204 | dag.parent_offsets[static_cast<std::size_t>(v+1)] = 1; |
202 | 205 | } |
203 | 206 | for (std::size_t v = 1; v < dag.parent_offsets.size(); ++v) dag.parent_offsets[v] += dag.parent_offsets[v-1]; |
@@ -234,7 +237,9 @@ std::vector<std::pair<std::vector<Cost>, PredDAG>> k_shortest_paths( |
234 | 237 | for (std::size_t idx = 1; idx < last.nodes.size(); ++idx) { |
235 | 238 | // edge at idx-1 |
236 | 239 | auto e = last.edges[idx - 1]; |
237 | | - prefix_cost[idx] = prefix_cost[idx - 1] + static_cast<Cost>(cost_view[static_cast<std::size_t>(e)]); |
| 240 | + prefix_cost[idx] = saturating_cost_add( |
| 241 | + prefix_cost[idx - 1], |
| 242 | + static_cast<Cost>(cost_view[static_cast<std::size_t>(e)])); |
238 | 243 | } |
239 | 244 | // Spur node positions 0..len-2 |
240 | 245 | for (std::size_t j = 0; j + 1 < last.nodes.size(); ++j) { |
@@ -300,7 +305,11 @@ std::vector<std::pair<std::vector<Cost>, PredDAG>> k_shortest_paths( |
300 | 305 | for (auto e : spur_edges) cand_edges.push_back(e); |
301 | 306 | // Compute candidate cost as prefix_cost[j] + sum(spur_edges) |
302 | 307 | Cost cand_cost = prefix_cost[j]; |
303 | | - for (auto e : spur_edges) cand_cost += static_cast<Cost>(cost_view[static_cast<std::size_t>(e)]); |
| 308 | + for (auto e : spur_edges) { |
| 309 | + cand_cost = saturating_cost_add( |
| 310 | + cand_cost, |
| 311 | + static_cast<Cost>(cost_view[static_cast<std::size_t>(e)])); |
| 312 | + } |
304 | 313 | if (cand_cost > max_cost) continue; |
305 | 314 | auto sig = path_signature(cand_edges); |
306 | 315 | if (unique && visited.find(sig) != visited.end()) continue; |
@@ -332,7 +341,9 @@ std::vector<std::pair<std::vector<Cost>, PredDAG>> k_shortest_paths( |
332 | 341 | dist[static_cast<std::size_t>(P.nodes.front())] = 0; |
333 | 342 | for (std::size_t i = 1; i < P.nodes.size(); ++i) { |
334 | 343 | auto u = P.nodes[i-1]; auto v = P.nodes[i]; auto e = P.edges[i-1]; |
335 | | - dist[static_cast<std::size_t>(v)] = dist[static_cast<std::size_t>(u)] + static_cast<Cost>(cost_view[static_cast<std::size_t>(e)]); |
| 344 | + dist[static_cast<std::size_t>(v)] = saturating_cost_add( |
| 345 | + dist[static_cast<std::size_t>(u)], |
| 346 | + static_cast<Cost>(cost_view[static_cast<std::size_t>(e)])); |
336 | 347 | dag.parent_offsets[static_cast<std::size_t>(v+1)] = 1; |
337 | 348 | } |
338 | 349 | for (std::size_t v = 1; v < dag.parent_offsets.size(); ++v) dag.parent_offsets[v] += dag.parent_offsets[v-1]; |
|
0 commit comments