# Copyright 2010-2025 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. load("@protobuf//bazel:cc_proto_library.bzl", "cc_proto_library") load("@protobuf//bazel:proto_library.bzl", "proto_library") load("@rules_cc//cc:cc_binary.bzl", "cc_binary") load("@rules_cc//cc:cc_library.bzl", "cc_library") load("@rules_cc//cc:cc_test.bzl", "cc_test") cc_library( name = "graph", hdrs = ["graph.h"], visibility = ["//visibility:public"], deps = [ ":iterators", "//ortools/base", "//ortools/base:constant_divisor", "@abseil-cpp//absl/debugging:leak_check", "@abseil-cpp//absl/types:span", ], ) cc_test( name = "graph_test", size = "small", srcs = ["graph_test.cc"], visibility = ["//visibility:public"], deps = [ ":graph", "//ortools/base:gmock_main", "//ortools/base:intops", "//ortools/base:strong_vector", "@abseil-cpp//absl/algorithm:container", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/random", "@abseil-cpp//absl/strings", "@abseil-cpp//absl/types:span", "@google_benchmark//:benchmark", ], ) cc_library( name = "flow_graph", hdrs = ["flow_graph.h"], visibility = ["//visibility:public"], deps = [ ":graph", ":iterators", "//ortools/base:stl_util", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/types:span", ], ) cc_library( name = "bfs", hdrs = ["bfs.h"], visibility = ["//visibility:public"], deps = [ "@abseil-cpp//absl/status", "@abseil-cpp//absl/strings:str_format", ], ) cc_library( name = "bounded_dijkstra", hdrs = ["bounded_dijkstra.h"], visibility = ["//visibility:public"], deps = [ "//ortools/base:intops", "//ortools/base:iterator_adaptors", "//ortools/base:strong_vector", "//ortools/base:threadpool", "//ortools/base:top_n", "//ortools/graph", "@abseil-cpp//absl/algorithm:container", "@abseil-cpp//absl/base:core_headers", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/types:span", ], ) cc_test( name = "bounded_dijkstra_test", size = "small", srcs = ["bounded_dijkstra_test.cc"], deps = [ ":bounded_dijkstra", "//ortools/base:dump_vars", "//ortools/base:gmock_main", "//ortools/base:intops", "//ortools/graph", "//ortools/graph:io", "//ortools/graph:test_util", "//ortools/util:flat_matrix", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/random", "@abseil-cpp//absl/random:distributions", "@google_benchmark//:benchmark", ], ) cc_library( name = "minimum_vertex_cover", srcs = ["minimum_vertex_cover.cc"], hdrs = ["minimum_vertex_cover.h"], visibility = ["//visibility:public"], deps = [ ":max_flow", "@abseil-cpp//absl/log:check", ], ) cc_test( name = "minimum_vertex_cover_test", srcs = ["minimum_vertex_cover_test.cc"], deps = [ ":minimum_vertex_cover", "//ortools/base:gmock_main", "@abseil-cpp//absl/algorithm:container", "@google_benchmark//:benchmark", ], ) cc_library( name = "multi_dijkstra", hdrs = ["multi_dijkstra.h"], visibility = ["//visibility:public"], deps = [ "//ortools/base:map_util", "//ortools/base:types", "@abseil-cpp//absl/container:flat_hash_map", ], ) cc_test( name = "multi_dijkstra_test", size = "small", srcs = ["multi_dijkstra_test.cc"], deps = [ ":multi_dijkstra", "//ortools/base:gmock_main", "//ortools/base:map_util", "//ortools/base:types", "//ortools/graph", "//ortools/graph:connected_components", "//ortools/graph:random_graph", "//ortools/graph:util", "@abseil-cpp//absl/container:flat_hash_map", "@abseil-cpp//absl/container:flat_hash_set", "@abseil-cpp//absl/random:distributions", ], ) cc_library( name = "bidirectional_dijkstra", hdrs = ["bidirectional_dijkstra.h"], visibility = ["//visibility:public"], deps = [ "//ortools/base", "//ortools/base:iterator_adaptors", "//ortools/base:threadpool", "@abseil-cpp//absl/base:core_headers", "@abseil-cpp//absl/log", "@abseil-cpp//absl/log:vlog_is_on", "@abseil-cpp//absl/strings", "@abseil-cpp//absl/synchronization", ], ) cc_test( name = "bidirectional_dijkstra_test", size = "small", srcs = ["bidirectional_dijkstra_test.cc"], tags = ["noci"], deps = [ ":bidirectional_dijkstra", ":bounded_dijkstra", "//ortools/base:gmock_main", "//ortools/base:iterator_adaptors", "//ortools/graph", "@abseil-cpp//absl/base:log_severity", "@abseil-cpp//absl/random:distributions", "@abseil-cpp//absl/strings", "@abseil-cpp//absl/types:span", ], ) cc_library( name = "cliques", srcs = ["cliques.cc"], hdrs = ["cliques.h"], visibility = ["//visibility:public"], deps = [ "//ortools/base", "//ortools/base:int_type", "//ortools/base:strong_vector", "//ortools/util:bitset", "//ortools/util:time_limit", "@abseil-cpp//absl/container:flat_hash_set", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/strings", ], ) cc_test( name = "cliques_test", size = "medium", srcs = ["cliques_test.cc"], deps = [ ":cliques", "//ortools/base:gmock_main", "//ortools/util:time_limit", "@abseil-cpp//absl/container:flat_hash_set", "@abseil-cpp//absl/flags:flag", "@abseil-cpp//absl/functional:bind_front", "@abseil-cpp//absl/log", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/random:distributions", "@abseil-cpp//absl/strings", "@abseil-cpp//absl/types:span", "@google_benchmark//:benchmark", ], ) cc_library( name = "hamiltonian_path", hdrs = ["hamiltonian_path.h"], visibility = ["//visibility:public"], deps = [ "//ortools/util:bitset", "//ortools/util:saturated_arithmetic", "//ortools/util:vector_or_function", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/types:span", ], ) cc_test( name = "hamiltonian_path_test", size = "medium", timeout = "long", srcs = ["hamiltonian_path_test.cc"], deps = [ ":hamiltonian_path", "//ortools/base:gmock_main", "@abseil-cpp//absl/base:core_headers", "@abseil-cpp//absl/log", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/random:distributions", "@abseil-cpp//absl/strings:str_format", "@abseil-cpp//absl/types:span", ], ) cc_library( name = "christofides", hdrs = ["christofides.h"], visibility = ["//visibility:public"], deps = [ ":eulerian_path", ":minimum_spanning_tree", ":perfect_matching", "//ortools/base", "//ortools/graph", "//ortools/linear_solver", "//ortools/linear_solver:linear_solver_cc_proto", "//ortools/util:saturated_arithmetic", "@abseil-cpp//absl/status", "@abseil-cpp//absl/status:statusor", "@abseil-cpp//absl/strings", ], ) cc_test( name = "christofides_test", srcs = ["christofides_test.cc"], deps = [ ":christofides", "//ortools/base", "//ortools/base:gmock_main", "@abseil-cpp//absl/status", "@abseil-cpp//absl/strings:str_format", "@abseil-cpp//absl/types:span", "@google_benchmark//:benchmark", ], ) cc_library( name = "eulerian_path", hdrs = ["eulerian_path.h"], visibility = ["//visibility:public"], deps = [ "//ortools/base", ], ) cc_test( name = "eulerian_path_test", srcs = ["eulerian_path_test.cc"], deps = [ ":eulerian_path", "//ortools/base:gmock_main", "//ortools/graph", "@abseil-cpp//absl/base:core_headers", "@google_benchmark//:benchmark", ], ) cc_library( name = "minimum_spanning_tree", hdrs = ["minimum_spanning_tree.h"], visibility = ["//visibility:public"], deps = [ "//ortools/base:adjustable_priority_queue", "//ortools/base:types", "//ortools/graph:connected_components", "//ortools/util:vector_or_function", "@abseil-cpp//absl/types:span", ], ) cc_test( name = "minimum_spanning_tree_test", srcs = ["minimum_spanning_tree_test.cc"], deps = [ ":minimum_spanning_tree", "//ortools/base:gmock_main", "//ortools/base:types", "//ortools/graph", "@abseil-cpp//absl/base:core_headers", "@abseil-cpp//absl/random:distributions", "@abseil-cpp//absl/types:span", "@google_benchmark//:benchmark", ], ) cc_library( name = "one_tree_lower_bound", hdrs = ["one_tree_lower_bound.h"], visibility = ["//visibility:public"], deps = [ ":christofides", ":minimum_spanning_tree", "//ortools/graph", "@abseil-cpp//absl/log", "@abseil-cpp//absl/types:span", ], ) 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/routing/parsers:tsplib_parser", "@abseil-cpp//absl/log", "@abseil-cpp//absl/types:span", ], ) cc_library( name = "shortest_paths", hdrs = ["shortest_paths.h"], visibility = ["//visibility:public"], deps = [ "//ortools/base", "//ortools/base:adjustable_priority_queue", "//ortools/base:map_util", "//ortools/base:stl_util", "//ortools/base:threadpool", "//ortools/base:timer", "@abseil-cpp//absl/base:core_headers", "@abseil-cpp//absl/container:flat_hash_map", "@abseil-cpp//absl/functional:bind_front", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/types:span", ], ) cc_test( name = "shortest_paths_test", size = "enormous", srcs = ["shortest_paths_test.cc"], tags = ["noci"], # Times out occasionally in ASAN mode. deps = [ ":shortest_paths", "//ortools/base:gmock_main", "//ortools/graph", "//ortools/graph:strongly_connected_components", "@abseil-cpp//absl/base:core_headers", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/random", ], ) cc_library( name = "k_shortest_paths", hdrs = ["k_shortest_paths.h"], visibility = ["//visibility:public"], deps = [ ":bounded_dijkstra", ":shortest_paths", "@abseil-cpp//absl/algorithm:container", "@abseil-cpp//absl/base:core_headers", "@abseil-cpp//absl/container:flat_hash_set", "@abseil-cpp//absl/log", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/strings", "@abseil-cpp//absl/types:span", ], ) cc_test( name = "k_shortest_paths_test", srcs = ["k_shortest_paths_test.cc"], deps = [ ":k_shortest_paths", ":shortest_paths", "//ortools/base:gmock_main", "//ortools/graph", "//ortools/graph:io", "@abseil-cpp//absl/algorithm:container", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/random:distributions", "@abseil-cpp//absl/strings", "@google_benchmark//:benchmark", ], ) # Flow problem protobuf representation proto_library( name = "flow_problem_proto", srcs = ["flow_problem.proto"], visibility = ["//visibility:public"], ) cc_proto_library( name = "flow_problem_cc_proto", visibility = ["//visibility:public"], deps = [":flow_problem_proto"], ) # Max Flow cc_library( name = "max_flow", srcs = ["max_flow.cc"], hdrs = ["max_flow.h"], visibility = ["//visibility:public"], deps = [ ":flow_problem_cc_proto", ":generic_max_flow", "//ortools/graph", ], ) cc_test( name = "max_flow_test", srcs = ["max_flow_test.cc"], data = ["//ortools/graph:testdata/max_flow_test1.pb.txt"], deps = [ ":flow_problem_cc_proto", ":max_flow", "//ortools/base:gmock_main", "//ortools/base:path", "//ortools/util:file_util", "@protobuf", ], ) cc_library( name = "generic_max_flow", hdrs = ["generic_max_flow.h"], visibility = ["//visibility:public"], deps = [ ":flow_problem_cc_proto", "//ortools/base", "//ortools/util:stats", "//ortools/util:zvector", "@abseil-cpp//absl/strings", ], ) cc_test( name = "generic_max_flow_test", size = "medium", srcs = ["generic_max_flow_test.cc"], deps = [ ":generic_max_flow", "//ortools/base", "//ortools/base:gmock_main", "//ortools/graph", "//ortools/graph:flow_graph", "//ortools/linear_solver", "@abseil-cpp//absl/random", "@abseil-cpp//absl/random:bit_gen_ref", "@abseil-cpp//absl/strings:str_format", "@abseil-cpp//absl/types:span", "@google_benchmark//:benchmark", ], ) # Min Cost Flow cc_library( name = "min_cost_flow", srcs = ["min_cost_flow.cc"], hdrs = ["min_cost_flow.h"], copts = select({ "@platforms//os:windows": ["/Zc:preprocessor"], "//conditions:default": [], }), visibility = ["//visibility:public"], deps = [ ":generic_max_flow", "//ortools/base:mathutil", "//ortools/graph", "//ortools/util:saturated_arithmetic", "//ortools/util:stats", "//ortools/util:zvector", "@abseil-cpp//absl/base:core_headers", "@abseil-cpp//absl/flags:flag", "@abseil-cpp//absl/log", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/strings", "@abseil-cpp//absl/strings:str_format", ], ) cc_test( name = "min_cost_flow_test", size = "medium", srcs = ["min_cost_flow_test.cc"], tags = ["noci"], deps = [ ":min_cost_flow", "//ortools/base:gmock_main", "@abseil-cpp//absl/log", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/random:distributions", "@abseil-cpp//absl/strings:str_format", "@abseil-cpp//absl/types:span", "@google_benchmark//:benchmark", "//ortools/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", srcs = ["solve_flow_model.cc"], deps = [ ":flow_problem_cc_proto", ":generic_max_flow", ":min_cost_flow", "//ortools/base", "//ortools/base:file", "//ortools/base:path", "//ortools/base:timer", "//ortools/graph", "//ortools/graph:flow_graph", "//ortools/util:file_util", "//ortools/util:filelineiter", "//ortools/util:stats", "@abseil-cpp//absl/base:log_severity", "@abseil-cpp//absl/flags:flag", "@abseil-cpp//absl/log", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/log:globals", "@abseil-cpp//absl/strings", "@abseil-cpp//absl/strings:str_format", ], ) # Linear Assignment wrapper that consumes more memory but presents a # simplified interface and no speed degradation from the full-featured # linear assignment implementation. cc_library( name = "assignment", srcs = ["assignment.cc"], hdrs = ["assignment.h"], visibility = ["//visibility:public"], deps = [ ":linear_assignment", "//ortools/graph", ], ) cc_test( name = "assignment_test", size = "small", srcs = ["assignment_test.cc"], deps = [ ":assignment", "//ortools/base:gmock_main", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/random:distributions", "@google_benchmark//:benchmark", ], ) # Linear Assignment with full-featured interface and efficient # implementation. cc_library( name = "linear_assignment", srcs = ["linear_assignment.cc"], hdrs = ["linear_assignment.h"], visibility = ["//visibility:public"], deps = [ "//ortools/base", "//ortools/graph:iterators", "//ortools/util:permutation", "//ortools/util:zvector", "@abseil-cpp//absl/flags:flag", "@abseil-cpp//absl/strings:str_format", ], ) cc_test( name = "linear_assignment_test", size = "small", srcs = ["linear_assignment_test.cc"], deps = [ ":linear_assignment", "//ortools/base:gmock_main", "//ortools/graph", "@abseil-cpp//absl/flags:flag", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/random:distributions", "@abseil-cpp//absl/types:span", "@google_benchmark//:benchmark", ], ) cc_library( name = "dag_connectivity", srcs = ["dag_connectivity.cc"], hdrs = ["dag_connectivity.h"], visibility = ["//visibility:public"], deps = [ "//ortools/base", "//ortools/base:container_logging", "//ortools/graph:topologicalsorter", "//ortools/util:bitset", "@abseil-cpp//absl/types:span", ], ) cc_test( name = "dag_connectivity_test", srcs = ["dag_connectivity_test.cc"], deps = [ ":dag_connectivity", "//ortools/base:gmock_main", "//ortools/util:bitset", "@abseil-cpp//absl/strings", "@abseil-cpp//absl/types:span", ], ) cc_library( name = "perfect_matching", srcs = ["perfect_matching.cc"], hdrs = ["perfect_matching.h"], visibility = ["//visibility:public"], deps = [ "//ortools/base", "//ortools/base:adjustable_priority_queue", "//ortools/base:int_type", "//ortools/base:strong_vector", "//ortools/util:saturated_arithmetic", "@abseil-cpp//absl/base:core_headers", "@abseil-cpp//absl/base:log_severity", "@abseil-cpp//absl/log", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/strings", ], ) cc_library( name = "dag_shortest_path", srcs = ["dag_shortest_path.cc"], hdrs = ["dag_shortest_path.h"], visibility = ["//visibility:public"], deps = [ "//ortools/graph", "//ortools/graph:topologicalsorter", "@abseil-cpp//absl/algorithm:container", "@abseil-cpp//absl/log", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/status", "@abseil-cpp//absl/strings:str_format", "@abseil-cpp//absl/types:span", ], ) cc_library( name = "dag_constrained_shortest_path", srcs = ["dag_constrained_shortest_path.cc"], hdrs = ["dag_constrained_shortest_path.h"], visibility = ["//visibility:public"], deps = [ ":dag_shortest_path", "//ortools/base:threadpool", "//ortools/graph", "//ortools/graph:topologicalsorter", "@abseil-cpp//absl/algorithm:container", "@abseil-cpp//absl/base:log_severity", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/status:statusor", "@abseil-cpp//absl/strings:str_format", "@abseil-cpp//absl/types:span", ], ) cc_library( name = "rooted_tree", hdrs = ["rooted_tree.h"], visibility = ["//visibility:public"], deps = [ "//ortools/base:status_macros", "@abseil-cpp//absl/algorithm:container", "@abseil-cpp//absl/log", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/status", "@abseil-cpp//absl/status:statusor", "@abseil-cpp//absl/strings", "@abseil-cpp//absl/types:span", ], ) cc_test( name = "rooted_tree_test", srcs = ["rooted_tree_test.cc"], deps = [ ":rooted_tree", "//ortools/base:gmock_main", "//ortools/graph", "@abseil-cpp//absl/algorithm:container", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/random", "@abseil-cpp//absl/status", "@google_benchmark//:benchmark", ], ) cc_test( name = "perfect_matching_test", size = "small", srcs = ["perfect_matching_test.cc"], deps = [ ":perfect_matching", "//ortools/base:gmock_main", "//ortools/linear_solver:linear_solver_cc_proto", "//ortools/linear_solver:solve_mp_model", "@abseil-cpp//absl/random", "@abseil-cpp//absl/types:span", ], ) cc_test( name = "dag_shortest_path_test", size = "small", srcs = ["dag_shortest_path_test.cc"], deps = [ ":dag_shortest_path", "//ortools/base:dump_vars", "//ortools/base:gmock_main", "//ortools/base:intops", "//ortools/base:strong_vector", "//ortools/graph", "//ortools/graph:io", "//ortools/util:flat_matrix", "@abseil-cpp//absl/algorithm:container", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/random", "@abseil-cpp//absl/status", "@abseil-cpp//absl/types:span", "@google_benchmark//:benchmark", ], ) cc_test( name = "dag_constrained_shortest_path_test", srcs = ["dag_constrained_shortest_path_test.cc"], deps = [ ":dag_constrained_shortest_path", "//ortools/base:dump_vars", "//ortools/base:gmock_main", "//ortools/graph", "//ortools/graph:io", "//ortools/math_opt/cpp:math_opt", "//ortools/math_opt/solvers:cp_sat_solver", "@abseil-cpp//absl/algorithm:container", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/random", "@abseil-cpp//absl/strings", "@abseil-cpp//absl/types:span", "@google_benchmark//:benchmark", ], ) # From util/graph cc_library( name = "connected_components", srcs = [ "connected_components.cc", ], hdrs = [ "connected_components.h", ], visibility = ["//visibility:public"], deps = [ "//ortools/base", "//ortools/base:map_util", "//ortools/base:stl_util", "@abseil-cpp//absl/container:flat_hash_map", "@abseil-cpp//absl/container:flat_hash_set", ], ) cc_library( name = "io", hdrs = ["graph_io.h"], visibility = ["//visibility:public"], deps = [ ":graph", "//ortools/base:numbers", "//ortools/util:filelineiter", "@abseil-cpp//absl/status", "@abseil-cpp//absl/status:statusor", "@abseil-cpp//absl/strings", ], ) cc_library( name = "iterators", hdrs = ["iterators.h"], visibility = ["//visibility:public"], deps = ["@abseil-cpp//absl/log:check"], ) cc_test( name = "iterators_test", size = "small", srcs = ["iterators_test.cc"], visibility = ["//visibility:public"], deps = [ ":iterators", "//ortools/base:gmock_main", "//ortools/base:intops", ], ) cc_library( name = "random_graph", srcs = ["random_graph.cc"], hdrs = ["random_graph.h"], visibility = ["//visibility:public"], deps = [ ":graph", "//ortools/base:logging", "//ortools/base:types", "@abseil-cpp//absl/container:flat_hash_set", "@abseil-cpp//absl/memory", "@abseil-cpp//absl/random", "@abseil-cpp//absl/random:bit_gen_ref", ], ) cc_library( name = "strongly_connected_components", hdrs = [ "strongly_connected_components.h", ], visibility = ["//visibility:public"], deps = [ "//ortools/base", ], ) cc_library( name = "topologicalsorter", srcs = ["topologicalsorter.cc"], hdrs = ["topologicalsorter.h"], visibility = ["//visibility:public"], deps = [ ":graph", "//ortools/base", "//ortools/base:container_logging", "//ortools/base:map_util", "//ortools/base:status_builder", "//ortools/base:stl_util", "@abseil-cpp//absl/base:core_headers", "@abseil-cpp//absl/container:flat_hash_map", "@abseil-cpp//absl/status", "@abseil-cpp//absl/status:statusor", ], ) cc_library( name = "util", srcs = ["util.cc"], hdrs = ["util.h"], visibility = ["//visibility:public"], deps = [ ":connected_components", ":graph", "//ortools/base:hash", "//ortools/base:map_util", "@abseil-cpp//absl/container:btree", "@abseil-cpp//absl/container:inlined_vector", ], ) cc_library( name = "test_util", hdrs = ["test_util.h"], visibility = ["//visibility:public"], deps = [ ":graph", "//ortools/base:types", "@abseil-cpp//absl/memory", ], )