20#include "absl/log/check.h"
21#include "absl/types/span.h"
34struct ShortestPathOnDagProblem {
41ShortestPathOnDagProblem ReadProblem(
42 const int num_nodes, absl::Span<const ArcWithLength> arcs_with_length) {
43 GraphType
graph(num_nodes, arcs_with_length.size());
46 for (
const auto&
arc : arcs_with_length) {
50 std::vector<ArcIndex> permutation;
51 graph.Build(&permutation);
55 if (!permutation.empty()) {
56 for (
ArcIndex i = 0;
i < permutation.size(); ++
i) {
65 return ShortestPathOnDagProblem{
66 .graph = std::move(
graph),
73 std::vector<ArcIndex>& arc_path) {
77 for (
int i = 0;
i < arc_path.size(); ++
i) {
85 const int num_nodes, absl::Span<const ArcWithLength> arcs_with_length,
86 const int source,
const int destination) {
87 const ShortestPathOnDagProblem problem =
88 ReadProblem(num_nodes, arcs_with_length);
91 &problem.graph, &problem.arc_lengths, problem.topological_order);
94 if (!shortest_path_on_dag.
IsReachable(destination)) {
95 return PathWithLength{.length = std::numeric_limits<double>::infinity()};
98 std::vector<int> arc_path = shortest_path_on_dag.
ArcPathTo(destination);
99 GetOriginalArcPath(problem.original_arc_indices, arc_path);
101 .length = shortest_path_on_dag.
LengthTo(destination),
102 .arc_path = std::move(arc_path),
103 .node_path = shortest_path_on_dag.
NodePathTo(destination)};
107 const int num_nodes, absl::Span<const ArcWithLength> arcs_with_length,
108 const int source,
const int destination,
const int path_count) {
109 const ShortestPathOnDagProblem problem =
110 ReadProblem(num_nodes, arcs_with_length);
113 &problem.graph, &problem.arc_lengths, problem.topological_order,
117 if (!shortest_paths_on_dag.
IsReachable(destination)) {
118 return {
PathWithLength{.length = std::numeric_limits<double>::infinity()}};
121 std::vector<double> lengths = shortest_paths_on_dag.
LengthsTo(destination);
122 std::vector<std::vector<ArcIndex>> arc_paths =
123 shortest_paths_on_dag.
ArcPathsTo(destination);
124 std::vector<std::vector<NodeIndex>> node_paths =
126 std::vector<PathWithLength> paths;
127 paths.reserve(lengths.size());
128 for (
int k = 0; k < lengths.size(); ++k) {
129 GetOriginalArcPath(problem.original_arc_indices, arc_paths[k]);
131 .arc_path = std::move(arc_paths[k]),
132 .node_path = std::move(node_paths[k])});
bool IsReachable(NodeIndex node) const
void RunKShortestPathOnDag(absl::Span< const NodeIndex > sources)
std::vector< std::vector< ArcIndex > > ArcPathsTo(NodeIndex node) const
std::vector< std::vector< NodeIndex > > NodePathsTo(NodeIndex node) const
std::vector< double > LengthsTo(NodeIndex node) const
double LengthTo(NodeIndex node) const
Returns the length of the shortest path from node's source to node.
bool IsReachable(NodeIndex node) const
std::vector< ArcIndex > ArcPathTo(NodeIndex node) const
void RunShortestPathOnDag(absl::Span< const NodeIndex > sources)
std::vector< NodeIndex > NodePathTo(NodeIndex node) const
std::vector< ArcIndex > original_arc_indices
std::vector< NodeIndex > topological_order
std::vector< double > arc_lengths
In SWIG mode, we don't want anything besides these top-level includes.
std::vector< PathWithLength > KShortestPathsOnDag(const int num_nodes, absl::Span< const ArcWithLength > arcs_with_length, const int source, const int destination, const int path_count)
PathWithLength ShortestPathsOnDag(const int num_nodes, absl::Span< const ArcWithLength > arcs_with_length, const int source, const int destination)
absl::StatusOr< std::vector< int > > FastTopologicalSort(const AdjacencyLists &adj)
void Permute(const IntVector &permutation, Array *array_to_permute)