export from google3

This commit is contained in:
Corentin Le Molgat
2025-02-07 17:08:01 +01:00
parent 22afd75080
commit 281a9f8e14
23 changed files with 102 additions and 126 deletions

View File

@@ -20,6 +20,8 @@ import "ortools/util/int128.proto";
option java_package = "com.google.ortools.algorithms";
option java_multiple_files = true;
// TODO(user): use uint64 instead of int32 for indices, as the solver
// supports it.
message SetCoverProto {
message Subset {
// The cost for using the given subset.

View File

@@ -63,7 +63,6 @@ class SetCoverDecision {
// are covered 1 time or less (not overcovered) in the current solution;
// is_redundant_, whether a subset can be removed from the solution.
// is_redundant_[subset] == (num_non_overcovered_elements_[subet] == 0).
class SetCoverInvariant {
public:
// The consistency level of the invariant.

View File

@@ -340,12 +340,14 @@ void SetCoverModel::CreateSparseRowView() {
for (const SubsetIndex subset : SubsetRange()) {
// Sort the columns. It's not super-critical to improve performance here
// as this needs to be done only once.
// std::sort(columns_[subset].begin(), columns_[subset].end());
BaseInt* data = reinterpret_cast<BaseInt*>(columns_[subset].data());
RadixSort(absl::MakeSpan(data, columns_[subset].size()));
ElementIndex preceding_element(-1);
for (const ElementIndex element : columns_[subset]) {
DCHECK_GT(element, preceding_element); // Fail if there is a repetition.
++row_sizes[element];
preceding_element = element;
}
}
for (const ElementIndex element : ElementRange()) {

View File

@@ -296,7 +296,6 @@ class SetCoverModel {
bool elements_in_subsets_are_sorted_;
// Costs for each subset.
SubsetCostVector subset_costs_;
// Vector of columns. Each column corresponds to a subset and contains the

View File

@@ -18,6 +18,7 @@
#include "absl/log/check.h"
#include "absl/strings/match.h"
#include "absl/strings/str_join.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "ortools/algorithms/set_cover_heuristics.h"
#include "ortools/algorithms/set_cover_invariant.h"
@@ -160,7 +161,7 @@ SetCoverModel ReadModel(const std::string& input_file,
}
}
SubsetBoolVector ReadSolution(const std::string& input_file,
SubsetBoolVector ReadSolution(absl::string_view input_file,
FileFormat input_format) {
switch (input_format) {
case FileFormat::TXT:
@@ -198,7 +199,7 @@ void WriteModel(const SetCoverModel& model, const std::string& output_file,
}
void WriteSolution(const SetCoverModel& model, const SubsetBoolVector& solution,
const std::string& output_file, FileFormat output_format) {
absl::string_view output_file, FileFormat output_format) {
switch (output_format) {
case FileFormat::TXT:
WriteSetCoverSolutionText(model, solution, output_file);

View File

@@ -16,7 +16,7 @@
#include <cstdlib> // for size_t.
#include "ortools/base/base_export.h" // for OR_DLL
#include "ortools/base/base_export.h" // for OR_DLL
#define COMPILE_ASSERT(x, msg)

View File

@@ -1072,7 +1072,7 @@ bool CheckSetNotIn(const Constraint& ct,
bool CheckSetInReif(const Constraint& ct,
const std::function<int64_t(Variable*)>& evaluator) {
const int64_t value = Eval(ct.arguments[0], evaluator);
const bool status = Eval(ct.arguments[2], evaluator) != 0;
const int64_t status = Eval(ct.arguments[2], evaluator);
return status == ct.arguments[1].Contains(value);
}

View File

@@ -116,10 +116,6 @@ class GenericPathContainer {
using NodeIndex = typename GraphType::NodeIndex;
using Impl = internal::PathContainerImpl<NodeIndex, GraphType::kNilNode>;
// TODO(b/385094969): Remove this when all clients are migrated, and use
// factory functions instead.
GenericPathContainer();
// This type is neither copyable nor movable.
GenericPathContainer(const GenericPathContainer&) = delete;
GenericPathContainer& operator=(const GenericPathContainer&) = delete;
@@ -153,9 +149,6 @@ class GenericPathContainer {
// Builds a path container which only stores distances between path nodes.
static GenericPathContainer BuildPathDistanceContainer();
ABSL_DEPRECATED("Use factory function BuildPathDistanceContainer instead.")
static void BuildPathDistanceContainer(GenericPathContainer* path_container);
// Builds a path container which stores explicit paths and distances between
// path nodes in a memory-compact representation.
// In this case `GetPenultimateNodeInPath()` is `O(log(path_tree_size))`,
@@ -168,11 +161,6 @@ class GenericPathContainer {
// `O(log(path_tree_size) * path_size)`.
static GenericPathContainer BuildInMemoryCompactPathContainer();
ABSL_DEPRECATED(
"Use factory function BuildInMemoryCompactPathContainer instead.")
static void BuildInMemoryCompactPathContainer(
GenericPathContainer* path_container);
// TODO(user): Add save-to-disk container.
// TODO(user): Add `BuildInMemoryFastPathContainer()`, which does
// `GetPenultimateNodeInPath()` in `O(1)`.
@@ -230,12 +218,12 @@ void ComputeOneToAllShortestPaths(
// Computes shortest paths from the node `source` to nodes in `destinations`.
// TODO(b/385094969): Remove second template parameter when all clients are
// migrated.
template <class GraphType, class PathContainerGraphType>
template <class GraphType>
void ComputeOneToManyShortestPaths(
const GraphType& graph, const std::vector<PathDistance>& arc_lengths,
typename GraphType::NodeIndex source,
const std::vector<typename GraphType::NodeIndex>& destinations,
GenericPathContainer<PathContainerGraphType>* const path_container) {
GenericPathContainer<GraphType>* const path_container) {
std::vector<typename GraphType::NodeIndex> sources(1, source);
ComputeManyToManyShortestPathsWithMultipleThreads(
graph, arc_lengths, sources, destinations, 1, path_container);
@@ -282,13 +270,10 @@ void ComputeManyToAllShortestPathsWithMultipleThreads(
}
// Computes shortest paths between all nodes of the graph.
// TODO(b/385094969): Remove second template parameter when all clients are
// migrated.
template <class GraphType, class PathContainerGraphType>
template <class GraphType>
void ComputeAllToAllShortestPathsWithMultipleThreads(
const GraphType& graph, const std::vector<PathDistance>& arc_lengths,
int num_threads,
GenericPathContainer<PathContainerGraphType>* const path_container) {
int num_threads, GenericPathContainer<GraphType>* const path_container) {
std::vector<typename GraphType::NodeIndex> all_nodes;
GetGraphNodesFromGraph<GraphType>(graph, &all_nodes);
ComputeManyToManyShortestPathsWithMultipleThreads(
@@ -635,15 +620,13 @@ bool InsertOrUpdateEntry(
// using a binary heap-based Dijkstra algorithm.
// TODO(user): Investigate alternate implementation which wouldn't use
// AdjustablePriorityQueue.
// TODO(b/385094969): Remove second template parameter when all clients are
// migrated.
template <class GraphType, class PathContainerGraphType>
template <class GraphType>
void ComputeOneToManyOnGraph(
const GraphType* const graph,
const std::vector<PathDistance>* const arc_lengths,
typename GraphType::NodeIndex source,
const std::vector<typename GraphType::NodeIndex>* const destinations,
typename GenericPathContainer<PathContainerGraphType>::Impl* const paths) {
typename GenericPathContainer<GraphType>::Impl* const paths) {
using NodeIndex = typename GraphType::NodeIndex;
using ArcIndex = typename GraphType::ArcIndex;
using NodeEntryT = NodeEntry<NodeIndex, GraphType::kNilNode>;
@@ -715,9 +698,6 @@ void ComputeOneToManyOnGraph(
} // namespace internal
template <class GraphType>
GenericPathContainer<GraphType>::GenericPathContainer() = default;
template <class GraphType>
GenericPathContainer<GraphType>::~GenericPathContainer() = default;
@@ -744,22 +724,6 @@ void GenericPathContainer<GraphType>::GetPath(
container_->GetPath(from, to, path);
}
template <class GraphType>
void GenericPathContainer<GraphType>::BuildPathDistanceContainer(
GenericPathContainer* const path_container) {
CHECK(path_container != nullptr);
path_container->container_ = std::make_unique<
internal::DistanceContainer<NodeIndex, GraphType::kNilNode>>();
}
template <class GraphType>
void GenericPathContainer<GraphType>::BuildInMemoryCompactPathContainer(
GenericPathContainer* const path_container) {
CHECK(path_container != nullptr);
path_container->container_ = std::make_unique<
internal::InMemoryCompactPathContainer<NodeIndex, GraphType::kNilNode>>();
}
template <class GraphType>
GenericPathContainer<GraphType>
GenericPathContainer<GraphType>::BuildPathDistanceContainer() {
@@ -776,22 +740,12 @@ GenericPathContainer<GraphType>::BuildInMemoryCompactPathContainer() {
NodeIndex, GraphType::kNilNode>>());
}
// TODO(b/385094969): Remove second template parameter when all clients are
// migrated.
template <class GraphType, class PathContainerGraphType>
template <class GraphType>
void ComputeManyToManyShortestPathsWithMultipleThreads(
const GraphType& graph, const std::vector<PathDistance>& arc_lengths,
const std::vector<typename GraphType::NodeIndex>& sources,
const std::vector<typename GraphType::NodeIndex>& destinations,
int num_threads,
GenericPathContainer<PathContainerGraphType>* const paths) {
static_assert(std::is_same_v<typename GraphType::NodeIndex,
typename PathContainerGraphType::NodeIndex>,
"use an explicit `GenericPathContainer<T>` instead of using "
"`PathContainer`");
static_assert(GraphType::kNilNode == PathContainerGraphType::kNilNode,
"use an explicit `GenericPathContainer<T>` instead of using "
"`PathContainer`");
int num_threads, GenericPathContainer<GraphType>* const paths) {
if (graph.num_nodes() > 0) {
CHECK_EQ(graph.num_arcs(), arc_lengths.size())
<< "Number of arcs in graph must match arc length vector size";
@@ -812,10 +766,8 @@ void ComputeManyToManyShortestPathsWithMultipleThreads(
pool->StartWorkers();
for (int i = 0; i < unique_sources.size(); ++i) {
pool->Schedule(absl::bind_front(
&internal::ComputeOneToManyOnGraph<GraphType,
PathContainerGraphType>,
&graph, &arc_lengths, unique_sources[i], &unique_destinations,
container));
&internal::ComputeOneToManyOnGraph<GraphType>, &graph, &arc_lengths,
unique_sources[i], &unique_destinations, container));
}
}
container->Finalize();

View File

@@ -15,8 +15,8 @@ package(default_visibility = ["//visibility:public"])
cc_library(
name = "init",
hdrs = ["init.h"],
srcs = ["init.cc"],
hdrs = ["init.h"],
deps = [
"//ortools/base",
"//ortools/gurobi:environment",

View File

@@ -22,25 +22,24 @@
#include "ortools/sat/cp_model_solver_helpers.h"
namespace operations_research {
void CppBridge::InitLogging(const std::string& usage) {
absl::SetProgramUsageMessage(usage);
absl::InitializeLog();
}
void CppBridge::InitLogging(const std::string& usage) {
absl::SetProgramUsageMessage(usage);
absl::InitializeLog();
}
void CppBridge::SetFlags(const CppFlags& flags) {
absl::SetFlag(&FLAGS_stderrthreshold, flags.stderrthreshold);
absl::EnableLogPrefix(flags.log_prefix);
if (!flags.cp_model_dump_prefix.empty()) {
absl::SetFlag(&FLAGS_cp_model_dump_prefix, flags.cp_model_dump_prefix);
}
absl::SetFlag(&FLAGS_cp_model_dump_models, flags.cp_model_dump_models);
absl::SetFlag(&FLAGS_cp_model_dump_submodels,
flags.cp_model_dump_submodels);
absl::SetFlag(&FLAGS_cp_model_dump_response, flags.cp_model_dump_response);
void CppBridge::SetFlags(const CppFlags& flags) {
absl::SetFlag(&FLAGS_stderrthreshold, flags.stderrthreshold);
absl::EnableLogPrefix(flags.log_prefix);
if (!flags.cp_model_dump_prefix.empty()) {
absl::SetFlag(&FLAGS_cp_model_dump_prefix, flags.cp_model_dump_prefix);
}
absl::SetFlag(&FLAGS_cp_model_dump_models, flags.cp_model_dump_models);
absl::SetFlag(&FLAGS_cp_model_dump_submodels, flags.cp_model_dump_submodels);
absl::SetFlag(&FLAGS_cp_model_dump_response, flags.cp_model_dump_response);
}
bool CppBridge::LoadGurobiSharedLibrary(const std::string& full_library_path) {
return LoadGurobiDynamicLibrary({full_library_path}).ok();
}
bool CppBridge::LoadGurobiSharedLibrary(const std::string& full_library_path) {
return LoadGurobiDynamicLibrary({full_library_path}).ok();
}
} // namespace operations_research

View File

@@ -142,8 +142,8 @@ public class Loader {
URI resourceURI = getNativeResourceURI();
Path tempPath = unpackNativeResources(resourceURI);
// libraries order does matter !
List<String> dlls = Arrays.asList(
"zlib1", "abseil_dll", "re2", "utf8_validity", "libprotobuf", "highs", "ortools", "jniortools");
List<String> dlls = Arrays.asList("zlib1", "abseil_dll", "re2", "utf8_validity",
"libprotobuf", "highs", "ortools", "jniortools");
for (String dll : dlls) {
try {
// System.out.println("System.load(" + dll + ")");

View File

@@ -140,7 +140,7 @@ class MPModelProtoExporter {
// into two constraints, one for the left hand side (_lhs) and one for right
// hand side (_rhs).
bool AppendConstraint(const MPConstraintProto& ct_proto,
const std::string& name, LineBreaker& line_breaker,
absl::string_view name, LineBreaker& line_breaker,
std::vector<bool>& show_variable, std::string* output);
// Clears "output" and writes a term to it, in "LP" format. Returns false on
@@ -159,8 +159,8 @@ class MPModelProtoExporter {
// Same as AppendMpsLineHeader. Appends an extra new-line at the end the
// string pointed to by output.
void AppendMpsLineHeaderWithNewLine(const std::string& id,
const std::string& name,
void AppendMpsLineHeaderWithNewLine(absl::string_view id,
absl::string_view name,
std::string* output) const;
// Appends an MPS term in various contexts. The term consists of a head name,
@@ -186,7 +186,7 @@ class MPModelProtoExporter {
// Appends a line describing the bound of a variablenew-line if two columns
// are already present on the MPS line.
// Used by and in complement to AppendMpsTermWithContext.
void AppendMpsBound(const std::string& bound_type, const std::string& name,
void AppendMpsBound(absl::string_view bound_type, absl::string_view name,
double value, std::string* output) const;
const MPModelProto& proto_;
@@ -392,7 +392,7 @@ std::string DoubleToString(double d) { return absl::StrCat((d)); }
} // namespace
bool MPModelProtoExporter::AppendConstraint(const MPConstraintProto& ct_proto,
const std::string& name,
absl::string_view name,
LineBreaker& line_breaker,
std::vector<bool>& show_variable,
std::string* output) {
@@ -414,7 +414,7 @@ bool MPModelProtoExporter::AppendConstraint(const MPConstraintProto& ct_proto,
absl::StrAppend(output, " ", name, ": ", line_breaker.GetOutput());
} else {
if (ub != +kInfinity) {
std::string rhs_name = name;
std::string rhs_name(name);
if (lb != -kInfinity) {
absl::StrAppend(&rhs_name, "_rhs");
}
@@ -427,7 +427,7 @@ bool MPModelProtoExporter::AppendConstraint(const MPConstraintProto& ct_proto,
absl::StrAppend(output, relation);
}
if (lb != -kInfinity) {
std::string lhs_name = name;
std::string lhs_name(name);
if (ub != +kInfinity) {
absl::StrAppend(&lhs_name, "_lhs");
}
@@ -462,7 +462,7 @@ bool IsBoolean(const MPVariableProto& var) {
floor(var.upper_bound()) == 1.0;
}
void UpdateMaxSize(const std::string& new_string, int* size) {
void UpdateMaxSize(absl::string_view new_string, int* size) {
const int new_size = new_string.size();
if (new_size > *size) *size = new_size;
}
@@ -687,7 +687,7 @@ void MPModelProtoExporter::AppendMpsLineHeader(absl::string_view id,
}
void MPModelProtoExporter::AppendMpsLineHeaderWithNewLine(
const std::string& id, const std::string& name, std::string* output) const {
absl::string_view id, absl::string_view name, std::string* output) const {
AppendMpsLineHeader(id, name, output);
absl::StripTrailingAsciiWhitespace(output);
absl::StrAppend(output, "\n");
@@ -704,8 +704,8 @@ void MPModelProtoExporter::AppendMpsTermWithContext(absl::string_view head_name,
AppendNewLineIfTwoColumns(output);
}
void MPModelProtoExporter::AppendMpsBound(const std::string& bound_type,
const std::string& name, double value,
void MPModelProtoExporter::AppendMpsBound(absl::string_view bound_type,
absl::string_view name, double value,
std::string* output) const {
AppendMpsLineHeader(bound_type, "BOUND", output);
AppendMpsPair(name, value, output);

View File

@@ -1262,7 +1262,7 @@ std::optional<TerminationReason> PreprocessSolver::ApplyPresolveIfEnabled(
// set it for completeness.
presolved_qp->objective_scaling_factor = glop_lp.objective_scaling_factor();
sharded_qp_ = ShardedQuadraticProgram(std::move(*presolved_qp), num_threads_,
num_shards_);
num_shards_, params.scheduler_type());
// A status of `INIT` means the preprocessor created a (usually) smaller
// problem that needs solving. Other statuses mean the preprocessor solved
// the problem completely.

View File

@@ -2054,6 +2054,7 @@ cc_test(
"//ortools/base",
"//ortools/base:gmock_main",
"//ortools/util:sorted_interval_list",
"@com_google_absl//absl/types:span",
],
)
@@ -2656,9 +2657,11 @@ cc_library(
":model",
":precedences",
":sat_base",
":util",
"//ortools/base",
"//ortools/base:mathutil",
"//ortools/base:strong_vector",
"//ortools/graph",
"//ortools/graph:max_flow",
"//ortools/util:strong_integers",
"@com_google_absl//absl/algorithm:container",
@@ -2982,6 +2985,7 @@ cc_test(
"//ortools/base",
"//ortools/base:gmock_main",
"//ortools/base:mathutil",
"//ortools/base:stl_util",
"//ortools/util:random_engine",
"//ortools/util:sorted_interval_list",
"@com_google_absl//absl/container:btree",

View File

@@ -11,7 +11,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
file(GLOB _SRCS "*.h" "*.cc" "python/linear_expr.*")
file(GLOB _SRCS "*.h" "*.cc" "python/linear_expr.*" "c_api/*.h" "c_api/*.cc")
list(FILTER _SRCS EXCLUDE REGEX ".*/.*_test.cc")
list(FILTER _SRCS EXCLUDE REGEX ".*/.*_fuzz.cc")
list(REMOVE_ITEM _SRCS

View File

@@ -20,6 +20,7 @@
#include <string>
#include <vector>
#include "absl/types/span.h"
#include "gtest/gtest.h"
#include "ortools/base/logging.h"
#include "ortools/sat/integer.h"
@@ -36,8 +37,9 @@ namespace {
class AllDifferentTest : public ::testing::TestWithParam<std::string> {
public:
std::function<void(Model*)> AllDifferent(
const std::vector<IntegerVariable>& vars) {
return [=](Model* model) {
absl::Span<const IntegerVariable> vars) {
return [=, vars = std::vector<IntegerVariable>(vars.begin(), vars.end())](
Model* model) {
if (GetParam() == "binary") {
model->Add(AllDifferentBinary(vars));
} else if (GetParam() == "ac") {

View File

@@ -0,0 +1,31 @@
# 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("@rules_cc//cc:defs.bzl", "cc_library")
package(default_visibility = ["//visibility:public"])
cc_library(
name = "cp_solver_c",
srcs = ["cp_solver_c.cc"],
hdrs = ["cp_solver_c.h"],
deps = [
"//ortools/base:memutil",
"//ortools/sat:cp_model_cc_proto",
"//ortools/sat:cp_model_solver",
"//ortools/sat:model",
"//ortools/sat:sat_parameters_cc_proto",
"//ortools/util:time_limit",
"@com_google_absl//absl/log:check",
],
)

View File

@@ -11,7 +11,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "ortools/sat/go/cpmodel/cp_solver_c.h"
#include "ortools/sat/c_api/cp_solver_c.h"
#include <atomic>
#include <string>

View File

@@ -11,8 +11,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef OR_TOOLS_SAT_GO_CP_SOLVER_C_H_
#define OR_TOOLS_SAT_GO_CP_SOLVER_C_H_
#ifndef OR_TOOLS_SAT_C_API_CP_SOLVER_C_H_
#define OR_TOOLS_SAT_C_API_CP_SOLVER_C_H_
#include <stddef.h>
#include <stdint.h>
@@ -38,4 +38,4 @@ void SolveCpInterruptible(void* limit_reached, const void* creq, int creq_len,
} // extern "C"
#endif
#endif // OR_TOOLS_SAT_GO_CP_SOLVER_C_H_
#endif // OR_TOOLS_SAT_C_API_CP_SOLVER_C_H_

View File

@@ -869,8 +869,8 @@ void ExpandElement(ConstraintProto* ct, PresolveContext* context) {
// Adds clauses so that literals[i] true <=> encoding[values[i]] true.
// This also implicitly use the fact that exactly one alternative is true.
void LinkLiteralsAndValues(const std::vector<int>& literals,
const std::vector<int64_t>& values,
void LinkLiteralsAndValues(absl::Span<const int> literals,
absl::Span<const int64_t> values,
const absl::flat_hash_map<int64_t, int>& encoding,
PresolveContext* context) {
CHECK_EQ(literals.size(), values.size());

View File

@@ -20,7 +20,7 @@ go_library(
"cp_solver.go",
"domain.go",
],
cdeps = [":cp_solver_c"],
cdeps = ["//ortools/sat/c_api:cp_solver_c"],
cgo = True,
importpath = "github.com/google/or-tools/ortools/sat/go/cpmodel",
visibility = ["//visibility:public"],
@@ -49,18 +49,3 @@ go_test(
"@org_golang_google_protobuf//testing/protocmp",
],
)
cc_library(
name = "cp_solver_c",
srcs = ["cp_solver_c.cc"],
hdrs = ["cp_solver_c.h"],
deps = [
"//ortools/base:memutil",
"//ortools/sat:cp_model_cc_proto",
"//ortools/sat:cp_model_solver",
"//ortools/sat:model",
"//ortools/sat:sat_parameters_cc_proto",
"//ortools/util:time_limit",
"@com_google_absl//absl/log:check",
],
)

View File

@@ -27,7 +27,7 @@ import (
/*
#include <stdlib.h> // for free
#include <stdint.h>
#include "ortools/sat/go/cpmodel/cp_solver_c.h"
#include "ortools/sat/c_api/cp_solver_c.h"
*/
import "C"

View File

@@ -196,9 +196,9 @@ function test_wheel() {
"ortools/linear_solver/samples/simple_lp_program.py"
"ortools/linear_solver/samples/simple_mip_program.py"
"ortools/sat/samples/simple_sat_program.py"
"ortools/constraint_solver/samples/tsp.py"
"ortools/constraint_solver/samples/vrp.py"
"ortools/constraint_solver/samples/cvrptw_break.py"
"ortools/routing/samples/tsp.py"
"ortools/routing/samples/vrp.py"
"ortools/routing/samples/cvrptw_break.py"
)
# Run all the specified test scripts using the current environment.