or-tools 0.5.0 → 0.5.4
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 +19 -0
- data/README.md +1 -1
- data/ext/or-tools/assignment.cpp +2 -5
- data/ext/or-tools/bin_packing.cpp +26 -33
- data/ext/or-tools/constraint.cpp +149 -201
- 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 +121 -145
- data/ext/or-tools/vendor.rb +16 -13
- data/lib/or_tools/cp_solver.rb +12 -6
- data/lib/or_tools/seating.rb +1 -1
- data/lib/or_tools/version.rb +1 -1
- metadata +6 -5
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;
|
@@ -28,130 +26,75 @@ using Rice::Symbol;
|
|
28
26
|
Class rb_cBoolVar;
|
29
27
|
Class rb_cSatIntVar;
|
30
28
|
|
31
|
-
|
32
|
-
inline
|
33
|
-
LinearExpr from_ruby<LinearExpr>(Object x)
|
29
|
+
namespace Rice::detail
|
34
30
|
{
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
for (auto const& var: vars) {
|
42
|
-
auto cvar = (Array) var;
|
43
|
-
Object o = cvar[0];
|
44
|
-
if (o.is_a(rb_cBoolVar)) {
|
45
|
-
expr.AddTerm(from_ruby<BoolVar>(cvar[0]), from_ruby<int64_t>(cvar[1]));
|
46
|
-
} else if (o.is_a(rb_cInteger)) {
|
47
|
-
expr.AddConstant(from_ruby<int64_t>(cvar[0]) * from_ruby<int64_t>(cvar[1]));
|
48
|
-
} else {
|
49
|
-
expr.AddTerm(from_ruby<IntVar>(cvar[0]), from_ruby<int64_t>(cvar[1]));
|
50
|
-
}
|
31
|
+
template<>
|
32
|
+
struct Type<LinearExpr>
|
33
|
+
{
|
34
|
+
static bool verify()
|
35
|
+
{
|
36
|
+
return true;
|
51
37
|
}
|
52
|
-
}
|
53
|
-
expr = from_ruby<BoolVar>(x);
|
54
|
-
} else {
|
55
|
-
expr = from_ruby<IntVar>(x);
|
56
|
-
}
|
38
|
+
};
|
57
39
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
// need a wrapper class since absl::Span doesn't own
|
62
|
-
class IntVarSpan {
|
63
|
-
std::vector<IntVar> vec;
|
40
|
+
template<>
|
41
|
+
class From_Ruby<LinearExpr>
|
42
|
+
{
|
64
43
|
public:
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
vec.push_back(from_ruby<IntVar>(a[i]));
|
70
|
-
}
|
71
|
-
}
|
72
|
-
operator absl::Span<const IntVar>() {
|
73
|
-
return absl::Span<const IntVar>(vec);
|
74
|
-
}
|
75
|
-
};
|
44
|
+
LinearExpr convert(VALUE v)
|
45
|
+
{
|
46
|
+
Object x(v);
|
47
|
+
LinearExpr expr;
|
76
48
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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());
|
83
58
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
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
|
+
}
|
93
73
|
}
|
94
|
-
}
|
95
|
-
operator absl::Span<const IntervalVar>() {
|
96
|
-
return absl::Span<const IntervalVar>(vec);
|
97
|
-
}
|
98
|
-
};
|
99
74
|
|
100
|
-
|
101
|
-
inline
|
102
|
-
IntervalVarSpan from_ruby<IntervalVarSpan>(Object x)
|
103
|
-
{
|
104
|
-
return IntervalVarSpan(x);
|
105
|
-
}
|
106
|
-
|
107
|
-
// need a wrapper class since absl::Span doesn't own
|
108
|
-
class LinearExprSpan {
|
109
|
-
std::vector<LinearExpr> vec;
|
110
|
-
public:
|
111
|
-
LinearExprSpan(Object x) {
|
112
|
-
Array a = Array(x);
|
113
|
-
vec.reserve(a.size());
|
114
|
-
for (std::size_t i = 0; i < a.size(); ++i) {
|
115
|
-
vec.push_back(from_ruby<LinearExpr>(a[i]));
|
116
|
-
}
|
117
|
-
}
|
118
|
-
operator absl::Span<const LinearExpr>() {
|
119
|
-
return absl::Span<const LinearExpr>(vec);
|
75
|
+
return expr;
|
120
76
|
}
|
121
|
-
};
|
77
|
+
};
|
122
78
|
|
123
|
-
template<>
|
124
|
-
|
125
|
-
|
126
|
-
{
|
127
|
-
return LinearExprSpan(x);
|
128
|
-
}
|
129
|
-
|
130
|
-
// need a wrapper class since absl::Span doesn't own
|
131
|
-
class BoolVarSpan {
|
132
|
-
std::vector<BoolVar> vec;
|
79
|
+
template<>
|
80
|
+
class From_Ruby<std::vector<BoolVar>>
|
81
|
+
{
|
133
82
|
public:
|
134
|
-
|
135
|
-
|
83
|
+
std::vector<BoolVar> convert(VALUE v)
|
84
|
+
{
|
85
|
+
auto a = Array(v);
|
86
|
+
std::vector<BoolVar> vec;
|
136
87
|
vec.reserve(a.size());
|
137
|
-
for (
|
138
|
-
if (
|
139
|
-
vec.push_back(
|
88
|
+
for (const Object v : a) {
|
89
|
+
if (v.is_a(rb_cSatIntVar)) {
|
90
|
+
vec.push_back(From_Ruby<IntVar>().convert(v.value()).ToBoolVar());
|
140
91
|
} else {
|
141
|
-
vec.push_back(
|
92
|
+
vec.push_back(From_Ruby<BoolVar>().convert(v.value()));
|
142
93
|
}
|
143
94
|
}
|
95
|
+
return vec;
|
144
96
|
}
|
145
|
-
|
146
|
-
return absl::Span<const BoolVar>(vec);
|
147
|
-
}
|
148
|
-
};
|
149
|
-
|
150
|
-
template<>
|
151
|
-
inline
|
152
|
-
BoolVarSpan from_ruby<BoolVarSpan>(Object x)
|
153
|
-
{
|
154
|
-
return BoolVarSpan(x);
|
97
|
+
};
|
155
98
|
}
|
156
99
|
|
157
100
|
void init_constraint(Rice::Module& m) {
|
@@ -164,14 +107,14 @@ void init_constraint(Rice::Module& m) {
|
|
164
107
|
Rice::define_class_under<Constraint>(m, "SatConstraint")
|
165
108
|
.define_method(
|
166
109
|
"only_enforce_if",
|
167
|
-
|
110
|
+
[](Constraint& self, Object literal) {
|
168
111
|
if (literal.is_a(rb_cSatIntVar)) {
|
169
|
-
return self.OnlyEnforceIf(
|
112
|
+
return self.OnlyEnforceIf(Rice::detail::From_Ruby<IntVar>().convert(literal).ToBoolVar());
|
170
113
|
} else if (literal.is_a(rb_cArray)) {
|
171
114
|
// TODO support IntVarSpan
|
172
|
-
return self.OnlyEnforceIf(
|
115
|
+
return self.OnlyEnforceIf(Rice::detail::From_Ruby<std::vector<BoolVar>>().convert(literal));
|
173
116
|
} else {
|
174
|
-
return self.OnlyEnforceIf(
|
117
|
+
return self.OnlyEnforceIf(Rice::detail::From_Ruby<BoolVar>().convert(literal));
|
175
118
|
}
|
176
119
|
});
|
177
120
|
|
@@ -181,254 +124,226 @@ void init_constraint(Rice::Module& m) {
|
|
181
124
|
.define_method("not", &BoolVar::Not)
|
182
125
|
.define_method(
|
183
126
|
"inspect",
|
184
|
-
|
127
|
+
[](BoolVar& self) {
|
185
128
|
String name(self.Name());
|
186
129
|
return "#<ORTools::BoolVar @name=" + name.inspect().str() + ">";
|
187
130
|
});
|
188
131
|
|
189
132
|
Rice::define_class_under<SatParameters>(m, "SatParameters")
|
190
133
|
.define_constructor(Rice::Constructor<SatParameters>())
|
191
|
-
.define_method(
|
192
|
-
|
193
|
-
self
|
194
|
-
|
134
|
+
.define_method(
|
135
|
+
"max_time_in_seconds=",
|
136
|
+
[](SatParameters& self, double value) {
|
137
|
+
self.set_max_time_in_seconds(value);
|
138
|
+
})
|
139
|
+
.define_method(
|
140
|
+
"enumerate_all_solutions=",
|
141
|
+
[](SatParameters& self, bool value) {
|
142
|
+
self.set_enumerate_all_solutions(value);
|
143
|
+
})
|
144
|
+
.define_method(
|
145
|
+
"enumerate_all_solutions",
|
146
|
+
[](SatParameters& self) {
|
147
|
+
return self.enumerate_all_solutions();
|
148
|
+
});
|
195
149
|
|
196
150
|
Rice::define_class_under<CpModelBuilder>(m, "CpModel")
|
197
151
|
.define_constructor(Rice::Constructor<CpModelBuilder>())
|
198
152
|
.define_method(
|
199
153
|
"new_int_var",
|
200
|
-
|
154
|
+
[](CpModelBuilder& self, int64_t start, int64_t end, const std::string& name) {
|
201
155
|
const operations_research::Domain domain(start, end);
|
202
156
|
return self.NewIntVar(domain).WithName(name);
|
203
157
|
})
|
204
158
|
.define_method(
|
205
159
|
"new_bool_var",
|
206
|
-
|
160
|
+
[](CpModelBuilder& self, const std::string& name) {
|
207
161
|
return self.NewBoolVar().WithName(name);
|
208
162
|
})
|
209
163
|
.define_method(
|
210
164
|
"new_constant",
|
211
|
-
|
165
|
+
[](CpModelBuilder& self, int64_t value) {
|
212
166
|
return self.NewConstant(value);
|
213
167
|
})
|
214
168
|
.define_method(
|
215
169
|
"true_var",
|
216
|
-
|
170
|
+
[](CpModelBuilder& self) {
|
217
171
|
return self.TrueVar();
|
218
172
|
})
|
219
173
|
.define_method(
|
220
174
|
"false_var",
|
221
|
-
|
175
|
+
[](CpModelBuilder& self) {
|
222
176
|
return self.FalseVar();
|
223
177
|
})
|
224
178
|
.define_method(
|
225
179
|
"new_interval_var",
|
226
|
-
|
180
|
+
[](CpModelBuilder& self, IntVar start, IntVar size, IntVar end, const std::string& name) {
|
227
181
|
return self.NewIntervalVar(start, size, end).WithName(name);
|
228
182
|
})
|
229
183
|
.define_method(
|
230
184
|
"new_optional_interval_var",
|
231
|
-
|
185
|
+
[](CpModelBuilder& self, IntVar start, IntVar size, IntVar end, BoolVar presence, const std::string& name) {
|
232
186
|
return self.NewOptionalIntervalVar(start, size, end, presence).WithName(name);
|
233
187
|
})
|
234
188
|
.define_method(
|
235
189
|
"add_bool_or",
|
236
|
-
|
190
|
+
[](CpModelBuilder& self, std::vector<BoolVar> literals) {
|
237
191
|
return self.AddBoolOr(literals);
|
238
192
|
})
|
239
193
|
.define_method(
|
240
194
|
"add_bool_and",
|
241
|
-
|
195
|
+
[](CpModelBuilder& self, std::vector<BoolVar> literals) {
|
242
196
|
return self.AddBoolAnd(literals);
|
243
197
|
})
|
244
198
|
.define_method(
|
245
199
|
"add_bool_xor",
|
246
|
-
|
200
|
+
[](CpModelBuilder& self, std::vector<BoolVar> literals) {
|
247
201
|
return self.AddBoolXor(literals);
|
248
202
|
})
|
249
203
|
.define_method(
|
250
204
|
"add_implication",
|
251
|
-
|
205
|
+
[](CpModelBuilder& self, BoolVar a, BoolVar b) {
|
252
206
|
return self.AddImplication(a, b);
|
253
207
|
})
|
254
208
|
.define_method(
|
255
209
|
"add_equality",
|
256
|
-
|
210
|
+
[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
|
257
211
|
return self.AddEquality(x, y);
|
258
212
|
})
|
259
213
|
.define_method(
|
260
214
|
"add_greater_or_equal",
|
261
|
-
|
215
|
+
[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
|
262
216
|
return self.AddGreaterOrEqual(x, y);
|
263
217
|
})
|
264
218
|
.define_method(
|
265
219
|
"add_greater_than",
|
266
|
-
|
220
|
+
[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
|
267
221
|
return self.AddGreaterThan(x, y);
|
268
222
|
})
|
269
223
|
.define_method(
|
270
224
|
"add_less_or_equal",
|
271
|
-
|
225
|
+
[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
|
272
226
|
return self.AddLessOrEqual(x, y);
|
273
227
|
})
|
274
228
|
.define_method(
|
275
229
|
"add_less_than",
|
276
|
-
|
230
|
+
[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
|
277
231
|
return self.AddLessThan(x, y);
|
278
232
|
})
|
279
233
|
// TODO add domain
|
280
234
|
// .define_method(
|
281
235
|
// "add_linear_constraint",
|
282
|
-
//
|
236
|
+
// [](CpModelBuilder& self, LinearExpr expr, Domain domain) {
|
283
237
|
// return self.AddLinearConstraint(expr, domain);
|
284
238
|
// })
|
285
239
|
.define_method(
|
286
240
|
"add_not_equal",
|
287
|
-
|
241
|
+
[](CpModelBuilder& self, LinearExpr x, LinearExpr y) {
|
288
242
|
return self.AddNotEqual(x, y);
|
289
243
|
})
|
290
244
|
.define_method(
|
291
245
|
"add_all_different",
|
292
|
-
|
246
|
+
[](CpModelBuilder& self, std::vector<IntVar> vars) {
|
293
247
|
return self.AddAllDifferent(vars);
|
294
248
|
})
|
295
249
|
.define_method(
|
296
250
|
"add_inverse_constraint",
|
297
|
-
|
251
|
+
[](CpModelBuilder& self, std::vector<IntVar> variables, std::vector<IntVar> inverse_variables) {
|
298
252
|
return self.AddInverseConstraint(variables, inverse_variables);
|
299
253
|
})
|
300
254
|
.define_method(
|
301
255
|
"add_min_equality",
|
302
|
-
|
256
|
+
[](CpModelBuilder& self, IntVar target, std::vector<IntVar> vars) {
|
303
257
|
return self.AddMinEquality(target, vars);
|
304
258
|
})
|
305
259
|
.define_method(
|
306
260
|
"add_lin_min_equality",
|
307
|
-
|
261
|
+
[](CpModelBuilder& self, LinearExpr target, std::vector<LinearExpr> exprs) {
|
308
262
|
return self.AddLinMinEquality(target, exprs);
|
309
263
|
})
|
310
264
|
.define_method(
|
311
265
|
"add_max_equality",
|
312
|
-
|
266
|
+
[](CpModelBuilder& self, IntVar target, std::vector<IntVar> vars) {
|
313
267
|
return self.AddMaxEquality(target, vars);
|
314
268
|
})
|
315
269
|
.define_method(
|
316
270
|
"add_lin_max_equality",
|
317
|
-
|
271
|
+
[](CpModelBuilder& self, LinearExpr target, std::vector<LinearExpr> exprs) {
|
318
272
|
return self.AddLinMaxEquality(target, exprs);
|
319
273
|
})
|
320
274
|
.define_method(
|
321
275
|
"add_division_equality",
|
322
|
-
|
276
|
+
[](CpModelBuilder& self, IntVar target, IntVar numerator, IntVar denominator) {
|
323
277
|
return self.AddDivisionEquality(target, numerator, denominator);
|
324
278
|
})
|
325
279
|
.define_method(
|
326
280
|
"add_abs_equality",
|
327
|
-
|
281
|
+
[](CpModelBuilder& self, IntVar target, IntVar var) {
|
328
282
|
return self.AddAbsEquality(target, var);
|
329
283
|
})
|
330
284
|
.define_method(
|
331
285
|
"add_modulo_equality",
|
332
|
-
|
286
|
+
[](CpModelBuilder& self, IntVar target, IntVar var, IntVar mod) {
|
333
287
|
return self.AddModuloEquality(target, var, mod);
|
334
288
|
})
|
335
289
|
.define_method(
|
336
290
|
"add_product_equality",
|
337
|
-
|
291
|
+
[](CpModelBuilder& self, IntVar target, std::vector<IntVar> vars) {
|
338
292
|
return self.AddProductEquality(target, vars);
|
339
293
|
})
|
340
294
|
.define_method(
|
341
295
|
"add_no_overlap",
|
342
|
-
|
296
|
+
[](CpModelBuilder& self, std::vector<IntervalVar> vars) {
|
343
297
|
return self.AddNoOverlap(vars);
|
344
298
|
})
|
345
299
|
.define_method(
|
346
300
|
"maximize",
|
347
|
-
|
301
|
+
[](CpModelBuilder& self, LinearExpr expr) {
|
348
302
|
self.Maximize(expr);
|
349
303
|
})
|
350
304
|
.define_method(
|
351
305
|
"minimize",
|
352
|
-
|
306
|
+
[](CpModelBuilder& self, LinearExpr expr) {
|
353
307
|
self.Minimize(expr);
|
354
308
|
})
|
355
309
|
.define_method(
|
356
310
|
"scale_objective_by",
|
357
|
-
|
311
|
+
[](CpModelBuilder& self, double scaling) {
|
358
312
|
self.ScaleObjectiveBy(scaling);
|
359
313
|
})
|
360
314
|
.define_method(
|
361
315
|
"add_hint",
|
362
|
-
|
316
|
+
[](CpModelBuilder& self, IntVar var, int64_t value) {
|
363
317
|
self.AddHint(var, value);
|
364
318
|
})
|
365
319
|
.define_method(
|
366
320
|
"clear_hints",
|
367
|
-
|
321
|
+
[](CpModelBuilder& self) {
|
368
322
|
self.ClearHints();
|
369
323
|
})
|
370
324
|
.define_method(
|
371
325
|
"add_assumption",
|
372
|
-
|
326
|
+
[](CpModelBuilder& self, BoolVar lit) {
|
373
327
|
self.AddAssumption(lit);
|
374
328
|
})
|
375
329
|
.define_method(
|
376
330
|
"add_assumptions",
|
377
|
-
|
331
|
+
[](CpModelBuilder& self, std::vector<BoolVar> literals) {
|
378
332
|
self.AddAssumptions(literals);
|
379
333
|
})
|
380
334
|
.define_method(
|
381
335
|
"clear_assumptions",
|
382
|
-
|
336
|
+
[](CpModelBuilder& self) {
|
383
337
|
self.ClearAssumptions();
|
384
338
|
})
|
385
339
|
.define_method(
|
386
340
|
"to_s",
|
387
|
-
|
341
|
+
[](CpModelBuilder& self) {
|
388
342
|
std::string proto_string;
|
389
343
|
google::protobuf::TextFormat::PrintToString(self.Proto(), &proto_string);
|
390
344
|
return proto_string;
|
391
345
|
});
|
392
346
|
|
393
|
-
Rice::define_class_under(m, "CpSolver")
|
394
|
-
.define_method(
|
395
|
-
"_solve_with_observer",
|
396
|
-
*[](Object self, CpModelBuilder& model, SatParameters& parameters, Object callback, bool all_solutions) {
|
397
|
-
Model m;
|
398
|
-
|
399
|
-
if (all_solutions) {
|
400
|
-
// set parameters for SearchForAllSolutions
|
401
|
-
parameters.set_enumerate_all_solutions(true);
|
402
|
-
}
|
403
|
-
m.Add(NewSatParameters(parameters));
|
404
|
-
|
405
|
-
m.Add(NewFeasibleSolutionObserver(
|
406
|
-
[callback](const CpSolverResponse& r) {
|
407
|
-
// TODO find a better way to do this
|
408
|
-
callback.call("response=", r);
|
409
|
-
callback.call("on_solution_callback");
|
410
|
-
})
|
411
|
-
);
|
412
|
-
return SolveCpModel(model.Build(), &m);
|
413
|
-
})
|
414
|
-
.define_method(
|
415
|
-
"_solve",
|
416
|
-
*[](Object self, CpModelBuilder& model, SatParameters& parameters) {
|
417
|
-
Model m;
|
418
|
-
m.Add(NewSatParameters(parameters));
|
419
|
-
return SolveCpModel(model.Build(), &m);
|
420
|
-
})
|
421
|
-
.define_method(
|
422
|
-
"_solution_integer_value",
|
423
|
-
*[](Object self, CpSolverResponse& response, IntVar& x) {
|
424
|
-
return SolutionIntegerValue(response, x);
|
425
|
-
})
|
426
|
-
.define_method(
|
427
|
-
"_solution_boolean_value",
|
428
|
-
*[](Object self, CpSolverResponse& response, BoolVar& x) {
|
429
|
-
return SolutionBooleanValue(response, x);
|
430
|
-
});
|
431
|
-
|
432
347
|
Rice::define_class_under<CpSolverResponse>(m, "CpSolverResponse")
|
433
348
|
.define_method("objective_value", &CpSolverResponse::objective_value)
|
434
349
|
.define_method("num_conflicts", &CpSolverResponse::num_conflicts)
|
@@ -436,14 +351,14 @@ void init_constraint(Rice::Module& m) {
|
|
436
351
|
.define_method("wall_time", &CpSolverResponse::wall_time)
|
437
352
|
.define_method(
|
438
353
|
"solution_integer_value",
|
439
|
-
|
354
|
+
[](CpSolverResponse& self, IntVar& x) {
|
440
355
|
LinearExpr expr(x);
|
441
356
|
return SolutionIntegerValue(self, expr);
|
442
357
|
})
|
443
358
|
.define_method("solution_boolean_value", &SolutionBooleanValue)
|
444
359
|
.define_method(
|
445
360
|
"status",
|
446
|
-
|
361
|
+
[](CpSolverResponse& self) {
|
447
362
|
auto status = self.status();
|
448
363
|
|
449
364
|
if (status == CpSolverStatus::OPTIMAL) {
|
@@ -462,12 +377,45 @@ void init_constraint(Rice::Module& m) {
|
|
462
377
|
})
|
463
378
|
.define_method(
|
464
379
|
"sufficient_assumptions_for_infeasibility",
|
465
|
-
|
380
|
+
[](CpSolverResponse& self) {
|
466
381
|
auto a = Array();
|
467
382
|
auto assumptions = self.sufficient_assumptions_for_infeasibility();
|
468
|
-
for (auto
|
383
|
+
for (const auto& v : assumptions) {
|
469
384
|
a.push(v);
|
470
385
|
}
|
471
386
|
return a;
|
472
387
|
});
|
388
|
+
|
389
|
+
Rice::define_class_under(m, "CpSolver")
|
390
|
+
.define_method(
|
391
|
+
"_solve",
|
392
|
+
[](Object self, CpModelBuilder& model, SatParameters& parameters, Object callback) {
|
393
|
+
Model m;
|
394
|
+
|
395
|
+
if (!callback.is_nil()) {
|
396
|
+
// TODO figure out how to use callback with multiple cores
|
397
|
+
parameters.set_num_search_workers(1);
|
398
|
+
|
399
|
+
m.Add(NewFeasibleSolutionObserver(
|
400
|
+
[callback](const CpSolverResponse& r) {
|
401
|
+
// TODO find a better way to do this
|
402
|
+
callback.call("response=", r);
|
403
|
+
callback.call("on_solution_callback");
|
404
|
+
})
|
405
|
+
);
|
406
|
+
}
|
407
|
+
|
408
|
+
m.Add(NewSatParameters(parameters));
|
409
|
+
return SolveCpModel(model.Build(), &m);
|
410
|
+
})
|
411
|
+
.define_method(
|
412
|
+
"_solution_integer_value",
|
413
|
+
[](Object self, CpSolverResponse& response, IntVar& x) {
|
414
|
+
return SolutionIntegerValue(response, x);
|
415
|
+
})
|
416
|
+
.define_method(
|
417
|
+
"_solution_boolean_value",
|
418
|
+
[](Object self, CpSolverResponse& response, BoolVar& x) {
|
419
|
+
return SolutionBooleanValue(response, x);
|
420
|
+
});
|
473
421
|
}
|
data/ext/or-tools/ext.cpp
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#include <ortools/base/version.h>
|
2
2
|
|
3
|
-
#include
|
3
|
+
#include "ext.h"
|
4
4
|
|
5
5
|
void init_assignment(Rice::Module& m);
|
6
6
|
void init_bin_packing(Rice::Module& m);
|
@@ -14,9 +14,9 @@ void Init_ext()
|
|
14
14
|
{
|
15
15
|
auto m = Rice::define_module("ORTools");
|
16
16
|
|
17
|
-
m.
|
17
|
+
m.define_singleton_function(
|
18
18
|
"lib_version",
|
19
|
-
|
19
|
+
[]() {
|
20
20
|
return std::to_string(operations_research::OrToolsMajorVersion()) + "."
|
21
21
|
+ std::to_string(operations_research::OrToolsMinorVersion());
|
22
22
|
});
|
data/ext/or-tools/ext.h
ADDED
data/ext/or-tools/extconf.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
require "mkmf-rice"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
$CXXFLAGS << " -std=c++17 -DUSE_CBC"
|
3
|
+
$CXXFLAGS << " -std=c++17 $(optflags) -DUSE_CBC"
|
6
4
|
|
7
5
|
# or-tools warnings
|
8
6
|
$CXXFLAGS << " -Wno-sign-compare -Wno-shorten-64-to-32 -Wno-ignored-qualifiers"
|