Skip to content

Commit 2761e67

Browse files
committed
math_opt: export from google3
* CMake has not been updated yet * bazel was compiling at least last week
1 parent d356be0 commit 2761e67

File tree

231 files changed

+28158
-5614
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

231 files changed

+28158
-5614
lines changed

ortools/math_opt/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ endif()
1818
add_subdirectory(core)
1919
add_subdirectory(constraints)
2020
add_subdirectory(cpp)
21+
add_subdirectory(elemental)
2122
add_subdirectory(io)
2223
add_subdirectory(labs)
2324
add_subdirectory(solver_tests)
@@ -31,6 +32,7 @@ target_sources(${NAME} PUBLIC
3132
$<TARGET_OBJECTS:${NAME}_core>
3233
$<TARGET_OBJECTS:${NAME}_core_c_api>
3334
$<TARGET_OBJECTS:${NAME}_cpp>
35+
$<TARGET_OBJECTS:${NAME}_elemental>
3436
$<TARGET_OBJECTS:${NAME}_io>
3537
$<TARGET_OBJECTS:${NAME}_labs>
3638
$<TARGET_OBJECTS:${NAME}_solvers>

ortools/math_opt/README.md

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# math_opt
2+
3+
The code in this directory provides a generic way of accessing mathematical
4+
optimization solvers (sometimes called mathematical programming solvers), such
5+
as GLOP, CP-SAT, SCIP and Gurobi. In particular, a single API is provided to
6+
make these solvers largely interoperable.
7+
8+
New code should prefer MathOpt to `MPSolver`, as defined in
9+
[linear_solver.h](../linear_solver/linear_solver.h)
10+
when possible.
11+
12+
MathOpt has client libraries in C++, Python, and Java that most users should use
13+
to build and solve their models. A proto API is also provided, but this is not
14+
recommended for most users.
15+
16+
See
17+
[parameters.proto](../math_opt/parameters.proto?q=SolverTypeProto)
18+
for the list of supported solvers.

ortools/math_opt/callback.proto

+11-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,17 @@ message CallbackResultProto {
158158
bool is_lazy = 4;
159159
}
160160

161-
// Ends the solve early.
161+
// When true it tells the solver to interrupt the solve as soon as possible.
162+
//
163+
// It can be set from any event. This is equivalent to using a
164+
// SolveInterrupter and triggering it from the callback.
165+
//
166+
// Some solvers don't support interruption, in that case this is simply
167+
// ignored and the solve terminates as usual. On top of that solvers may not
168+
// immediately stop the solve. Thus the user should expect the callback to
169+
// still be called after they set `terminate` to true in a previous
170+
// call. Returning with `terminate` false after having previously returned
171+
// true won't cancel the interruption.
162172
bool terminate = 1;
163173

164174
// TODO(b/172214608): SCIP allows to reject a feasible solution without

ortools/math_opt/constraints/indicator/BUILD.bazel

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ cc_library(
1818
srcs = ["indicator_constraint.cc"],
1919
hdrs = ["indicator_constraint.h"],
2020
deps = [
21-
"//ortools/base:intops",
2221
"//ortools/math_opt/constraints/util:model_util",
2322
"//ortools/math_opt/cpp:variable_and_expressions",
23+
"//ortools/math_opt/elemental:elements",
2424
"//ortools/math_opt/storage:model_storage",
25+
"//ortools/math_opt/storage:model_storage_item",
2526
"@abseil-cpp//absl/strings",
2627
],
2728
)
@@ -51,6 +52,7 @@ cc_library(
5152
"//ortools/math_opt:model_update_cc_proto",
5253
"//ortools/math_opt:sparse_containers_cc_proto",
5354
"//ortools/math_opt/core:sorted",
55+
"//ortools/math_opt/elemental:elements",
5456
"//ortools/math_opt/storage:atomic_constraint_storage",
5557
"//ortools/math_opt/storage:sparse_coefficient_map",
5658
"@abseil-cpp//absl/container:flat_hash_set",

ortools/math_opt/constraints/indicator/indicator_constraint.cc

+5-7
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,29 @@
1818
#include <string>
1919
#include <utility>
2020

21-
#include "absl/strings/string_view.h"
22-
#include "ortools/base/strong_int.h"
2321
#include "ortools/math_opt/constraints/util/model_util.h"
2422
#include "ortools/math_opt/cpp/variable_and_expressions.h"
2523
#include "ortools/math_opt/storage/model_storage.h"
2624

2725
namespace operations_research::math_opt {
2826

2927
BoundedLinearExpression IndicatorConstraint::ImpliedConstraint() const {
30-
const IndicatorConstraintData& data = storage()->constraint_data(id_);
28+
const IndicatorConstraintData& data = storage()->constraint_data(typed_id());
3129
// NOTE: The following makes a copy of `data.linear_terms`. This can be made
3230
// more efficient if the need arises.
3331
LinearExpression expr = ToLinearExpression(
34-
*storage_, {.coeffs = data.linear_terms, .offset = 0.0});
32+
*storage(), {.coeffs = data.linear_terms, .offset = 0.0});
3533
return data.lower_bound <= std::move(expr) <= data.upper_bound;
3634
}
3735

3836
std::string IndicatorConstraint::ToString() const {
39-
if (!storage()->has_constraint(id_)) {
37+
if (!storage()->has_constraint(typed_id())) {
4038
return std::string(kDeletedConstraintDefaultDescription);
4139
}
42-
const IndicatorConstraintData& data = storage()->constraint_data(id_);
40+
const IndicatorConstraintData& data = storage()->constraint_data(typed_id());
4341
std::stringstream str;
4442
if (data.indicator.has_value()) {
45-
str << Variable(storage_, *data.indicator)
43+
str << Variable(storage(), *data.indicator)
4644
<< (data.activate_on_zero ? " = 0" : " = 1");
4745
} else {
4846
str << "[unset indicator variable]";

ortools/math_opt/constraints/indicator/indicator_constraint.h

+14-79
Original file line numberDiff line numberDiff line change
@@ -16,38 +16,28 @@
1616
#ifndef OR_TOOLS_MATH_OPT_CONSTRAINTS_INDICATOR_INDICATOR_CONSTRAINT_H_
1717
#define OR_TOOLS_MATH_OPT_CONSTRAINTS_INDICATOR_INDICATOR_CONSTRAINT_H_
1818

19-
#include <cstdint>
2019
#include <optional>
21-
#include <ostream>
2220
#include <string>
2321
#include <vector>
2422

2523
#include "absl/strings/string_view.h"
26-
#include "ortools/base/strong_int.h"
2724
#include "ortools/math_opt/constraints/util/model_util.h"
2825
#include "ortools/math_opt/cpp/variable_and_expressions.h"
26+
#include "ortools/math_opt/elemental/elements.h"
2927
#include "ortools/math_opt/storage/model_storage.h"
28+
#include "ortools/math_opt/storage/model_storage_item.h"
3029

3130
namespace operations_research::math_opt {
3231

3332
// A value type that references an indicator constraint from ModelStorage.
3433
// Usually this type is passed by copy.
35-
//
36-
// This type implements https://abseil.io/docs/cpp/guides/hash.
37-
class IndicatorConstraint {
34+
class IndicatorConstraint final
35+
: public ModelStorageElement<ElementType::kIndicatorConstraint,
36+
IndicatorConstraint> {
3837
public:
39-
// The typed integer used for ids.
40-
using IdType = IndicatorConstraintId;
41-
42-
inline IndicatorConstraint(const ModelStorage* storage,
43-
IndicatorConstraintId id);
44-
45-
inline int64_t id() const;
38+
using ModelStorageElement::ModelStorageElement;
4639

47-
inline IndicatorConstraintId typed_id() const;
48-
inline const ModelStorage* storage() const;
49-
50-
inline absl::string_view name() const;
40+
absl::string_view name() const;
5141

5242
// Returns nullopt if the indicator variable is unset (this is a valid state,
5343
// in which the constraint is functionally ignored).
@@ -65,91 +55,36 @@ class IndicatorConstraint {
6555
// Returns a detailed string description of the contents of the constraint
6656
// (not its name, use `<<` for that instead).
6757
std::string ToString() const;
68-
69-
friend inline bool operator==(const IndicatorConstraint& lhs,
70-
const IndicatorConstraint& rhs);
71-
friend inline bool operator!=(const IndicatorConstraint& lhs,
72-
const IndicatorConstraint& rhs);
73-
template <typename H>
74-
friend H AbslHashValue(H h, const IndicatorConstraint& constraint);
75-
friend std::ostream& operator<<(std::ostream& ostr,
76-
const IndicatorConstraint& constraint);
77-
78-
private:
79-
const ModelStorage* storage_;
80-
IndicatorConstraintId id_;
8158
};
8259

83-
// Streams the name of the constraint, as registered upon constraint creation,
84-
// or a short default if none was provided.
85-
inline std::ostream& operator<<(std::ostream& ostr,
86-
const IndicatorConstraint& constraint);
87-
8860
////////////////////////////////////////////////////////////////////////////////
8961
// Inline function implementations
9062
////////////////////////////////////////////////////////////////////////////////
9163

92-
int64_t IndicatorConstraint::id() const { return id_.value(); }
93-
94-
IndicatorConstraintId IndicatorConstraint::typed_id() const { return id_; }
95-
96-
const ModelStorage* IndicatorConstraint::storage() const { return storage_; }
97-
98-
absl::string_view IndicatorConstraint::name() const {
99-
if (storage_->has_constraint(id_)) {
100-
return storage_->constraint_data(id_).name;
64+
inline absl::string_view IndicatorConstraint::name() const {
65+
if (storage()->has_constraint(typed_id())) {
66+
return storage()->constraint_data(typed_id()).name;
10167
}
10268
return kDeletedConstraintDefaultDescription;
10369
}
10470

10571
std::optional<Variable> IndicatorConstraint::indicator_variable() const {
10672
const std::optional<VariableId> maybe_indicator =
107-
storage_->constraint_data(id_).indicator;
73+
storage()->constraint_data(typed_id()).indicator;
10874
if (!maybe_indicator.has_value()) {
10975
return std::nullopt;
11076
}
111-
return Variable(storage_, *maybe_indicator);
77+
return Variable(storage(), *maybe_indicator);
11278
}
11379

11480
bool IndicatorConstraint::activate_on_zero() const {
115-
return storage_->constraint_data(id_).activate_on_zero;
81+
return storage()->constraint_data(typed_id()).activate_on_zero;
11682
}
11783

11884
std::vector<Variable> IndicatorConstraint::NonzeroVariables() const {
119-
return AtomicConstraintNonzeroVariables(*storage_, id_);
85+
return AtomicConstraintNonzeroVariables(*storage(), typed_id());
12086
}
12187

122-
bool operator==(const IndicatorConstraint& lhs,
123-
const IndicatorConstraint& rhs) {
124-
return lhs.id_ == rhs.id_ && lhs.storage_ == rhs.storage_;
125-
}
126-
127-
bool operator!=(const IndicatorConstraint& lhs,
128-
const IndicatorConstraint& rhs) {
129-
return !(lhs == rhs);
130-
}
131-
132-
template <typename H>
133-
H AbslHashValue(H h, const IndicatorConstraint& constraint) {
134-
return H::combine(std::move(h), constraint.id_.value(), constraint.storage_);
135-
}
136-
137-
std::ostream& operator<<(std::ostream& ostr,
138-
const IndicatorConstraint& constraint) {
139-
// TODO(b/170992529): handle quoting of invalid characters in the name.
140-
const absl::string_view name = constraint.name();
141-
if (name.empty()) {
142-
ostr << "__indic_con#" << constraint.id() << "__";
143-
} else {
144-
ostr << name;
145-
}
146-
return ostr;
147-
}
148-
149-
IndicatorConstraint::IndicatorConstraint(const ModelStorage* const storage,
150-
const IndicatorConstraintId id)
151-
: storage_(storage), id_(id) {}
152-
15388
} // namespace operations_research::math_opt
15489

15590
#endif // OR_TOOLS_MATH_OPT_CONSTRAINTS_INDICATOR_INDICATOR_CONSTRAINT_H_

ortools/math_opt/constraints/indicator/storage.h

+5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <string>
2020
#include <vector>
2121

22+
#include "ortools/math_opt/elemental/elements.h"
2223
#include "ortools/math_opt/model.pb.h"
2324
#include "ortools/math_opt/model_update.pb.h"
2425
#include "ortools/math_opt/storage/atomic_constraint_storage.h"
@@ -34,6 +35,8 @@ struct IndicatorConstraintData {
3435
using IdType = IndicatorConstraintId;
3536
using ProtoType = IndicatorConstraintProto;
3637
using UpdatesProtoType = IndicatorConstraintUpdatesProto;
38+
static constexpr ElementType kElementType = ElementType::kIndicatorConstraint;
39+
static constexpr bool kSupportsElemental = true;
3740

3841
// The `in_proto` must be in a valid state; see the inline comments on
3942
// `IndicatorConstraintProto` for details.
@@ -55,6 +58,8 @@ struct IndicatorConstraintData {
5558
template <>
5659
struct AtomicConstraintTraits<IndicatorConstraintId> {
5760
using ConstraintData = IndicatorConstraintData;
61+
static constexpr ElementType kElementType = ElementType::kIndicatorConstraint;
62+
static constexpr bool kSupportsElemental = true;
5863
};
5964

6065
} // namespace operations_research::math_opt

ortools/math_opt/constraints/quadratic/BUILD.bazel

+3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ cc_library(
2222
"//ortools/math_opt/constraints/util:model_util",
2323
"//ortools/math_opt/cpp:key_types",
2424
"//ortools/math_opt/cpp:variable_and_expressions",
25+
"//ortools/math_opt/elemental:elements",
2526
"//ortools/math_opt/storage:model_storage",
27+
"//ortools/math_opt/storage:model_storage_item",
2628
"//ortools/math_opt/storage:sparse_coefficient_map",
2729
"//ortools/math_opt/storage:sparse_matrix",
2830
"@abseil-cpp//absl/log:check",
@@ -54,6 +56,7 @@ cc_library(
5456
"//ortools/math_opt:model_cc_proto",
5557
"//ortools/math_opt:model_update_cc_proto",
5658
"//ortools/math_opt:sparse_containers_cc_proto",
59+
"//ortools/math_opt/elemental:elements",
5760
"//ortools/math_opt/storage:atomic_constraint_storage",
5861
"//ortools/math_opt/storage:model_storage_types",
5962
"//ortools/math_opt/storage:sparse_coefficient_map",

ortools/math_opt/constraints/quadratic/quadratic_constraint.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace operations_research::math_opt {
2626
BoundedQuadraticExpression QuadraticConstraint::AsBoundedQuadraticExpression()
2727
const {
2828
QuadraticExpression expression;
29-
const QuadraticConstraintData& data = storage()->constraint_data(id_);
29+
const QuadraticConstraintData& data = storage()->constraint_data(typed_id());
3030
for (const auto [var, coeff] : data.linear_terms.terms()) {
3131
expression += coeff * Variable(storage(), var);
3232
}

0 commit comments

Comments
 (0)