Google OR-Tools v9.9
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
dag_shortest_path.cc
Go to the documentation of this file.
1// Copyright 2010-2024 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
15
16#include <limits>
17#include <vector>
18
19#include "absl/log/check.h"
20#include "absl/types/span.h"
21#include "ortools/graph/graph.h"
23
24namespace operations_research {
25
27 const int num_nodes, absl::Span<const ArcWithLength> arcs_with_length,
28 int source, int destination) {
29 using GraphType = util::StaticGraph<>;
30 using NodeIndex = GraphType::NodeIndex;
31 using ArcIndex = GraphType::ArcIndex;
32
33 GraphType graph(num_nodes, arcs_with_length.size());
34 std::vector<double> arc_lengths;
35 arc_lengths.reserve(arcs_with_length.size());
36 for (const auto& arc : arcs_with_length) {
37 graph.AddArc(arc.tail, arc.head);
38 arc_lengths.push_back(arc.length);
39 }
40 std::vector<ArcIndex> permutation;
41 graph.Build(&permutation);
42 util::Permute(permutation, &arc_lengths);
43
44 std::vector<ArcIndex> inverse_permutation(permutation.size());
45 if (!permutation.empty()) {
46 for (ArcIndex i = 0; i < permutation.size(); ++i) {
47 inverse_permutation[permutation[i]] = i;
48 }
49 }
50
51 const absl::StatusOr<std::vector<NodeIndex>> topological_order =
53 CHECK_OK(topological_order) << "arcs_with_length form a cycle.";
54
56 &graph, &arc_lengths, *topological_order);
57
58 shortest_path_on_dag.RunShortestPathOnDag({source});
59
60 if (!shortest_path_on_dag.IsReachable(destination)) {
61 return PathWithLength{.length = std::numeric_limits<double>::infinity(),
62 .arc_path = std::vector<int>(),
63 .node_path = std::vector<int>()};
64 }
65
66 std::vector<int> arc_path = shortest_path_on_dag.ArcPathTo(destination);
67 if (!inverse_permutation.empty()) {
68 for (int i = 0; i < arc_path.size(); ++i) {
69 arc_path[i] = inverse_permutation[arc_path[i]];
70 }
71 }
72 return PathWithLength{
73 .length = shortest_path_on_dag.LengthTo(destination),
74 .arc_path = arc_path,
75 .node_path = shortest_path_on_dag.NodePathTo(destination)};
76}
77
78} // namespace operations_research
double LengthTo(NodeIndex node) const
Returns the length of the shortest path from node's source to node.
std::vector< ArcIndex > ArcPathTo(NodeIndex node) const
void RunShortestPathOnDag(absl::Span< const NodeIndex > sources)
std::vector< NodeIndex > NodePathTo(NodeIndex node) const
int arc
In SWIG mode, we don't want anything besides these top-level includes.
PathWithLength ShortestPathsOnDag(const int num_nodes, absl::Span< const ArcWithLength > arcs_with_length, int source, int destination)
absl::StatusOr< std::vector< int > > FastTopologicalSort(const AdjacencyLists &adj)
void Permute(const IntVector &permutation, Array *array_to_permute)
Definition graph.h:758