1414#include " RoadJunction.hpp"
1515#include " Intersection.hpp"
1616#include " TrafficLight.hpp"
17+ #include " PathCollection.hpp"
1718#include " Roundabout.hpp"
1819#include " Station.hpp"
1920#include " Street.hpp"
@@ -204,10 +205,9 @@ namespace dsf::mobility {
204205 // / @throws std::invalid_argument if the dynamics function is not callable with a const reference
205206 template <typename DynamicsFunc>
206207 requires (std::is_invocable_r_v<double , DynamicsFunc, std::unique_ptr<Street> const &>)
207- std::unordered_map<Id, std::vector<Id>> allPathsTo (
208- Id const targetId,
209- DynamicsFunc getEdgeWeight,
210- double const threshold = 1e-9 ) const ;
208+ PathCollection allPathsTo (Id const targetId,
209+ DynamicsFunc getEdgeWeight,
210+ double const threshold = 1e-9 ) const ;
211211
212212 // / @brief Find the shortest path between two nodes using Dijkstra's algorithm
213213 // / @tparam DynamicsFunc A callable type that takes a const reference to a Street and returns a double representing the edge weight
@@ -221,11 +221,10 @@ namespace dsf::mobility {
221221 // / Like allPathsTo, this method tracks all equivalent paths within the threshold, allowing for multiple next hops per node.
222222 template <typename DynamicsFunc>
223223 requires (std::is_invocable_r_v<double , DynamicsFunc, std::unique_ptr<Street> const &>)
224- std::unordered_map<Id, std::vector<Id>> shortestPath (
225- Id const sourceId,
226- Id const targetId,
227- DynamicsFunc getEdgeWeight,
228- double const threshold = 1e-9 ) const ;
224+ PathCollection shortestPath (Id const sourceId,
225+ Id const targetId,
226+ DynamicsFunc getEdgeWeight,
227+ double const threshold = 1e-9 ) const ;
229228 };
230229
231230 template <typename ... TArgs>
@@ -312,16 +311,17 @@ namespace dsf::mobility {
312311
313312 template <typename DynamicsFunc>
314313 requires (std::is_invocable_r_v<double , DynamicsFunc, std::unique_ptr<Street> const &>)
315- std::unordered_map<Id, std::vector<Id>> RoadNetwork::allPathsTo (
316- Id const targetId, DynamicsFunc f, double const threshold) const {
314+ PathCollection RoadNetwork::allPathsTo (Id const targetId,
315+ DynamicsFunc f,
316+ double const threshold) const {
317317 // Check if source node exists
318318 auto const & nodes = this ->nodes ();
319319
320320 // Distance from each node to the source (going backward)
321321 std::unordered_map<Id, double > distToTarget;
322322 distToTarget.reserve (nNodes ());
323323 // Next hop from each node toward the source
324- std::unordered_map<Id, std::vector<Id>> nextHopsToTarget;
324+ PathCollection nextHopsToTarget;
325325
326326 // Priority queue: pair<distance, nodeId> (min-heap)
327327 std::priority_queue<std::pair<double , Id>,
@@ -383,7 +383,7 @@ namespace dsf::mobility {
383383 }
384384
385385 // Build result: only include reachable nodes (excluding source)
386- std::unordered_map<Id, std::vector<Id>> result;
386+ PathCollection result;
387387 for (auto const & [nodeId, hops] : nextHopsToTarget) {
388388 if (nodeId != targetId &&
389389 distToTarget[nodeId] != std::numeric_limits<double >::infinity () &&
@@ -397,11 +397,13 @@ namespace dsf::mobility {
397397
398398 template <typename DynamicsFunc>
399399 requires (std::is_invocable_r_v<double , DynamicsFunc, std::unique_ptr<Street> const &>)
400- std::unordered_map<Id, std::vector<Id>> RoadNetwork::shortestPath (
401- Id const sourceId, Id const targetId, DynamicsFunc f, double const threshold) const {
400+ PathCollection RoadNetwork::shortestPath (Id const sourceId,
401+ Id const targetId,
402+ DynamicsFunc f,
403+ double const threshold) const {
402404 // If source equals target, return empty map (no intermediate hops needed)
403405 if (sourceId == targetId) {
404- return std::unordered_map<Id, std::vector<Id>> {};
406+ return PathCollection {};
405407 }
406408 // Check if source node exists
407409 if (!this ->nodes ().contains (sourceId)) {
@@ -419,7 +421,7 @@ namespace dsf::mobility {
419421 std::unordered_map<Id, double > distToTarget;
420422 distToTarget.reserve (nNodes ());
421423 // Next hop from each node toward the target
422- std::unordered_map<Id, std::vector<Id>> nextHopsToTarget;
424+ PathCollection nextHopsToTarget;
423425
424426 // Priority queue: pair<distance, nodeId> (min-heap)
425427 std::priority_queue<std::pair<double , Id>,
@@ -487,11 +489,11 @@ namespace dsf::mobility {
487489
488490 // Check if target is reachable from source
489491 if (distToTarget[sourceId] == std::numeric_limits<double >::infinity ()) {
490- return std::unordered_map<Id, std::vector<Id>> {};
492+ return PathCollection {};
491493 }
492494
493495 // Build result: only include nodes on the path from source to target
494- std::unordered_map<Id, std::vector<Id>> result;
496+ PathCollection result;
495497 std::unordered_set<Id> nodesOnPath;
496498
497499 // Start from source and traverse to target using BFS to find all nodes on valid paths
0 commit comments