graph: enable more tests in bazel
This commit is contained in:
@@ -76,6 +76,25 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "bounded_dijkstra_test",
|
||||
size = "small",
|
||||
srcs = ["bounded_dijkstra_test.cc"],
|
||||
deps = [
|
||||
":bounded_dijkstra",
|
||||
":graph",
|
||||
":io",
|
||||
":test_util",
|
||||
"//ortools/base:dump_vars",
|
||||
"//ortools/base:gmock_main",
|
||||
"//ortools/util:flat_matrix",
|
||||
"@com_google_absl//absl/log:check",
|
||||
"@com_google_absl//absl/random",
|
||||
"@com_google_absl//absl/random:distributions",
|
||||
"@com_google_benchmark//:benchmark",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "multi_dijkstra",
|
||||
hdrs = ["multi_dijkstra.h"],
|
||||
@@ -152,6 +171,25 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "cliques_test",
|
||||
size = "medium",
|
||||
srcs = ["cliques_test.cc"],
|
||||
deps = [
|
||||
":cliques",
|
||||
"//ortools/base:gmock_main",
|
||||
"//ortools/base:mathutil",
|
||||
"//ortools/util:time_limit",
|
||||
"@com_google_absl//absl/container:flat_hash_set",
|
||||
"@com_google_absl//absl/functional:bind_front",
|
||||
"@com_google_absl//absl/log:check",
|
||||
"@com_google_absl//absl/random:distributions",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/types:span",
|
||||
"@com_google_benchmark//:benchmark",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "hamiltonian_path",
|
||||
hdrs = ["hamiltonian_path.h"],
|
||||
@@ -271,6 +309,20 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "one_tree_lower_bound_test",
|
||||
size = "medium",
|
||||
srcs = ["one_tree_lower_bound_test.cc"],
|
||||
deps = [
|
||||
":one_tree_lower_bound",
|
||||
"//ortools/base:gmock_main",
|
||||
"//ortools/base:path",
|
||||
"//ortools/base:types",
|
||||
"//ortools/routing/parsers:tsplib_parser",
|
||||
"@com_google_absl//absl/types:span",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "ebert_graph",
|
||||
hdrs = ["ebert_graph.h"],
|
||||
@@ -355,6 +407,23 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "k_shortest_paths_test",
|
||||
srcs = ["k_shortest_paths_test.cc"],
|
||||
deps = [
|
||||
":graph",
|
||||
":io",
|
||||
":k_shortest_paths",
|
||||
":shortest_paths",
|
||||
"//ortools/base:gmock_main",
|
||||
"@com_google_absl//absl/algorithm:container",
|
||||
"@com_google_absl//absl/log:check",
|
||||
"@com_google_absl//absl/random:distributions",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_benchmark//:benchmark",
|
||||
],
|
||||
)
|
||||
|
||||
# Flow problem protobuf representation
|
||||
proto_library(
|
||||
name = "flow_problem_proto",
|
||||
@@ -438,6 +507,25 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "min_cost_flow_test",
|
||||
size = "medium",
|
||||
srcs = ["min_cost_flow_test.cc"],
|
||||
deps = [
|
||||
":graphs",
|
||||
":min_cost_flow",
|
||||
"//ortools/base:gmock_main",
|
||||
"@com_google_absl//absl/random:distributions",
|
||||
"@com_google_absl//absl/strings:str_format",
|
||||
"@com_google_absl//absl/types:span",
|
||||
"@com_google_benchmark//:benchmark",
|
||||
":graph",
|
||||
# Using CLP because GLOP is too slow in non-opt mode.
|
||||
"//ortools/algorithms:binary_search",
|
||||
"//ortools/linear_solver",
|
||||
],
|
||||
)
|
||||
|
||||
# Flow-problem solver
|
||||
cc_binary(
|
||||
name = "solve_flow_model",
|
||||
@@ -748,3 +836,13 @@ cc_library(
|
||||
"@com_google_absl//absl/container:inlined_vector",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "test_util",
|
||||
hdrs = ["test_util.h"],
|
||||
deps = [
|
||||
":graph",
|
||||
"//ortools/base:types",
|
||||
"@com_google_absl//absl/memory",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -28,13 +28,12 @@
|
||||
#include "absl/random/random.h"
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "ortools/base/dump_vars.h"
|
||||
#include "ortools/base/gmock.h"
|
||||
#include "ortools/graph/graph.h"
|
||||
#include "ortools/graph/io.h"
|
||||
#include "ortools/graph/test_util.h"
|
||||
#include "ortools/util/flat_matrix.h"
|
||||
#include "ortools/util/saturated_arithmetic.h"
|
||||
#include "util/tuple/dump_vars.h"
|
||||
|
||||
namespace operations_research {
|
||||
namespace {
|
||||
@@ -683,8 +682,7 @@ TEST(BoundedDisjktraTest, RandomizedStressTest) {
|
||||
EXPECT_EQ(dijkstra.distances()[node], node_min_dist[node]) << node;
|
||||
}
|
||||
ASSERT_FALSE(HasFailure())
|
||||
<< DUMP_VARS(num_nodes, num_arcs, num_sources, limit, sources,
|
||||
lengths)
|
||||
<< DUMP_VARS(num_nodes, num_arcs, num_sources, limit, lengths)
|
||||
<< "\n With graph:\n"
|
||||
<< util::GraphToString(graph, util::PRINT_GRAPH_ARCS);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "ortools/base/mathutil.h"
|
||||
#include "ortools/util/time_limit.h"
|
||||
#include "util/functional/to_callback.h"
|
||||
|
||||
namespace operations_research {
|
||||
namespace {
|
||||
@@ -163,9 +162,7 @@ TEST(BronKerbosch, CompleteGraph) {
|
||||
CliqueReporter<int> reporter;
|
||||
auto callback =
|
||||
absl::bind_front(&CliqueReporter<int>::AppendClique, &reporter);
|
||||
operations_research::FindCliques(
|
||||
::util::functional::ToPermanentCallback(graph), num_nodes,
|
||||
::util::functional::ToPermanentCallback(callback));
|
||||
operations_research::FindCliques(graph, num_nodes, callback);
|
||||
const std::vector<std::vector<int>>& all_cliques = reporter.all_cliques();
|
||||
EXPECT_EQ(1, all_cliques.size());
|
||||
EXPECT_EQ(num_nodes, all_cliques[0].size());
|
||||
@@ -243,9 +240,7 @@ TEST(BronKerbosch, EmptyGraph) {
|
||||
CliqueReporter<int> reporter;
|
||||
auto callback =
|
||||
absl::bind_front(&CliqueReporter<int>::AppendClique, &reporter);
|
||||
operations_research::FindCliques(
|
||||
::util::functional::ToPermanentCallback(graph), 10,
|
||||
::util::functional::ToPermanentCallback(callback));
|
||||
operations_research::FindCliques(graph, 10, callback);
|
||||
const std::vector<std::vector<int>>& all_cliques = reporter.all_cliques();
|
||||
EXPECT_EQ(10, all_cliques.size());
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
@@ -336,9 +331,7 @@ TEST(BronKerbosch, MatchingGraph) {
|
||||
CliqueReporter<int> reporter;
|
||||
auto callback =
|
||||
absl::bind_front(&CliqueReporter<int>::AppendClique, &reporter);
|
||||
operations_research::FindCliques(
|
||||
::util::functional::ToPermanentCallback(graph), 10,
|
||||
::util::functional::ToPermanentCallback(callback));
|
||||
operations_research::FindCliques(graph, 10, callback);
|
||||
const std::vector<std::vector<int>>& all_cliques = reporter.all_cliques();
|
||||
EXPECT_EQ(5, all_cliques.size());
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
@@ -370,9 +363,7 @@ TEST(BronKerbosch, ModuloGraph5) {
|
||||
CliqueReporter<int> reporter;
|
||||
auto callback =
|
||||
absl::bind_front(&CliqueReporter<int>::AppendClique, &reporter);
|
||||
operations_research::FindCliques(
|
||||
::util::functional::ToPermanentCallback(graph), 40,
|
||||
::util::functional::ToPermanentCallback(callback));
|
||||
operations_research::FindCliques(graph, 40, callback);
|
||||
const std::vector<std::vector<int>>& all_cliques = reporter.all_cliques();
|
||||
EXPECT_EQ(5, all_cliques.size());
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
@@ -406,9 +397,7 @@ TEST(BronKerbosch, CompleteGraphCover) {
|
||||
CliqueReporter<int> reporter;
|
||||
auto callback =
|
||||
absl::bind_front(&CliqueReporter<int>::AppendClique, &reporter);
|
||||
operations_research::CoverArcsByCliques(
|
||||
::util::functional::ToPermanentCallback(graph), 10,
|
||||
::util::functional::ToPermanentCallback(callback));
|
||||
operations_research::CoverArcsByCliques(graph, 10, callback);
|
||||
const std::vector<std::vector<int>>& all_cliques = reporter.all_cliques();
|
||||
EXPECT_EQ(1, all_cliques.size());
|
||||
EXPECT_EQ(10, all_cliques[0].size());
|
||||
@@ -457,9 +446,7 @@ TEST(BronKerbosch, EmptyGraphCover) {
|
||||
CliqueReporter<int> reporter;
|
||||
auto callback =
|
||||
absl::bind_front(&CliqueReporter<int>::AppendClique, &reporter);
|
||||
operations_research::CoverArcsByCliques(
|
||||
::util::functional::ToPermanentCallback(graph), 10,
|
||||
::util::functional::ToPermanentCallback(callback));
|
||||
operations_research::CoverArcsByCliques(graph, 10, callback);
|
||||
const std::vector<std::vector<int>>& all_cliques = reporter.all_cliques();
|
||||
EXPECT_EQ(0, all_cliques.size());
|
||||
}
|
||||
@@ -469,9 +456,7 @@ TEST(BronKerbosch, MatchingGraphCover) {
|
||||
CliqueReporter<int> reporter;
|
||||
auto callback =
|
||||
absl::bind_front(&CliqueReporter<int>::AppendClique, &reporter);
|
||||
operations_research::CoverArcsByCliques(
|
||||
::util::functional::ToPermanentCallback(graph), 10,
|
||||
::util::functional::ToPermanentCallback(callback));
|
||||
operations_research::CoverArcsByCliques(graph, 10, callback);
|
||||
const std::vector<std::vector<int>>& all_cliques = reporter.all_cliques();
|
||||
EXPECT_EQ(5, all_cliques.size());
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
@@ -486,9 +471,7 @@ TEST(BronKerbosch, ModuloGraph5Cover) {
|
||||
CliqueReporter<int> reporter;
|
||||
auto callback =
|
||||
absl::bind_front(&CliqueReporter<int>::AppendClique, &reporter);
|
||||
operations_research::CoverArcsByCliques(
|
||||
::util::functional::ToPermanentCallback(graph), 40,
|
||||
::util::functional::ToPermanentCallback(callback));
|
||||
operations_research::CoverArcsByCliques(graph, 40, callback);
|
||||
const std::vector<std::vector<int>>& all_cliques = reporter.all_cliques();
|
||||
EXPECT_EQ(5, all_cliques.size());
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
@@ -628,9 +611,7 @@ void BM_FindCliquesInModuloGraph(benchmark::State& state) {
|
||||
auto callback =
|
||||
absl::bind_front(&CliqueSizeVerifier::AppendClique, &verifier);
|
||||
|
||||
operations_research::FindCliques(
|
||||
::util::functional::ToPermanentCallback(graph), kGraphSize,
|
||||
::util::functional::ToPermanentCallback(callback));
|
||||
operations_research::FindCliques(graph, kGraphSize, callback);
|
||||
}
|
||||
EXPECT_EQ(state.max_iterations * kExpectedNumCliques, verifier.num_cliques());
|
||||
}
|
||||
@@ -720,10 +701,8 @@ void BM_FindCliquesInFull7PartiteGraph(benchmark::State& state) {
|
||||
auto callback =
|
||||
absl::bind_front(&CliqueSizeVerifier::AppendClique, &verifier);
|
||||
|
||||
operations_research::FindCliques(
|
||||
::util::functional::ToPermanentCallback(graph),
|
||||
kNumPartitions * kNumPartitions,
|
||||
::util::functional::ToPermanentCallback(callback));
|
||||
operations_research::FindCliques(graph, kNumPartitions * kNumPartitions,
|
||||
callback);
|
||||
}
|
||||
EXPECT_EQ(state.max_iterations * kExpectedNumCliques, verifier.num_cliques());
|
||||
}
|
||||
@@ -733,8 +712,7 @@ BENCHMARK(BM_FindCliquesInFull7PartiteGraph);
|
||||
void BM_FindCliquesInFullKPartiteGraphWithBronKerboschAlgorithm(
|
||||
benchmark::State& state) {
|
||||
int num_partitions = state.range(0);
|
||||
const int kExpectedNumCliques =
|
||||
::MathUtil::IPow(num_partitions, num_partitions);
|
||||
const int kExpectedNumCliques = std::pow(num_partitions, num_partitions);
|
||||
const int kExpectedCliqueSize = num_partitions;
|
||||
|
||||
const auto graph = [num_partitions](int index1, int index2) {
|
||||
@@ -764,7 +742,7 @@ void BM_FindCliquesInRandomGraphWithBronKerboschAlgorithm(
|
||||
const double arc_probability = arc_probability_permille / 1000.0;
|
||||
const absl::flat_hash_set<std::pair<int, int>> adjacency_matrix =
|
||||
MakeRandomGraphAdjacencyMatrix(num_nodes, arc_probability,
|
||||
absl::GetFlag(FLAGS_test_random_seed));
|
||||
GTEST_FLAG_GET(random_seed));
|
||||
const auto graph = [adjacency_matrix](int index1, int index2) {
|
||||
return BitmapGraph(adjacency_matrix, index1, index2);
|
||||
};
|
||||
|
||||
@@ -237,8 +237,8 @@ Graph GenerateUniformGraph(URBG&& urbg, const NodeIndexType num_nodes,
|
||||
for (ArcIndexType i = 0; i < std::min(num_edges, max_num_arcs); ++i) {
|
||||
NodeIndexType src, dst;
|
||||
std::tie(src, dst) = pick_two_distinct_nodes();
|
||||
if (arcs.contains({src, dst})) continue;
|
||||
if (IsDirected && arcs.contains({dst, src})) continue;
|
||||
if (arcs.find({src, dst}) != arcs.end()) continue;
|
||||
if (IsDirected && (arcs.find({dst, src}) != arcs.end())) continue;
|
||||
|
||||
arcs.insert({src, dst});
|
||||
graph.AddArc(src, dst);
|
||||
|
||||
@@ -588,7 +588,7 @@ CostValue SolveMinCostFlow(GenericMinCostFlow<Graph>* min_cost_flow) {
|
||||
|
||||
template <typename Graph>
|
||||
CostValue SolveMinCostFlowWithLP(GenericMinCostFlow<Graph>* min_cost_flow) {
|
||||
MPSolver solver("LPSolver", MPSolver::CLP_LINEAR_PROGRAMMING);
|
||||
MPSolver solver("LPSolver", MPSolver::GLOP_LINEAR_PROGRAMMING);
|
||||
const Graph* graph = min_cost_flow->graph();
|
||||
const NodeIndex num_nodes = graph->num_nodes();
|
||||
const ArcIndex num_arcs = graph->num_arcs();
|
||||
|
||||
65
ortools/graph/test_util.h
Normal file
65
ortools/graph/test_util.h
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright 2010-2024 Google LLC
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Unit test utilities related to graph.h.
|
||||
|
||||
#ifndef UTIL_GRAPH_TEST_UTIL_H_
|
||||
#define UTIL_GRAPH_TEST_UTIL_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "ortools/base/types.h"
|
||||
#include "ortools/graph/graph.h"
|
||||
|
||||
namespace util {
|
||||
|
||||
// Generate a 2-dimensional undirected grid graph.
|
||||
//
|
||||
// Eg. for width=3, height=2, it generates this:
|
||||
// 0 <---> 1 <---> 2
|
||||
// ^ ^ ^
|
||||
// | | |
|
||||
// v v v
|
||||
// 3 <---> 4 <---> 5
|
||||
template <class Graph>
|
||||
std::unique_ptr<Graph> Create2DGridGraph(int64_t width, int64_t height) {
|
||||
const int64_t num_arcs = 2L * ((width - 1) * height + width * (height - 1));
|
||||
auto graph = std::make_unique<Graph>(/*num_nodes=*/width * height,
|
||||
/*arc_capacity=*/num_arcs);
|
||||
// Add horizontal edges.
|
||||
for (int i = 0; i < height; ++i) {
|
||||
for (int j = 1; j < width; ++j) {
|
||||
const int left = i * width + (j - 1);
|
||||
const int right = i * width + j;
|
||||
graph->AddArc(left, right);
|
||||
graph->AddArc(right, left);
|
||||
}
|
||||
}
|
||||
// Add vertical edges.
|
||||
for (int i = 1; i < height; ++i) {
|
||||
for (int j = 0; j < width; ++j) {
|
||||
const int up = (i - 1) * width + j;
|
||||
const int down = i * width + j;
|
||||
graph->AddArc(up, down);
|
||||
graph->AddArc(down, up);
|
||||
}
|
||||
}
|
||||
graph->Build();
|
||||
return graph;
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
|
||||
#endif // UTIL_GRAPH_TEST_UTIL_H_
|
||||
Reference in New Issue
Block a user