or-tools 0.4.0 → 0.5.1
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 +27 -0
- data/README.md +1 -1
- data/ext/or-tools/assignment.cpp +36 -0
- data/ext/or-tools/bin_packing.cpp +48 -0
- data/ext/or-tools/constraint.cpp +416 -0
- data/ext/or-tools/ext.cpp +19 -1026
- data/ext/or-tools/ext.h +4 -0
- data/ext/or-tools/extconf.rb +1 -3
- data/ext/or-tools/linear.cpp +201 -0
- data/ext/or-tools/network_flows.cpp +103 -0
- data/ext/or-tools/routing.cpp +291 -0
- data/ext/or-tools/vendor.rb +25 -11
- data/lib/or-tools.rb +5 -0
- data/lib/or_tools/cp_model.rb +4 -0
- data/lib/or_tools/cp_solver.rb +4 -0
- data/lib/or_tools/cp_solver_solution_callback.rb +1 -1
- data/lib/or_tools/objective_solution_printer.rb +18 -0
- data/lib/or_tools/sat_int_var.rb +4 -0
- data/lib/or_tools/sat_linear_expr.rb +2 -2
- data/lib/or_tools/seating.rb +1 -1
- data/lib/or_tools/var_array_and_objective_solution_printer.rb +20 -0
- data/lib/or_tools/var_array_solution_printer.rb +19 -0
- data/lib/or_tools/version.rb +1 -1
- metadata +15 -61
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a848cf114ad9ca6d778daf6cb19ff78b3c4015c4b39eb6b6274e61c4175b87d
|
4
|
+
data.tar.gz: bb3c6b79787a0793367ab900b95caf8fa0b242f76fd0c2adc2a434056648e1e9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 571acd73a42c0e3181e256d30c42f8b18d7bcf01ada104a181c7e2b4034358d14409ba1904017c31a4c3c07b15744ac8eeb9422f5d8074c9e2c818bc38bf7ec3
|
7
|
+
data.tar.gz: 762bfc272f728f1b04af4d153591b52798415c2729d4111445779b66c356b9714a4b88eb8ba6546bc43c017184868cf9adcb91df980c105be3a72f2555a8d7f2
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,30 @@
|
|
1
|
+
## 0.5.1 (2021-05-23)
|
2
|
+
|
3
|
+
- Updated to Rice 4
|
4
|
+
|
5
|
+
## 0.5.0 (2021-04-30)
|
6
|
+
|
7
|
+
- Updated OR-Tools to 9.0
|
8
|
+
- Added binary installation for CentOS 7
|
9
|
+
- Added `sufficient_assumptions_for_infeasibility` to `CpSolver`
|
10
|
+
|
11
|
+
## 0.4.3 (2021-03-26)
|
12
|
+
|
13
|
+
- Added `add_assumption`, `add_assumptions`, and `clear_assumptions` to `CpModel`
|
14
|
+
- Added `add_hint` and `clear_hints` to `CpModel`
|
15
|
+
- Added `only_enforce_if` to `SatConstraint`
|
16
|
+
- Fixed installation for Debian
|
17
|
+
|
18
|
+
## 0.4.2 (2021-03-03)
|
19
|
+
|
20
|
+
- Updated OR-Tools to 8.2
|
21
|
+
|
22
|
+
## 0.4.1 (2021-02-23)
|
23
|
+
|
24
|
+
- Added solution printers
|
25
|
+
- Improved `inspect` and `to_s` for `CpModel`
|
26
|
+
- Improved constraint construction
|
27
|
+
|
1
28
|
## 0.4.0 (2021-01-14)
|
2
29
|
|
3
30
|
- Updated OR-Tools to 8.1
|
data/README.md
CHANGED
@@ -267,7 +267,7 @@ Constraint Optimization
|
|
267
267
|
- [Solving an Optimization Problem](#solving-an-optimization-problem)
|
268
268
|
- [Cryptarithmetic](#cryptarithmetic)
|
269
269
|
- [The N-queens Problem](#the-n-queens-problem)
|
270
|
-
- [Setting Solver Limits](#setting-solver-limits)
|
270
|
+
- [Setting Solver Limits](#setting-solver-limits)
|
271
271
|
|
272
272
|
Assignment
|
273
273
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#include <ortools/graph/assignment.h>
|
2
|
+
|
3
|
+
#include "ext.h"
|
4
|
+
|
5
|
+
using operations_research::SimpleLinearSumAssignment;
|
6
|
+
|
7
|
+
using Rice::Symbol;
|
8
|
+
|
9
|
+
void init_assignment(Rice::Module& m) {
|
10
|
+
Rice::define_class_under<SimpleLinearSumAssignment>(m, "LinearSumAssignment")
|
11
|
+
.define_constructor(Rice::Constructor<SimpleLinearSumAssignment>())
|
12
|
+
.define_method("add_arc_with_cost", &SimpleLinearSumAssignment::AddArcWithCost)
|
13
|
+
.define_method("num_nodes", &SimpleLinearSumAssignment::NumNodes)
|
14
|
+
.define_method("num_arcs", &SimpleLinearSumAssignment::NumArcs)
|
15
|
+
.define_method("left_node", &SimpleLinearSumAssignment::LeftNode)
|
16
|
+
.define_method("right_node", &SimpleLinearSumAssignment::RightNode)
|
17
|
+
.define_method("cost", &SimpleLinearSumAssignment::Cost)
|
18
|
+
.define_method("optimal_cost", &SimpleLinearSumAssignment::OptimalCost)
|
19
|
+
.define_method("right_mate", &SimpleLinearSumAssignment::RightMate)
|
20
|
+
.define_method("assignment_cost", &SimpleLinearSumAssignment::AssignmentCost)
|
21
|
+
.define_method(
|
22
|
+
"solve",
|
23
|
+
[](SimpleLinearSumAssignment& self) {
|
24
|
+
auto status = self.Solve();
|
25
|
+
|
26
|
+
if (status == SimpleLinearSumAssignment::Status::OPTIMAL) {
|
27
|
+
return Symbol("optimal");
|
28
|
+
} else if (status == SimpleLinearSumAssignment::Status::INFEASIBLE) {
|
29
|
+
return Symbol("infeasible");
|
30
|
+
} else if (status == SimpleLinearSumAssignment::Status::POSSIBLE_OVERFLOW) {
|
31
|
+
return Symbol("possible_overflow");
|
32
|
+
} else {
|
33
|
+
throw std::runtime_error("Unknown status");
|
34
|
+
}
|
35
|
+
});
|
36
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#include <ortools/algorithms/knapsack_solver.h>
|
2
|
+
|
3
|
+
#include "ext.h"
|
4
|
+
|
5
|
+
using operations_research::KnapsackSolver;
|
6
|
+
|
7
|
+
using Rice::Array;
|
8
|
+
using Rice::Object;
|
9
|
+
using Rice::Symbol;
|
10
|
+
|
11
|
+
namespace Rice::detail
|
12
|
+
{
|
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
|
+
};
|
36
|
+
}
|
37
|
+
|
38
|
+
void init_bin_packing(Rice::Module& m) {
|
39
|
+
Rice::define_class_under<KnapsackSolver>(m, "KnapsackSolver")
|
40
|
+
.define_constructor(Rice::Constructor<KnapsackSolver, KnapsackSolver::SolverType, std::string>())
|
41
|
+
.define_method("_solve", &KnapsackSolver::Solve)
|
42
|
+
.define_method("best_solution_contains?", &KnapsackSolver::BestSolutionContains)
|
43
|
+
.define_method(
|
44
|
+
"init",
|
45
|
+
[](KnapsackSolver& self, std::vector<int64_t> values, std::vector<std::vector<int64_t>> weights, std::vector<int64_t> capacities) {
|
46
|
+
self.Init(values, weights, capacities);
|
47
|
+
});
|
48
|
+
}
|
@@ -0,0 +1,416 @@
|
|
1
|
+
#include <google/protobuf/text_format.h>
|
2
|
+
#include <ortools/sat/cp_model.h>
|
3
|
+
|
4
|
+
#include "ext.h"
|
5
|
+
|
6
|
+
using operations_research::sat::BoolVar;
|
7
|
+
using operations_research::sat::Constraint;
|
8
|
+
using operations_research::sat::CpModelBuilder;
|
9
|
+
using operations_research::sat::CpSolverResponse;
|
10
|
+
using operations_research::sat::CpSolverStatus;
|
11
|
+
using operations_research::sat::LinearExpr;
|
12
|
+
using operations_research::sat::IntVar;
|
13
|
+
using operations_research::sat::IntervalVar;
|
14
|
+
using operations_research::sat::Model;
|
15
|
+
using operations_research::sat::NewFeasibleSolutionObserver;
|
16
|
+
using operations_research::sat::SatParameters;
|
17
|
+
using operations_research::sat::SolutionBooleanValue;
|
18
|
+
using operations_research::sat::SolutionIntegerValue;
|
19
|
+
|
20
|
+
using Rice::Array;
|
21
|
+
using Rice::Class;
|
22
|
+
using Rice::Object;
|
23
|
+
using Rice::String;
|
24
|
+
using Rice::Symbol;
|
25
|
+
|
26
|
+
Class rb_cBoolVar;
|
27
|
+
Class rb_cSatIntVar;
|
28
|
+
|
29
|
+
namespace Rice::detail
|
30
|
+
{
|
31
|
+
template<>
|
32
|
+
struct Type<LinearExpr>
|
33
|
+
{
|
34
|
+
static bool verify()
|
35
|
+
{
|
36
|
+
return true;
|
37
|
+
}
|
38
|
+
};
|
39
|
+
|
40
|
+
template<>
|
41
|
+
class From_Ruby<LinearExpr>
|
42
|
+
{
|
43
|
+
public:
|
44
|
+
LinearExpr convert(VALUE v)
|
45
|
+
{
|
46
|
+
Object x(v);
|
47
|
+
LinearExpr expr;
|
48
|
+
|
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());
|
58
|
+
|
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
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
return expr;
|
76
|
+
}
|
77
|
+
};
|
78
|
+
|
79
|
+
template<>
|
80
|
+
class From_Ruby<std::vector<BoolVar>>
|
81
|
+
{
|
82
|
+
public:
|
83
|
+
std::vector<BoolVar> convert(VALUE v)
|
84
|
+
{
|
85
|
+
auto a = Array(v);
|
86
|
+
std::vector<BoolVar> vec;
|
87
|
+
vec.reserve(a.size());
|
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
|
+
}
|
94
|
+
}
|
95
|
+
return vec;
|
96
|
+
}
|
97
|
+
};
|
98
|
+
}
|
99
|
+
|
100
|
+
void init_constraint(Rice::Module& m) {
|
101
|
+
rb_cSatIntVar = Rice::define_class_under<IntVar>(m, "SatIntVar")
|
102
|
+
.define_method("name", &IntVar::Name);
|
103
|
+
|
104
|
+
Rice::define_class_under<IntervalVar>(m, "SatIntervalVar")
|
105
|
+
.define_method("name", &IntervalVar::Name);
|
106
|
+
|
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
|
+
});
|
120
|
+
|
121
|
+
rb_cBoolVar = Rice::define_class_under<BoolVar>(m, "BoolVar")
|
122
|
+
.define_method("name", &BoolVar::Name)
|
123
|
+
.define_method("index", &BoolVar::index)
|
124
|
+
.define_method("not", &BoolVar::Not)
|
125
|
+
.define_method(
|
126
|
+
"inspect",
|
127
|
+
[](BoolVar& self) {
|
128
|
+
String name(self.Name());
|
129
|
+
return "#<ORTools::BoolVar @name=" + name.inspect().str() + ">";
|
130
|
+
});
|
131
|
+
|
132
|
+
Rice::define_class_under<SatParameters>(m, "SatParameters")
|
133
|
+
.define_constructor(Rice::Constructor<SatParameters>())
|
134
|
+
.define_method("max_time_in_seconds=",
|
135
|
+
[](SatParameters& self, double value) {
|
136
|
+
self.set_max_time_in_seconds(value);
|
137
|
+
});
|
138
|
+
|
139
|
+
Rice::define_class_under<CpModelBuilder>(m, "CpModel")
|
140
|
+
.define_constructor(Rice::Constructor<CpModelBuilder>())
|
141
|
+
.define_method(
|
142
|
+
"new_int_var",
|
143
|
+
[](CpModelBuilder& self, int64_t start, int64_t end, const std::string& name) {
|
144
|
+
const operations_research::Domain domain(start, end);
|
145
|
+
return self.NewIntVar(domain).WithName(name);
|
146
|
+
})
|
147
|
+
.define_method(
|
148
|
+
"new_bool_var",
|
149
|
+
[](CpModelBuilder& self, const std::string& name) {
|
150
|
+
return self.NewBoolVar().WithName(name);
|
151
|
+
})
|
152
|
+
.define_method(
|
153
|
+
"new_constant",
|
154
|
+
[](CpModelBuilder& self, int64_t value) {
|
155
|
+
return self.NewConstant(value);
|
156
|
+
})
|
157
|
+
.define_method(
|
158
|
+
"true_var",
|
159
|
+
[](CpModelBuilder& self) {
|
160
|
+
return self.TrueVar();
|
161
|
+
})
|
162
|
+
.define_method(
|
163
|
+
"false_var",
|
164
|
+
[](CpModelBuilder& self) {
|
165
|
+
return self.FalseVar();
|
166
|
+
})
|
167
|
+
.define_method(
|
168
|
+
"new_interval_var",
|
169
|
+
[](CpModelBuilder& self, IntVar start, IntVar size, IntVar end, const std::string& name) {
|
170
|
+
return self.NewIntervalVar(start, size, end).WithName(name);
|
171
|
+
})
|
172
|
+
.define_method(
|
173
|
+
"new_optional_interval_var",
|
174
|
+
[](CpModelBuilder& self, IntVar start, IntVar size, IntVar end, BoolVar presence, const std::string& name) {
|
175
|
+
return self.NewOptionalIntervalVar(start, size, end, presence).WithName(name);
|
176
|
+
})
|
177
|
+
.define_method(
|
178
|
+
"add_bool_or",
|
179
|
+
[](CpModelBuilder& self, std::vector<BoolVar> literals) {
|
180
|
+
return self.AddBoolOr(literals);
|
181
|
+
})
|
182
|
+
.define_method(
|
183
|
+
"add_bool_and",
|
184
|
+
[](CpModelBuilder& self, std::vector<BoolVar> literals) {
|
185
|
+
return self.AddBoolAnd(literals);
|
186
|
+
})
|
187
|
+
.define_method(
|
188
|
+
"add_bool_xor",
|
189
|
+
[](CpModelBuilder& self, std::vector<BoolVar> literals) {
|
190
|
+
return self.AddBoolXor(literals);
|
191
|
+
})
|
192
|
+
.define_method(
|
193
|
+
"add_implication",
|
194
|
+
[](CpModelBuilder& self, BoolVar a, BoolVar b) {
|
195
|
+
return self.AddImplication(a, b);
|
196
|
+
})
|
197
|
+
.define_method(
|
198
|
+
"add_equality",
|
199
|
+
[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
|
200
|
+
return self.AddEquality(x, y);
|
201
|
+
})
|
202
|
+
.define_method(
|
203
|
+
"add_greater_or_equal",
|
204
|
+
[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
|
205
|
+
return self.AddGreaterOrEqual(x, y);
|
206
|
+
})
|
207
|
+
.define_method(
|
208
|
+
"add_greater_than",
|
209
|
+
[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
|
210
|
+
return self.AddGreaterThan(x, y);
|
211
|
+
})
|
212
|
+
.define_method(
|
213
|
+
"add_less_or_equal",
|
214
|
+
[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
|
215
|
+
return self.AddLessOrEqual(x, y);
|
216
|
+
})
|
217
|
+
.define_method(
|
218
|
+
"add_less_than",
|
219
|
+
[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
|
220
|
+
return self.AddLessThan(x, y);
|
221
|
+
})
|
222
|
+
// TODO add domain
|
223
|
+
// .define_method(
|
224
|
+
// "add_linear_constraint",
|
225
|
+
// [](CpModelBuilder& self, LinearExpr expr, Domain domain) {
|
226
|
+
// return self.AddLinearConstraint(expr, domain);
|
227
|
+
// })
|
228
|
+
.define_method(
|
229
|
+
"add_not_equal",
|
230
|
+
[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
|
231
|
+
return self.AddNotEqual(x, y);
|
232
|
+
})
|
233
|
+
.define_method(
|
234
|
+
"add_all_different",
|
235
|
+
[](CpModelBuilder& self, std::vector<IntVar> vars) {
|
236
|
+
return self.AddAllDifferent(vars);
|
237
|
+
})
|
238
|
+
.define_method(
|
239
|
+
"add_inverse_constraint",
|
240
|
+
[](CpModelBuilder& self, std::vector<IntVar> variables, std::vector<IntVar> inverse_variables) {
|
241
|
+
return self.AddInverseConstraint(variables, inverse_variables);
|
242
|
+
})
|
243
|
+
.define_method(
|
244
|
+
"add_min_equality",
|
245
|
+
[](CpModelBuilder& self, IntVar target, std::vector<IntVar> vars) {
|
246
|
+
return self.AddMinEquality(target, vars);
|
247
|
+
})
|
248
|
+
.define_method(
|
249
|
+
"add_lin_min_equality",
|
250
|
+
[](CpModelBuilder& self, LinearExpr target, std::vector<LinearExpr> exprs) {
|
251
|
+
return self.AddLinMinEquality(target, exprs);
|
252
|
+
})
|
253
|
+
.define_method(
|
254
|
+
"add_max_equality",
|
255
|
+
[](CpModelBuilder& self, IntVar target, std::vector<IntVar> vars) {
|
256
|
+
return self.AddMaxEquality(target, vars);
|
257
|
+
})
|
258
|
+
.define_method(
|
259
|
+
"add_lin_max_equality",
|
260
|
+
[](CpModelBuilder& self, LinearExpr target, std::vector<LinearExpr> exprs) {
|
261
|
+
return self.AddLinMaxEquality(target, exprs);
|
262
|
+
})
|
263
|
+
.define_method(
|
264
|
+
"add_division_equality",
|
265
|
+
[](CpModelBuilder& self, IntVar target, IntVar numerator, IntVar denominator) {
|
266
|
+
return self.AddDivisionEquality(target, numerator, denominator);
|
267
|
+
})
|
268
|
+
.define_method(
|
269
|
+
"add_abs_equality",
|
270
|
+
[](CpModelBuilder& self, IntVar target, IntVar var) {
|
271
|
+
return self.AddAbsEquality(target, var);
|
272
|
+
})
|
273
|
+
.define_method(
|
274
|
+
"add_modulo_equality",
|
275
|
+
[](CpModelBuilder& self, IntVar target, IntVar var, IntVar mod) {
|
276
|
+
return self.AddModuloEquality(target, var, mod);
|
277
|
+
})
|
278
|
+
.define_method(
|
279
|
+
"add_product_equality",
|
280
|
+
[](CpModelBuilder& self, IntVar target, std::vector<IntVar> vars) {
|
281
|
+
return self.AddProductEquality(target, vars);
|
282
|
+
})
|
283
|
+
.define_method(
|
284
|
+
"add_no_overlap",
|
285
|
+
[](CpModelBuilder& self, std::vector<IntervalVar> vars) {
|
286
|
+
return self.AddNoOverlap(vars);
|
287
|
+
})
|
288
|
+
.define_method(
|
289
|
+
"maximize",
|
290
|
+
[](CpModelBuilder& self, LinearExpr expr) {
|
291
|
+
self.Maximize(expr);
|
292
|
+
})
|
293
|
+
.define_method(
|
294
|
+
"minimize",
|
295
|
+
[](CpModelBuilder& self, LinearExpr expr) {
|
296
|
+
self.Minimize(expr);
|
297
|
+
})
|
298
|
+
.define_method(
|
299
|
+
"scale_objective_by",
|
300
|
+
[](CpModelBuilder& self, double scaling) {
|
301
|
+
self.ScaleObjectiveBy(scaling);
|
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
|
+
})
|
328
|
+
.define_method(
|
329
|
+
"to_s",
|
330
|
+
[](CpModelBuilder& self) {
|
331
|
+
std::string proto_string;
|
332
|
+
google::protobuf::TextFormat::PrintToString(self.Proto(), &proto_string);
|
333
|
+
return proto_string;
|
334
|
+
});
|
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
|
+
|
378
|
+
Rice::define_class_under(m, "CpSolver")
|
379
|
+
.define_method(
|
380
|
+
"_solve_with_observer",
|
381
|
+
[](Object self, CpModelBuilder& model, SatParameters& parameters, Object callback, bool all_solutions) {
|
382
|
+
Model m;
|
383
|
+
|
384
|
+
if (all_solutions) {
|
385
|
+
// set parameters for SearchForAllSolutions
|
386
|
+
parameters.set_enumerate_all_solutions(true);
|
387
|
+
}
|
388
|
+
m.Add(NewSatParameters(parameters));
|
389
|
+
|
390
|
+
m.Add(NewFeasibleSolutionObserver(
|
391
|
+
[callback](const CpSolverResponse& r) {
|
392
|
+
// TODO find a better way to do this
|
393
|
+
callback.call("response=", r);
|
394
|
+
callback.call("on_solution_callback");
|
395
|
+
})
|
396
|
+
);
|
397
|
+
return SolveCpModel(model.Build(), &m);
|
398
|
+
})
|
399
|
+
.define_method(
|
400
|
+
"_solve",
|
401
|
+
[](Object self, CpModelBuilder& model, SatParameters& parameters) {
|
402
|
+
Model m;
|
403
|
+
m.Add(NewSatParameters(parameters));
|
404
|
+
return SolveCpModel(model.Build(), &m);
|
405
|
+
})
|
406
|
+
.define_method(
|
407
|
+
"_solution_integer_value",
|
408
|
+
[](Object self, CpSolverResponse& response, IntVar& x) {
|
409
|
+
return SolutionIntegerValue(response, x);
|
410
|
+
})
|
411
|
+
.define_method(
|
412
|
+
"_solution_boolean_value",
|
413
|
+
[](Object self, CpSolverResponse& response, BoolVar& x) {
|
414
|
+
return SolutionBooleanValue(response, x);
|
415
|
+
});
|
416
|
+
}
|