diff --git a/ortools/graph/BUILD.bazel b/ortools/graph/BUILD.bazel index 1de87e6152..15cc51bd01 100644 --- a/ortools/graph/BUILD.bazel +++ b/ortools/graph/BUILD.bazel @@ -623,6 +623,7 @@ cc_library( visibility = ["//visibility:public"], deps = [ "//ortools/base", + "//ortools/base:base_export", "//ortools/graph:iterators", "//ortools/util:permutation", "//ortools/util:zvector", diff --git a/ortools/graph/connected_components.h b/ortools/graph/connected_components.h index 1bb8a9418e..bba1ecd917 100644 --- a/ortools/graph/connected_components.h +++ b/ortools/graph/connected_components.h @@ -108,6 +108,10 @@ class DenseConnectedComponentsFinder { // Non-const because it does path compression internally. int FindRoot(int node); + // Returns the parent of the given node, in the chain towards the root of the + // set for this node. Returns the node itself if it is a root. + int GetParent(int node) const { return parent_[node]; } + // Returns the same as GetConnectedComponents(). std::vector GetComponentIds(); diff --git a/ortools/graph/samples/BUILD.bazel b/ortools/graph/samples/BUILD.bazel index 82ce60acd9..37d8c63ff0 100644 --- a/ortools/graph/samples/BUILD.bazel +++ b/ortools/graph/samples/BUILD.bazel @@ -18,6 +18,8 @@ load("@rules_java//java:java_binary.bzl", "java_binary") load("@rules_python//python:py_test.bzl", "py_test") load("//bazel:run_binary_test.bzl", "run_binary_test") +package(default_visibility = ["//visibility:public"]) + cc_test( name = "assignment_linear_sum_assignment_test", srcs = ["assignment_linear_sum_assignment.cc"], @@ -62,6 +64,7 @@ cc_test( "//ortools/base", "//ortools/graph:min_cost_flow", "@abseil-cpp//absl/base:log_severity", + "@abseil-cpp//absl/log", "@abseil-cpp//absl/log:globals", ], ) @@ -95,6 +98,7 @@ cc_test( "//ortools/base", "//ortools/graph:min_cost_flow", "@abseil-cpp//absl/base:log_severity", + "@abseil-cpp//absl/log", "@abseil-cpp//absl/log:globals", ], ) @@ -128,6 +132,7 @@ cc_test( "//ortools/base", "//ortools/graph:max_flow", "@abseil-cpp//absl/base:log_severity", + "@abseil-cpp//absl/log", "@abseil-cpp//absl/log:globals", ], ) @@ -164,6 +169,7 @@ cc_test( "//ortools/base", "//ortools/graph:min_cost_flow", "@abseil-cpp//absl/base:log_severity", + "@abseil-cpp//absl/log", "@abseil-cpp//absl/log:globals", ], ) @@ -203,6 +209,12 @@ cc_binary( ], ) +run_binary_test( + name = "dijkstra_directed_test", + binary = ":dijkstra_directed", + grep_lines = ["Shortest path length: 8"], +) + cc_binary( name = "dijkstra_undirected", srcs = ["dijkstra_undirected.cc"], @@ -213,6 +225,12 @@ cc_binary( ], ) +run_binary_test( + name = "dijkstra_undirected_test", + binary = ":dijkstra_undirected", + grep_lines = ["Shortest path length: 4"], +) + cc_binary( name = "dijkstra_one_to_all", srcs = ["dijkstra_one_to_all.cc"], @@ -224,6 +242,16 @@ cc_binary( ], ) +run_binary_test( + name = "dijkstra_one_to_all_test", + binary = ":dijkstra_one_to_all", + grep_lines = [ + "Distance to 1: 2", + "Distance to 2: 6", + "Distance to 3: 2", + ], +) + cc_binary( name = "dijkstra_sequential", srcs = ["dijkstra_sequential.cc"], @@ -236,6 +264,17 @@ cc_binary( ], ) +run_binary_test( + name = "dijkstra_sequential_test", + binary = ":dijkstra_sequential", + grep_lines = [ + "Initial distance: 200", + "Distance_2_4: 2", + "Distance_8_1: 3", + "Distance_3_7: 4", + ], +) + cc_binary( name = "dijkstra_all_pairs_shortest_paths", srcs = ["dijkstra_all_pairs_shortest_paths.cc"], @@ -251,6 +290,11 @@ cc_binary( ], ) +run_binary_test( + name = "dijkstra_all_pairs_shortest_paths_test", + binary = ":dijkstra_all_pairs_shortest_paths", +) + cc_binary( name = "dag_simple_shortest_path", srcs = ["dag_simple_shortest_path.cc"], @@ -261,6 +305,12 @@ cc_binary( ], ) +run_binary_test( + name = "dag_simple_shortest_path_test", + binary = ":dag_simple_shortest_path", + grep_lines = ["Shortest path length: 2"], +) + cc_binary( name = "dag_shortest_path_one_to_all", srcs = ["dag_shortest_path_one_to_all.cc"], @@ -276,6 +326,12 @@ cc_binary( ], ) +run_binary_test( + name = "dag_shortest_path_one_to_all_test", + binary = ":dag_shortest_path_one_to_all", + grep_lines = ["Length of shortest path to node 4: 2"], +) + cc_binary( name = "dag_shortest_path_sequential", srcs = ["dag_shortest_path_sequential.cc"], @@ -287,6 +343,17 @@ cc_binary( ], ) +run_binary_test( + name = "dag_shortest_path_sequential_test", + binary = ":dag_shortest_path_sequential", + grep_lines = [ + "Initial distance: 200", + "Distance_2_4: 2", + "Distance_8_1: 100", + "Distance_3_7: 4", + ], +) + cc_binary( name = "bfs_directed", srcs = ["bfs_directed.cc"], @@ -300,6 +367,12 @@ cc_binary( ], ) +run_binary_test( + name = "bfs_directed_test", + binary = ":bfs_directed", + grep_lines = ["Shortest path length (in arcs): 2"], +) + cc_binary( name = "bfs_undirected", srcs = ["bfs_undirected.cc"], @@ -313,6 +386,12 @@ cc_binary( ], ) +run_binary_test( + name = "bfs_undirected_test", + binary = ":bfs_undirected", + grep_lines = ["Shortest path length (in arcs): 2"], +) + cc_binary( name = "bfs_one_to_all", srcs = ["bfs_one_to_all.cc"], @@ -326,6 +405,12 @@ cc_binary( ], ) +run_binary_test( + name = "bfs_one_to_all_test", + binary = ":bfs_one_to_all", + grep_lines = ["Shortest path from 0 to 2 has length: 2"], +) + cc_binary( name = "root_a_tree", srcs = ["root_a_tree.cc"], @@ -340,6 +425,12 @@ cc_binary( ], ) +run_binary_test( + name = "root_a_tree_test", + binary = ":root_a_tree", + grep_lines = ["Depths:\n 0 -> 2"], +) + cc_binary( name = "rooted_tree_paths", srcs = ["rooted_tree_paths.cc"], @@ -353,6 +444,12 @@ cc_binary( ], ) +run_binary_test( + name = "rooted_tree_paths_test", + binary = ":rooted_tree_paths", + grep_lines = ["0 -> 4 [0, 1, 4]"], +) + cc_binary( name = "dag_simple_multiple_shortest_paths", srcs = ["dag_simple_multiple_shortest_paths.cc"], @@ -363,6 +460,15 @@ cc_binary( ], ) +run_binary_test( + name = "dag_simple_multiple_shortest_paths_test", + binary = ":dag_simple_multiple_shortest_paths", + grep_lines = [ + "#1 shortest path has length: 2", + "#2 shortest path has length: 3", + ], +) + cc_binary( name = "dag_multiple_shortest_paths_one_to_all", srcs = ["dag_multiple_shortest_paths_one_to_all.cc"], @@ -378,6 +484,15 @@ cc_binary( ], ) +run_binary_test( + name = "dag_multiple_shortest_paths_one_to_all_test", + binary = ":dag_multiple_shortest_paths_one_to_all", + grep_lines = [ + "\t#1 shortest path to node 4 has length: 2", + "\t#2 shortest path to node 4 has length: 3", + ], +) + cc_binary( name = "dag_multiple_shortest_paths_sequential", srcs = ["dag_multiple_shortest_paths_sequential.cc"], @@ -389,6 +504,23 @@ cc_binary( ], ) +run_binary_test( + name = "dag_multiple_shortest_paths_sequential_test", + binary = ":dag_multiple_shortest_paths_sequential", + grep_lines = [ + "\t#1 shortest path has length: 200", + "\t#2 shortest path has length: 202", + "\t#1 shortest path (2, 4) has length: 20", + "\t#2 shortest path (2, 4) has length: 102", + "\t#1 shortest path (8, 1) has length: 101", + "\t#2 shortest path (8, 1) has length: 108", + "\t#1 shortest path (3, 3) has length: 0", + "\t#2 shortest path (3, 3) has length: 112", + "\t#1 shortest path (0, 0) has length: 0", + "\t#2 shortest path (0, 0) has length: 111", + ], +) + cc_binary( name = "dag_simple_constrained_shortest_path", srcs = ["dag_simple_constrained_shortest_path.cc"], @@ -400,6 +532,12 @@ cc_binary( ], ) +run_binary_test( + name = "dag_simple_constrained_shortest_path_test", + binary = ":dag_simple_constrained_shortest_path", + grep_lines = ["Constrained shortest path length: 4"], +) + cc_binary( name = "dag_constrained_shortest_path_sequential", srcs = ["dag_constrained_shortest_path_sequential.cc"], @@ -410,3 +548,14 @@ cc_binary( "@abseil-cpp//absl/strings", ], ) + +run_binary_test( + name = "dag_constrained_shortest_path_sequential_test", + binary = ":dag_constrained_shortest_path_sequential", + grep_lines = [ + "Initial distance: 200", + "Distance_2_3: 1", + "Distance_8_1: 100", + "Distance_3_7: 100", + ], +) diff --git a/ortools/graph/samples/assignment_min_flow.cc b/ortools/graph/samples/assignment_min_flow.cc index 4adcd67521..b89a67eb3a 100644 --- a/ortools/graph/samples/assignment_min_flow.cc +++ b/ortools/graph/samples/assignment_min_flow.cc @@ -15,10 +15,12 @@ // [START import] #include #include +#include #include #include "absl/base/log_severity.h" #include "absl/log/globals.h" +#include "absl/log/log.h" #include "ortools/base/init_google.h" #include "ortools/graph/min_cost_flow.h" // [END import] diff --git a/ortools/graph/samples/balance_min_flow.cc b/ortools/graph/samples/balance_min_flow.cc index f9b8ccc3b4..5802be30d0 100644 --- a/ortools/graph/samples/balance_min_flow.cc +++ b/ortools/graph/samples/balance_min_flow.cc @@ -15,10 +15,12 @@ // [START import] #include #include +#include #include #include "absl/base/log_severity.h" #include "absl/log/globals.h" +#include "absl/log/log.h" #include "ortools/base/init_google.h" #include "ortools/graph/min_cost_flow.h" // [END import] diff --git a/ortools/graph/samples/simple_max_flow_program.cc b/ortools/graph/samples/simple_max_flow_program.cc index a49028a799..fbcb46fda2 100644 --- a/ortools/graph/samples/simple_max_flow_program.cc +++ b/ortools/graph/samples/simple_max_flow_program.cc @@ -16,10 +16,12 @@ // [START import] #include #include +#include #include #include "absl/base/log_severity.h" #include "absl/log/globals.h" +#include "absl/log/log.h" #include "ortools/base/init_google.h" #include "ortools/graph/max_flow.h" // [END import] diff --git a/ortools/graph/samples/simple_min_cost_flow_program.cc b/ortools/graph/samples/simple_min_cost_flow_program.cc index 319123cf4e..611cadab2d 100644 --- a/ortools/graph/samples/simple_min_cost_flow_program.cc +++ b/ortools/graph/samples/simple_min_cost_flow_program.cc @@ -16,10 +16,12 @@ // [START import] #include #include +#include #include #include "absl/base/log_severity.h" #include "absl/log/globals.h" +#include "absl/log/log.h" #include "ortools/base/init_google.h" #include "ortools/graph/min_cost_flow.h" // [END import] diff --git a/ortools/graph/strongly_connected_components.h b/ortools/graph/strongly_connected_components.h index ecc616a5f5..bd92303f49 100644 --- a/ortools/graph/strongly_connected_components.h +++ b/ortools/graph/strongly_connected_components.h @@ -181,6 +181,9 @@ class StronglyConnectedComponentsFinder { bool NodeIsInCurrentDfsPath(NodeIndex node) const { return node_index_[node] > 0 && node_index_[node] < kSettledIndex; } + bool NodeIsNotYetExplored(NodeIndex node) const { + return node_index_[node] == 0; + } private: static constexpr NodeIndex kSettledIndex =