or-tools 0.4.1 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/ext/or-tools/assignment.cpp +2 -5
- data/ext/or-tools/bin_packing.cpp +26 -33
- data/ext/or-tools/constraint.cpp +203 -210
- data/ext/or-tools/ext.cpp +3 -3
- data/ext/or-tools/ext.h +4 -0
- data/ext/or-tools/extconf.rb +1 -3
- data/ext/or-tools/linear.cpp +74 -67
- data/ext/or-tools/network_flows.cpp +7 -9
- data/ext/or-tools/routing.cpp +70 -147
- data/ext/or-tools/vendor.rb +25 -11
- data/lib/or_tools/cp_solver.rb +4 -0
- data/lib/or_tools/seating.rb +1 -1
- data/lib/or_tools/version.rb +1 -1
- metadata +6 -61
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4e179505f9df7d80af6a316ca719594fa2a99839c8c26b0f33ee1551b4e7b2d3
|
|
4
|
+
data.tar.gz: b05dc3c553d11112e55855bb91b0382a3a648a14848e5c9d6e3805bf52e009fb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fa77b818baf408c3cf30b56065f0b9b7f877358e1f0d39718a3ebc1f49fc4dae78da9678875c340895427f189074939e220ffa320207bea76bd0d7921f0675d7
|
|
7
|
+
data.tar.gz: 7c174df348ad0835c93a56ecb51a6f9763aaba43f0d3fc3eaf0b8b745922a204d86ee6fae6ba3fba632b284179251decbbfce17b2a1dd1e608d91b96cf3ff9ec
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
## 0.5.2 (2021-07-07)
|
|
2
|
+
|
|
3
|
+
- Added `export_model_as_lp_format` and `export_model_as_mps_format` to `Solver`
|
|
4
|
+
|
|
5
|
+
## 0.5.1 (2021-05-23)
|
|
6
|
+
|
|
7
|
+
- Updated to Rice 4
|
|
8
|
+
|
|
9
|
+
## 0.5.0 (2021-04-30)
|
|
10
|
+
|
|
11
|
+
- Updated OR-Tools to 9.0
|
|
12
|
+
- Added binary installation for CentOS 7
|
|
13
|
+
- Added `sufficient_assumptions_for_infeasibility` to `CpSolver`
|
|
14
|
+
|
|
15
|
+
## 0.4.3 (2021-03-26)
|
|
16
|
+
|
|
17
|
+
- Added `add_assumption`, `add_assumptions`, and `clear_assumptions` to `CpModel`
|
|
18
|
+
- Added `add_hint` and `clear_hints` to `CpModel`
|
|
19
|
+
- Added `only_enforce_if` to `SatConstraint`
|
|
20
|
+
- Fixed installation for Debian
|
|
21
|
+
|
|
22
|
+
## 0.4.2 (2021-03-03)
|
|
23
|
+
|
|
24
|
+
- Updated OR-Tools to 8.2
|
|
25
|
+
|
|
1
26
|
## 0.4.1 (2021-02-23)
|
|
2
27
|
|
|
3
28
|
- Added solution printers
|
data/ext/or-tools/assignment.cpp
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
#include <ortools/graph/assignment.h>
|
|
2
2
|
|
|
3
|
-
#include
|
|
4
|
-
#include <rice/Constructor.hpp>
|
|
5
|
-
#include <rice/Module.hpp>
|
|
3
|
+
#include "ext.h"
|
|
6
4
|
|
|
7
5
|
using operations_research::SimpleLinearSumAssignment;
|
|
8
6
|
|
|
9
|
-
using Rice::Array;
|
|
10
7
|
using Rice::Symbol;
|
|
11
8
|
|
|
12
9
|
void init_assignment(Rice::Module& m) {
|
|
@@ -23,7 +20,7 @@ void init_assignment(Rice::Module& m) {
|
|
|
23
20
|
.define_method("assignment_cost", &SimpleLinearSumAssignment::AssignmentCost)
|
|
24
21
|
.define_method(
|
|
25
22
|
"solve",
|
|
26
|
-
|
|
23
|
+
[](SimpleLinearSumAssignment& self) {
|
|
27
24
|
auto status = self.Solve();
|
|
28
25
|
|
|
29
26
|
if (status == SimpleLinearSumAssignment::Status::OPTIMAL) {
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
#include <ortools/algorithms/knapsack_solver.h>
|
|
2
2
|
|
|
3
|
-
#include
|
|
4
|
-
#include <rice/Constructor.hpp>
|
|
5
|
-
#include <rice/Module.hpp>
|
|
3
|
+
#include "ext.h"
|
|
6
4
|
|
|
7
5
|
using operations_research::KnapsackSolver;
|
|
8
6
|
|
|
@@ -10,16 +8,31 @@ using Rice::Array;
|
|
|
10
8
|
using Rice::Object;
|
|
11
9
|
using Rice::Symbol;
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
inline
|
|
15
|
-
KnapsackSolver::SolverType from_ruby<KnapsackSolver::SolverType>(Object x)
|
|
11
|
+
namespace Rice::detail
|
|
16
12
|
{
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
13
|
+
template<>
|
|
14
|
+
struct Type<KnapsackSolver::SolverType>
|
|
15
|
+
{
|
|
16
|
+
static bool verify()
|
|
17
|
+
{
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
template<>
|
|
23
|
+
class From_Ruby<KnapsackSolver::SolverType>
|
|
24
|
+
{
|
|
25
|
+
public:
|
|
26
|
+
KnapsackSolver::SolverType convert(VALUE x)
|
|
27
|
+
{
|
|
28
|
+
auto s = Symbol(x).str();
|
|
29
|
+
if (s == "branch_and_bound") {
|
|
30
|
+
return KnapsackSolver::KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER;
|
|
31
|
+
} else {
|
|
32
|
+
throw std::runtime_error("Unknown solver type: " + s);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
};
|
|
23
36
|
}
|
|
24
37
|
|
|
25
38
|
void init_bin_packing(Rice::Module& m) {
|
|
@@ -29,27 +42,7 @@ void init_bin_packing(Rice::Module& m) {
|
|
|
29
42
|
.define_method("best_solution_contains?", &KnapsackSolver::BestSolutionContains)
|
|
30
43
|
.define_method(
|
|
31
44
|
"init",
|
|
32
|
-
|
|
33
|
-
std::vector<int64> values;
|
|
34
|
-
for (std::size_t i = 0; i < rb_values.size(); ++i) {
|
|
35
|
-
values.push_back(from_ruby<int64>(rb_values[i]));
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
std::vector<std::vector<int64>> weights;
|
|
39
|
-
for (std::size_t i = 0; i < rb_weights.size(); ++i) {
|
|
40
|
-
Array rb_w = Array(rb_weights[i]);
|
|
41
|
-
std::vector<int64> w;
|
|
42
|
-
for (std::size_t j = 0; j < rb_w.size(); ++j) {
|
|
43
|
-
w.push_back(from_ruby<int64>(rb_w[j]));
|
|
44
|
-
}
|
|
45
|
-
weights.push_back(w);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
std::vector<int64> capacities;
|
|
49
|
-
for (std::size_t i = 0; i < rb_capacities.size(); ++i) {
|
|
50
|
-
capacities.push_back(from_ruby<int64>(rb_capacities[i]));
|
|
51
|
-
}
|
|
52
|
-
|
|
45
|
+
[](KnapsackSolver& self, std::vector<int64_t> values, std::vector<std::vector<int64_t>> weights, std::vector<int64_t> capacities) {
|
|
53
46
|
self.Init(values, weights, capacities);
|
|
54
47
|
});
|
|
55
48
|
}
|
data/ext/or-tools/constraint.cpp
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
#include <google/protobuf/text_format.h>
|
|
2
2
|
#include <ortools/sat/cp_model.h>
|
|
3
3
|
|
|
4
|
-
#include
|
|
5
|
-
#include <rice/Constructor.hpp>
|
|
6
|
-
#include <rice/Module.hpp>
|
|
4
|
+
#include "ext.h"
|
|
7
5
|
|
|
8
6
|
using operations_research::sat::BoolVar;
|
|
9
7
|
using operations_research::sat::Constraint;
|
|
@@ -20,153 +18,113 @@ using operations_research::sat::SolutionBooleanValue;
|
|
|
20
18
|
using operations_research::sat::SolutionIntegerValue;
|
|
21
19
|
|
|
22
20
|
using Rice::Array;
|
|
21
|
+
using Rice::Class;
|
|
23
22
|
using Rice::Object;
|
|
24
23
|
using Rice::String;
|
|
25
24
|
using Rice::Symbol;
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
LinearExpr from_ruby<LinearExpr>(Object x)
|
|
30
|
-
{
|
|
31
|
-
LinearExpr expr;
|
|
26
|
+
Class rb_cBoolVar;
|
|
27
|
+
Class rb_cSatIntVar;
|
|
32
28
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
std::string type = ((String) o.call("class").call("name")).str();
|
|
42
|
-
if (type == "ORTools::BoolVar") {
|
|
43
|
-
expr.AddTerm(from_ruby<BoolVar>(cvar[0]), from_ruby<int64>(cvar[1]));
|
|
44
|
-
} else if (type == "Integer") {
|
|
45
|
-
expr.AddConstant(from_ruby<int64>(cvar[0]) * from_ruby<int64>(cvar[1]));
|
|
46
|
-
} else {
|
|
47
|
-
expr.AddTerm(from_ruby<IntVar>(cvar[0]), from_ruby<int64>(cvar[1]));
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
} else {
|
|
51
|
-
std::string type = ((String) x.call("class").call("name")).str();
|
|
52
|
-
if (type == "ORTools::BoolVar") {
|
|
53
|
-
expr = from_ruby<BoolVar>(x);
|
|
54
|
-
} else {
|
|
55
|
-
expr = from_ruby<IntVar>(x);
|
|
29
|
+
namespace Rice::detail
|
|
30
|
+
{
|
|
31
|
+
template<>
|
|
32
|
+
struct Type<LinearExpr>
|
|
33
|
+
{
|
|
34
|
+
static bool verify()
|
|
35
|
+
{
|
|
36
|
+
return true;
|
|
56
37
|
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return expr;
|
|
60
|
-
}
|
|
38
|
+
};
|
|
61
39
|
|
|
62
|
-
|
|
63
|
-
class
|
|
64
|
-
|
|
40
|
+
template<>
|
|
41
|
+
class From_Ruby<LinearExpr>
|
|
42
|
+
{
|
|
65
43
|
public:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
vec.push_back(from_ruby<IntVar>(a[i]));
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
operator absl::Span<const IntVar>() {
|
|
74
|
-
return absl::Span<const IntVar>(vec);
|
|
75
|
-
}
|
|
76
|
-
};
|
|
44
|
+
LinearExpr convert(VALUE v)
|
|
45
|
+
{
|
|
46
|
+
Object x(v);
|
|
47
|
+
LinearExpr expr;
|
|
77
48
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
49
|
+
if (x.respond_to("to_i")) {
|
|
50
|
+
expr = From_Ruby<int64_t>().convert(x.call("to_i").value());
|
|
51
|
+
} else if (x.respond_to("vars")) {
|
|
52
|
+
Array vars = x.call("vars");
|
|
53
|
+
for (const auto& v : vars) {
|
|
54
|
+
// TODO clean up
|
|
55
|
+
auto cvar = (Array) v;
|
|
56
|
+
Object var = cvar[0];
|
|
57
|
+
auto coeff = From_Ruby<int64_t>().convert(cvar[1].value());
|
|
84
58
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
59
|
+
if (var.is_a(rb_cBoolVar)) {
|
|
60
|
+
expr.AddTerm(From_Ruby<BoolVar>().convert(var.value()), coeff);
|
|
61
|
+
} else if (var.is_a(rb_cInteger)) {
|
|
62
|
+
expr.AddConstant(From_Ruby<int64_t>().convert(var.value()) * coeff);
|
|
63
|
+
} else {
|
|
64
|
+
expr.AddTerm(From_Ruby<IntVar>().convert(var.value()), coeff);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
if (x.is_a(rb_cBoolVar)) {
|
|
69
|
+
expr = From_Ruby<BoolVar>().convert(x.value());
|
|
70
|
+
} else {
|
|
71
|
+
expr = From_Ruby<IntVar>().convert(x.value());
|
|
72
|
+
}
|
|
94
73
|
}
|
|
95
|
-
}
|
|
96
|
-
operator absl::Span<const IntervalVar>() {
|
|
97
|
-
return absl::Span<const IntervalVar>(vec);
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
74
|
|
|
101
|
-
|
|
102
|
-
inline
|
|
103
|
-
IntervalVarSpan from_ruby<IntervalVarSpan>(Object x)
|
|
104
|
-
{
|
|
105
|
-
return IntervalVarSpan(x);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// need a wrapper class since absl::Span doesn't own
|
|
109
|
-
class LinearExprSpan {
|
|
110
|
-
std::vector<LinearExpr> vec;
|
|
111
|
-
public:
|
|
112
|
-
LinearExprSpan(Object x) {
|
|
113
|
-
Array a = Array(x);
|
|
114
|
-
vec.reserve(a.size());
|
|
115
|
-
for (std::size_t i = 0; i < a.size(); ++i) {
|
|
116
|
-
vec.push_back(from_ruby<LinearExpr>(a[i]));
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
operator absl::Span<const LinearExpr>() {
|
|
120
|
-
return absl::Span<const LinearExpr>(vec);
|
|
75
|
+
return expr;
|
|
121
76
|
}
|
|
122
|
-
};
|
|
77
|
+
};
|
|
123
78
|
|
|
124
|
-
template<>
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
{
|
|
128
|
-
return LinearExprSpan(x);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// need a wrapper class since absl::Span doesn't own
|
|
132
|
-
class BoolVarSpan {
|
|
133
|
-
std::vector<BoolVar> vec;
|
|
79
|
+
template<>
|
|
80
|
+
class From_Ruby<std::vector<BoolVar>>
|
|
81
|
+
{
|
|
134
82
|
public:
|
|
135
|
-
|
|
136
|
-
|
|
83
|
+
std::vector<BoolVar> convert(VALUE v)
|
|
84
|
+
{
|
|
85
|
+
auto a = Array(v);
|
|
86
|
+
std::vector<BoolVar> vec;
|
|
137
87
|
vec.reserve(a.size());
|
|
138
|
-
for (
|
|
139
|
-
|
|
88
|
+
for (const Object v : a) {
|
|
89
|
+
if (v.is_a(rb_cSatIntVar)) {
|
|
90
|
+
vec.push_back(From_Ruby<IntVar>().convert(v.value()).ToBoolVar());
|
|
91
|
+
} else {
|
|
92
|
+
vec.push_back(From_Ruby<BoolVar>().convert(v.value()));
|
|
93
|
+
}
|
|
140
94
|
}
|
|
95
|
+
return vec;
|
|
141
96
|
}
|
|
142
|
-
|
|
143
|
-
return absl::Span<const BoolVar>(vec);
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
template<>
|
|
148
|
-
inline
|
|
149
|
-
BoolVarSpan from_ruby<BoolVarSpan>(Object x)
|
|
150
|
-
{
|
|
151
|
-
return BoolVarSpan(x);
|
|
97
|
+
};
|
|
152
98
|
}
|
|
153
99
|
|
|
154
100
|
void init_constraint(Rice::Module& m) {
|
|
155
|
-
Rice::define_class_under<IntVar>(m, "SatIntVar")
|
|
101
|
+
rb_cSatIntVar = Rice::define_class_under<IntVar>(m, "SatIntVar")
|
|
156
102
|
.define_method("name", &IntVar::Name);
|
|
157
103
|
|
|
158
104
|
Rice::define_class_under<IntervalVar>(m, "SatIntervalVar")
|
|
159
105
|
.define_method("name", &IntervalVar::Name);
|
|
160
106
|
|
|
161
|
-
Rice::define_class_under<Constraint>(m, "SatConstraint")
|
|
107
|
+
Rice::define_class_under<Constraint>(m, "SatConstraint")
|
|
108
|
+
.define_method(
|
|
109
|
+
"only_enforce_if",
|
|
110
|
+
[](Constraint& self, Object literal) {
|
|
111
|
+
if (literal.is_a(rb_cSatIntVar)) {
|
|
112
|
+
return self.OnlyEnforceIf(Rice::detail::From_Ruby<IntVar>().convert(literal).ToBoolVar());
|
|
113
|
+
} else if (literal.is_a(rb_cArray)) {
|
|
114
|
+
// TODO support IntVarSpan
|
|
115
|
+
return self.OnlyEnforceIf(Rice::detail::From_Ruby<std::vector<BoolVar>>().convert(literal));
|
|
116
|
+
} else {
|
|
117
|
+
return self.OnlyEnforceIf(Rice::detail::From_Ruby<BoolVar>().convert(literal));
|
|
118
|
+
}
|
|
119
|
+
});
|
|
162
120
|
|
|
163
|
-
Rice::define_class_under<BoolVar>(m, "BoolVar")
|
|
121
|
+
rb_cBoolVar = Rice::define_class_under<BoolVar>(m, "BoolVar")
|
|
164
122
|
.define_method("name", &BoolVar::Name)
|
|
165
123
|
.define_method("index", &BoolVar::index)
|
|
166
124
|
.define_method("not", &BoolVar::Not)
|
|
167
125
|
.define_method(
|
|
168
126
|
"inspect",
|
|
169
|
-
|
|
127
|
+
[](BoolVar& self) {
|
|
170
128
|
String name(self.Name());
|
|
171
129
|
return "#<ORTools::BoolVar @name=" + name.inspect().str() + ">";
|
|
172
130
|
});
|
|
@@ -174,7 +132,7 @@ void init_constraint(Rice::Module& m) {
|
|
|
174
132
|
Rice::define_class_under<SatParameters>(m, "SatParameters")
|
|
175
133
|
.define_constructor(Rice::Constructor<SatParameters>())
|
|
176
134
|
.define_method("max_time_in_seconds=",
|
|
177
|
-
|
|
135
|
+
[](SatParameters& self, double value) {
|
|
178
136
|
self.set_max_time_in_seconds(value);
|
|
179
137
|
});
|
|
180
138
|
|
|
@@ -182,178 +140,245 @@ void init_constraint(Rice::Module& m) {
|
|
|
182
140
|
.define_constructor(Rice::Constructor<CpModelBuilder>())
|
|
183
141
|
.define_method(
|
|
184
142
|
"new_int_var",
|
|
185
|
-
|
|
143
|
+
[](CpModelBuilder& self, int64_t start, int64_t end, const std::string& name) {
|
|
186
144
|
const operations_research::Domain domain(start, end);
|
|
187
145
|
return self.NewIntVar(domain).WithName(name);
|
|
188
146
|
})
|
|
189
147
|
.define_method(
|
|
190
148
|
"new_bool_var",
|
|
191
|
-
|
|
149
|
+
[](CpModelBuilder& self, const std::string& name) {
|
|
192
150
|
return self.NewBoolVar().WithName(name);
|
|
193
151
|
})
|
|
194
152
|
.define_method(
|
|
195
153
|
"new_constant",
|
|
196
|
-
|
|
154
|
+
[](CpModelBuilder& self, int64_t value) {
|
|
197
155
|
return self.NewConstant(value);
|
|
198
156
|
})
|
|
199
157
|
.define_method(
|
|
200
158
|
"true_var",
|
|
201
|
-
|
|
159
|
+
[](CpModelBuilder& self) {
|
|
202
160
|
return self.TrueVar();
|
|
203
161
|
})
|
|
204
162
|
.define_method(
|
|
205
163
|
"false_var",
|
|
206
|
-
|
|
164
|
+
[](CpModelBuilder& self) {
|
|
207
165
|
return self.FalseVar();
|
|
208
166
|
})
|
|
209
167
|
.define_method(
|
|
210
168
|
"new_interval_var",
|
|
211
|
-
|
|
169
|
+
[](CpModelBuilder& self, IntVar start, IntVar size, IntVar end, const std::string& name) {
|
|
212
170
|
return self.NewIntervalVar(start, size, end).WithName(name);
|
|
213
171
|
})
|
|
214
172
|
.define_method(
|
|
215
173
|
"new_optional_interval_var",
|
|
216
|
-
|
|
174
|
+
[](CpModelBuilder& self, IntVar start, IntVar size, IntVar end, BoolVar presence, const std::string& name) {
|
|
217
175
|
return self.NewOptionalIntervalVar(start, size, end, presence).WithName(name);
|
|
218
176
|
})
|
|
219
177
|
.define_method(
|
|
220
178
|
"add_bool_or",
|
|
221
|
-
|
|
222
|
-
self.AddBoolOr(literals);
|
|
179
|
+
[](CpModelBuilder& self, std::vector<BoolVar> literals) {
|
|
180
|
+
return self.AddBoolOr(literals);
|
|
223
181
|
})
|
|
224
182
|
.define_method(
|
|
225
183
|
"add_bool_and",
|
|
226
|
-
|
|
227
|
-
self.AddBoolAnd(literals);
|
|
184
|
+
[](CpModelBuilder& self, std::vector<BoolVar> literals) {
|
|
185
|
+
return self.AddBoolAnd(literals);
|
|
228
186
|
})
|
|
229
187
|
.define_method(
|
|
230
188
|
"add_bool_xor",
|
|
231
|
-
|
|
232
|
-
self.AddBoolXor(literals);
|
|
189
|
+
[](CpModelBuilder& self, std::vector<BoolVar> literals) {
|
|
190
|
+
return self.AddBoolXor(literals);
|
|
233
191
|
})
|
|
234
192
|
.define_method(
|
|
235
193
|
"add_implication",
|
|
236
|
-
|
|
237
|
-
self.AddImplication(a, b);
|
|
194
|
+
[](CpModelBuilder& self, BoolVar a, BoolVar b) {
|
|
195
|
+
return self.AddImplication(a, b);
|
|
238
196
|
})
|
|
239
197
|
.define_method(
|
|
240
198
|
"add_equality",
|
|
241
|
-
|
|
242
|
-
self.AddEquality(x, y);
|
|
199
|
+
[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
|
|
200
|
+
return self.AddEquality(x, y);
|
|
243
201
|
})
|
|
244
202
|
.define_method(
|
|
245
203
|
"add_greater_or_equal",
|
|
246
|
-
|
|
247
|
-
self.AddGreaterOrEqual(x, y);
|
|
204
|
+
[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
|
|
205
|
+
return self.AddGreaterOrEqual(x, y);
|
|
248
206
|
})
|
|
249
207
|
.define_method(
|
|
250
208
|
"add_greater_than",
|
|
251
|
-
|
|
252
|
-
self.AddGreaterThan(x, y);
|
|
209
|
+
[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
|
|
210
|
+
return self.AddGreaterThan(x, y);
|
|
253
211
|
})
|
|
254
212
|
.define_method(
|
|
255
213
|
"add_less_or_equal",
|
|
256
|
-
|
|
257
|
-
self.AddLessOrEqual(x, y);
|
|
214
|
+
[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
|
|
215
|
+
return self.AddLessOrEqual(x, y);
|
|
258
216
|
})
|
|
259
217
|
.define_method(
|
|
260
218
|
"add_less_than",
|
|
261
|
-
|
|
262
|
-
self.AddLessThan(x, y);
|
|
219
|
+
[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
|
|
220
|
+
return self.AddLessThan(x, y);
|
|
263
221
|
})
|
|
264
222
|
// TODO add domain
|
|
265
223
|
// .define_method(
|
|
266
224
|
// "add_linear_constraint",
|
|
267
|
-
//
|
|
268
|
-
// self.AddLinearConstraint(expr, domain);
|
|
225
|
+
// [](CpModelBuilder& self, LinearExpr expr, Domain domain) {
|
|
226
|
+
// return self.AddLinearConstraint(expr, domain);
|
|
269
227
|
// })
|
|
270
228
|
.define_method(
|
|
271
229
|
"add_not_equal",
|
|
272
|
-
|
|
273
|
-
self.AddNotEqual(x, y);
|
|
230
|
+
[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
|
|
231
|
+
return self.AddNotEqual(x, y);
|
|
274
232
|
})
|
|
275
233
|
.define_method(
|
|
276
234
|
"add_all_different",
|
|
277
|
-
|
|
278
|
-
self.AddAllDifferent(vars);
|
|
235
|
+
[](CpModelBuilder& self, std::vector<IntVar> vars) {
|
|
236
|
+
return self.AddAllDifferent(vars);
|
|
279
237
|
})
|
|
280
238
|
.define_method(
|
|
281
239
|
"add_inverse_constraint",
|
|
282
|
-
|
|
283
|
-
self.AddInverseConstraint(variables, inverse_variables);
|
|
240
|
+
[](CpModelBuilder& self, std::vector<IntVar> variables, std::vector<IntVar> inverse_variables) {
|
|
241
|
+
return self.AddInverseConstraint(variables, inverse_variables);
|
|
284
242
|
})
|
|
285
243
|
.define_method(
|
|
286
244
|
"add_min_equality",
|
|
287
|
-
|
|
288
|
-
self.AddMinEquality(target, vars);
|
|
245
|
+
[](CpModelBuilder& self, IntVar target, std::vector<IntVar> vars) {
|
|
246
|
+
return self.AddMinEquality(target, vars);
|
|
289
247
|
})
|
|
290
248
|
.define_method(
|
|
291
249
|
"add_lin_min_equality",
|
|
292
|
-
|
|
293
|
-
self.AddLinMinEquality(target, exprs);
|
|
250
|
+
[](CpModelBuilder& self, LinearExpr target, std::vector<LinearExpr> exprs) {
|
|
251
|
+
return self.AddLinMinEquality(target, exprs);
|
|
294
252
|
})
|
|
295
253
|
.define_method(
|
|
296
254
|
"add_max_equality",
|
|
297
|
-
|
|
298
|
-
self.AddMaxEquality(target, vars);
|
|
255
|
+
[](CpModelBuilder& self, IntVar target, std::vector<IntVar> vars) {
|
|
256
|
+
return self.AddMaxEquality(target, vars);
|
|
299
257
|
})
|
|
300
258
|
.define_method(
|
|
301
259
|
"add_lin_max_equality",
|
|
302
|
-
|
|
303
|
-
self.AddLinMaxEquality(target, exprs);
|
|
260
|
+
[](CpModelBuilder& self, LinearExpr target, std::vector<LinearExpr> exprs) {
|
|
261
|
+
return self.AddLinMaxEquality(target, exprs);
|
|
304
262
|
})
|
|
305
263
|
.define_method(
|
|
306
264
|
"add_division_equality",
|
|
307
|
-
|
|
308
|
-
self.AddDivisionEquality(target, numerator, denominator);
|
|
265
|
+
[](CpModelBuilder& self, IntVar target, IntVar numerator, IntVar denominator) {
|
|
266
|
+
return self.AddDivisionEquality(target, numerator, denominator);
|
|
309
267
|
})
|
|
310
268
|
.define_method(
|
|
311
269
|
"add_abs_equality",
|
|
312
|
-
|
|
313
|
-
self.AddAbsEquality(target, var);
|
|
270
|
+
[](CpModelBuilder& self, IntVar target, IntVar var) {
|
|
271
|
+
return self.AddAbsEquality(target, var);
|
|
314
272
|
})
|
|
315
273
|
.define_method(
|
|
316
274
|
"add_modulo_equality",
|
|
317
|
-
|
|
318
|
-
self.AddModuloEquality(target, var, mod);
|
|
275
|
+
[](CpModelBuilder& self, IntVar target, IntVar var, IntVar mod) {
|
|
276
|
+
return self.AddModuloEquality(target, var, mod);
|
|
319
277
|
})
|
|
320
278
|
.define_method(
|
|
321
279
|
"add_product_equality",
|
|
322
|
-
|
|
323
|
-
self.AddProductEquality(target, vars);
|
|
280
|
+
[](CpModelBuilder& self, IntVar target, std::vector<IntVar> vars) {
|
|
281
|
+
return self.AddProductEquality(target, vars);
|
|
324
282
|
})
|
|
325
283
|
.define_method(
|
|
326
284
|
"add_no_overlap",
|
|
327
|
-
|
|
328
|
-
self.AddNoOverlap(vars);
|
|
285
|
+
[](CpModelBuilder& self, std::vector<IntervalVar> vars) {
|
|
286
|
+
return self.AddNoOverlap(vars);
|
|
329
287
|
})
|
|
330
288
|
.define_method(
|
|
331
289
|
"maximize",
|
|
332
|
-
|
|
290
|
+
[](CpModelBuilder& self, LinearExpr expr) {
|
|
333
291
|
self.Maximize(expr);
|
|
334
292
|
})
|
|
335
293
|
.define_method(
|
|
336
294
|
"minimize",
|
|
337
|
-
|
|
295
|
+
[](CpModelBuilder& self, LinearExpr expr) {
|
|
338
296
|
self.Minimize(expr);
|
|
339
297
|
})
|
|
340
298
|
.define_method(
|
|
341
299
|
"scale_objective_by",
|
|
342
|
-
|
|
300
|
+
[](CpModelBuilder& self, double scaling) {
|
|
343
301
|
self.ScaleObjectiveBy(scaling);
|
|
344
302
|
})
|
|
303
|
+
.define_method(
|
|
304
|
+
"add_hint",
|
|
305
|
+
[](CpModelBuilder& self, IntVar var, int64_t value) {
|
|
306
|
+
self.AddHint(var, value);
|
|
307
|
+
})
|
|
308
|
+
.define_method(
|
|
309
|
+
"clear_hints",
|
|
310
|
+
[](CpModelBuilder& self) {
|
|
311
|
+
self.ClearHints();
|
|
312
|
+
})
|
|
313
|
+
.define_method(
|
|
314
|
+
"add_assumption",
|
|
315
|
+
[](CpModelBuilder& self, BoolVar lit) {
|
|
316
|
+
self.AddAssumption(lit);
|
|
317
|
+
})
|
|
318
|
+
.define_method(
|
|
319
|
+
"add_assumptions",
|
|
320
|
+
[](CpModelBuilder& self, std::vector<BoolVar> literals) {
|
|
321
|
+
self.AddAssumptions(literals);
|
|
322
|
+
})
|
|
323
|
+
.define_method(
|
|
324
|
+
"clear_assumptions",
|
|
325
|
+
[](CpModelBuilder& self) {
|
|
326
|
+
self.ClearAssumptions();
|
|
327
|
+
})
|
|
345
328
|
.define_method(
|
|
346
329
|
"to_s",
|
|
347
|
-
|
|
330
|
+
[](CpModelBuilder& self) {
|
|
348
331
|
std::string proto_string;
|
|
349
332
|
google::protobuf::TextFormat::PrintToString(self.Proto(), &proto_string);
|
|
350
333
|
return proto_string;
|
|
351
334
|
});
|
|
352
335
|
|
|
336
|
+
Rice::define_class_under<CpSolverResponse>(m, "CpSolverResponse")
|
|
337
|
+
.define_method("objective_value", &CpSolverResponse::objective_value)
|
|
338
|
+
.define_method("num_conflicts", &CpSolverResponse::num_conflicts)
|
|
339
|
+
.define_method("num_branches", &CpSolverResponse::num_branches)
|
|
340
|
+
.define_method("wall_time", &CpSolverResponse::wall_time)
|
|
341
|
+
.define_method(
|
|
342
|
+
"solution_integer_value",
|
|
343
|
+
[](CpSolverResponse& self, IntVar& x) {
|
|
344
|
+
LinearExpr expr(x);
|
|
345
|
+
return SolutionIntegerValue(self, expr);
|
|
346
|
+
})
|
|
347
|
+
.define_method("solution_boolean_value", &SolutionBooleanValue)
|
|
348
|
+
.define_method(
|
|
349
|
+
"status",
|
|
350
|
+
[](CpSolverResponse& self) {
|
|
351
|
+
auto status = self.status();
|
|
352
|
+
|
|
353
|
+
if (status == CpSolverStatus::OPTIMAL) {
|
|
354
|
+
return Symbol("optimal");
|
|
355
|
+
} else if (status == CpSolverStatus::FEASIBLE) {
|
|
356
|
+
return Symbol("feasible");
|
|
357
|
+
} else if (status == CpSolverStatus::INFEASIBLE) {
|
|
358
|
+
return Symbol("infeasible");
|
|
359
|
+
} else if (status == CpSolverStatus::MODEL_INVALID) {
|
|
360
|
+
return Symbol("model_invalid");
|
|
361
|
+
} else if (status == CpSolverStatus::UNKNOWN) {
|
|
362
|
+
return Symbol("unknown");
|
|
363
|
+
} else {
|
|
364
|
+
throw std::runtime_error("Unknown solver status");
|
|
365
|
+
}
|
|
366
|
+
})
|
|
367
|
+
.define_method(
|
|
368
|
+
"sufficient_assumptions_for_infeasibility",
|
|
369
|
+
[](CpSolverResponse& self) {
|
|
370
|
+
auto a = Array();
|
|
371
|
+
auto assumptions = self.sufficient_assumptions_for_infeasibility();
|
|
372
|
+
for (const auto& v : assumptions) {
|
|
373
|
+
a.push(v);
|
|
374
|
+
}
|
|
375
|
+
return a;
|
|
376
|
+
});
|
|
377
|
+
|
|
353
378
|
Rice::define_class_under(m, "CpSolver")
|
|
354
379
|
.define_method(
|
|
355
380
|
"_solve_with_observer",
|
|
356
|
-
|
|
381
|
+
[](Object self, CpModelBuilder& model, SatParameters& parameters, Object callback, bool all_solutions) {
|
|
357
382
|
Model m;
|
|
358
383
|
|
|
359
384
|
if (all_solutions) {
|
|
@@ -373,51 +398,19 @@ void init_constraint(Rice::Module& m) {
|
|
|
373
398
|
})
|
|
374
399
|
.define_method(
|
|
375
400
|
"_solve",
|
|
376
|
-
|
|
401
|
+
[](Object self, CpModelBuilder& model, SatParameters& parameters) {
|
|
377
402
|
Model m;
|
|
378
403
|
m.Add(NewSatParameters(parameters));
|
|
379
404
|
return SolveCpModel(model.Build(), &m);
|
|
380
405
|
})
|
|
381
406
|
.define_method(
|
|
382
407
|
"_solution_integer_value",
|
|
383
|
-
|
|
408
|
+
[](Object self, CpSolverResponse& response, IntVar& x) {
|
|
384
409
|
return SolutionIntegerValue(response, x);
|
|
385
410
|
})
|
|
386
411
|
.define_method(
|
|
387
412
|
"_solution_boolean_value",
|
|
388
|
-
|
|
413
|
+
[](Object self, CpSolverResponse& response, BoolVar& x) {
|
|
389
414
|
return SolutionBooleanValue(response, x);
|
|
390
415
|
});
|
|
391
|
-
|
|
392
|
-
Rice::define_class_under<CpSolverResponse>(m, "CpSolverResponse")
|
|
393
|
-
.define_method("objective_value", &CpSolverResponse::objective_value)
|
|
394
|
-
.define_method("num_conflicts", &CpSolverResponse::num_conflicts)
|
|
395
|
-
.define_method("num_branches", &CpSolverResponse::num_branches)
|
|
396
|
-
.define_method("wall_time", &CpSolverResponse::wall_time)
|
|
397
|
-
.define_method(
|
|
398
|
-
"solution_integer_value",
|
|
399
|
-
*[](CpSolverResponse& self, IntVar& x) {
|
|
400
|
-
LinearExpr expr(x);
|
|
401
|
-
return SolutionIntegerValue(self, expr);
|
|
402
|
-
})
|
|
403
|
-
.define_method("solution_boolean_value", &SolutionBooleanValue)
|
|
404
|
-
.define_method(
|
|
405
|
-
"status",
|
|
406
|
-
*[](CpSolverResponse& self) {
|
|
407
|
-
auto status = self.status();
|
|
408
|
-
|
|
409
|
-
if (status == CpSolverStatus::OPTIMAL) {
|
|
410
|
-
return Symbol("optimal");
|
|
411
|
-
} else if (status == CpSolverStatus::FEASIBLE) {
|
|
412
|
-
return Symbol("feasible");
|
|
413
|
-
} else if (status == CpSolverStatus::INFEASIBLE) {
|
|
414
|
-
return Symbol("infeasible");
|
|
415
|
-
} else if (status == CpSolverStatus::MODEL_INVALID) {
|
|
416
|
-
return Symbol("model_invalid");
|
|
417
|
-
} else if (status == CpSolverStatus::UNKNOWN) {
|
|
418
|
-
return Symbol("unknown");
|
|
419
|
-
} else {
|
|
420
|
-
throw std::runtime_error("Unknown solver status");
|
|
421
|
-
}
|
|
422
|
-
});
|
|
423
416
|
}
|