@@ -65,6 +65,7 @@ function test_cpsat_CountDistinct(
65
65
@requires _supports (config, MOI. optimize!)
66
66
y = [MOI. add_constrained_variable (model, MOI. Integer ()) for _ in 1 : 4 ]
67
67
x = first .(y)
68
+ MOI. add_constraint .(model, x, MOI. Interval (T (0 ), T (4 )))
68
69
MOI. add_constraint (model, MOI. VectorOfVariables (x), MOI. CountDistinct (4 ))
69
70
MOI. optimize! (model)
70
71
x_val = round .(Int, MOI. get .(model, MOI. VariablePrimal (), x))
@@ -142,6 +143,7 @@ function test_cpsat_CountAtLeast(
142
143
x, _ = MOI. add_constrained_variable (model, MOI. Integer ())
143
144
y, _ = MOI. add_constrained_variable (model, MOI. Integer ())
144
145
z, _ = MOI. add_constrained_variable (model, MOI. Integer ())
146
+ MOI. add_constraint .(model, [x, y, z], MOI. Interval (T (0 ), T (3 )))
145
147
variables = [x, y, y, z]
146
148
partitions = [2 , 2 ]
147
149
set = Set ([3 ])
@@ -220,3 +222,246 @@ function setup_test(
220
222
)
221
223
return
222
224
end
225
+
226
+ """
227
+ test_cpsat_BinPacking(model::MOI.ModelLike, config::Config)
228
+
229
+ Add a VectorOfVariables-in-BinPacking constraint.
230
+ """
231
+ function test_cpsat_BinPacking (
232
+ model:: MOI.ModelLike ,
233
+ config:: Config{T} ,
234
+ ) where {T}
235
+ @requires MOI. supports_constraint (
236
+ model,
237
+ MOI. VectorOfVariables,
238
+ MOI. BinPacking{T},
239
+ )
240
+ @requires MOI. supports_add_constrained_variable (model, MOI. Integer)
241
+ @requires _supports (config, MOI. optimize!)
242
+ x = [MOI. add_constrained_variable (model, MOI. Integer ())[1 ] for _ in 1 : 2 ]
243
+ MOI. add_constraint .(model, x, MOI. Interval (T (0 ), T (2 )))
244
+ MOI. add_constraint (
245
+ model,
246
+ MOI. VectorOfVariables (x),
247
+ MOI. BinPacking (T (2 ), T[1 , 2 ]),
248
+ )
249
+ MOI. optimize! (model)
250
+ x_val = round .(Int, MOI. get .(model, MOI. VariablePrimal (), x))
251
+ @test 1 * x_val[1 ] + 2 * x_val[2 ] <= T (2 )
252
+ return
253
+ end
254
+
255
+ function setup_test (
256
+ :: typeof (test_cpsat_BinPacking),
257
+ model:: MOIU.MockOptimizer ,
258
+ :: Config{T} ,
259
+ ) where {T}
260
+ MOIU. set_mock_optimize! (
261
+ model,
262
+ (mock:: MOIU.MockOptimizer ) -> MOIU. mock_optimize! (
263
+ mock,
264
+ MOI. OPTIMAL,
265
+ (MOI. FEASIBLE_POINT, T[2 , 0 ]),
266
+ ),
267
+ )
268
+ return
269
+ end
270
+
271
+ """
272
+ test_cpsat_Cumulative(model::MOI.ModelLike, config::Config)
273
+
274
+ Add a VectorOfVariables-in-Cumulative constraint.
275
+ """
276
+ function test_cpsat_Cumulative (
277
+ model:: MOI.ModelLike ,
278
+ config:: Config{T} ,
279
+ ) where {T}
280
+ @requires MOI. supports_constraint (
281
+ model,
282
+ MOI. VectorOfVariables,
283
+ MOI. Cumulative,
284
+ )
285
+ @requires MOI. supports_add_constrained_variable (model, MOI. Integer)
286
+ @requires _supports (config, MOI. optimize!)
287
+ s = [MOI. add_constrained_variable (model, MOI. Integer ())[1 ] for _ in 1 : 3 ]
288
+ MOI. add_constraint .(model, s, MOI. Interval (T (0 ), T (3 )))
289
+ d = [MOI. add_constrained_variable (model, MOI. Integer ())[1 ] for _ in 1 : 3 ]
290
+ MOI. add_constraint .(model, d, MOI. EqualTo (T (2 )))
291
+ r = [MOI. add_constrained_variable (model, MOI. Integer ())[1 ] for _ in 1 : 3 ]
292
+ MOI. add_constraint .(model, r, MOI. EqualTo .(T[3 , 2 , 1 ]))
293
+ b, _ = MOI. add_constrained_variable (model, MOI. Integer ())
294
+ MOI. add_constraint .(model, b, MOI. EqualTo (T (5 )))
295
+ MOI. add_constraint (
296
+ model,
297
+ MOI. VectorOfVariables ([s; d; r; b]),
298
+ MOI. Cumulative (10 ),
299
+ )
300
+ MOI. optimize! (model)
301
+ s_val = round .(Int, MOI. get .(model, MOI. VariablePrimal (), s))
302
+ d_val = round .(Int, MOI. get .(model, MOI. VariablePrimal (), d))
303
+ r_val = round .(Int, MOI. get .(model, MOI. VariablePrimal (), r))
304
+ b_val = round (Int, MOI. get (model, MOI. VariablePrimal (), b))
305
+ times = zeros (1 + maximum (s_val) + maximum (d_val))
306
+ for i in 1 : 3
307
+ for j in 0 : (d_val[i]- 1 )
308
+ t = s_val[i] + j
309
+ times[t+ 1 ] += r_val[i]
310
+ end
311
+ end
312
+ @test all (times .<= b_val)
313
+ return
314
+ end
315
+
316
+ function setup_test (
317
+ :: typeof (test_cpsat_Cumulative),
318
+ model:: MOIU.MockOptimizer ,
319
+ :: Config{T} ,
320
+ ) where {T}
321
+ MOIU. set_mock_optimize! (
322
+ model,
323
+ (mock:: MOIU.MockOptimizer ) -> MOIU. mock_optimize! (
324
+ mock,
325
+ MOI. OPTIMAL,
326
+ (MOI. FEASIBLE_POINT, T[0 , 1 , 2 , 2 , 2 , 2 , 3 , 2 , 1 , 5 ]),
327
+ ),
328
+ )
329
+ return
330
+ end
331
+
332
+ """
333
+ test_cpsat_Table(model::MOI.ModelLike, config::Config)
334
+
335
+ Add a VectorOfVariables-in-Table constraint.
336
+ """
337
+ function test_cpsat_Table (model:: MOI.ModelLike , config:: Config{T} ) where {T}
338
+ @requires MOI. supports_constraint (
339
+ model,
340
+ MOI. VectorOfVariables,
341
+ MOI. Table{T},
342
+ )
343
+ @requires MOI. supports_add_constrained_variable (model, MOI. Integer)
344
+ @requires _supports (config, MOI. optimize!)
345
+ x = [MOI. add_constrained_variable (model, MOI. Integer ())[1 ] for _ in 1 : 3 ]
346
+ table = T[1 1 0 ; 0 1 1 ]
347
+ MOI. add_constraint (model, MOI. VectorOfVariables (x), MOI. Table (table))
348
+ MOI. optimize! (model)
349
+ x_val = round .(Int, MOI. get .(model, MOI. VariablePrimal (), x))
350
+ @test x_val == [1 , 1 , 0 ] || x_val == [0 , 1 , 1 ]
351
+ return
352
+ end
353
+
354
+ function setup_test (
355
+ :: typeof (test_cpsat_Table),
356
+ model:: MOIU.MockOptimizer ,
357
+ :: Config{T} ,
358
+ ) where {T}
359
+ MOIU. set_mock_optimize! (
360
+ model,
361
+ (mock:: MOIU.MockOptimizer ) -> MOIU. mock_optimize! (
362
+ mock,
363
+ MOI. OPTIMAL,
364
+ (MOI. FEASIBLE_POINT, T[1 , 1 , 0 ]),
365
+ ),
366
+ )
367
+ return
368
+ end
369
+
370
+ """
371
+ test_cpsat_Circuit(model::MOI.ModelLike, config::Config)
372
+
373
+ Add a VectorOfVariables-in-Circuit constraint.
374
+ """
375
+ function test_cpsat_Circuit (model:: MOI.ModelLike , config:: Config{T} ) where {T}
376
+ @requires MOI. supports_constraint (model, MOI. VectorOfVariables, MOI. Circuit)
377
+ @requires MOI. supports_add_constrained_variable (model, MOI. Integer)
378
+ @requires _supports (config, MOI. optimize!)
379
+ x = [MOI. add_constrained_variable (model, MOI. Integer ())[1 ] for _ in 1 : 3 ]
380
+ MOI. add_constraint (model, MOI. VectorOfVariables (x), MOI. Circuit (3 ))
381
+ MOI. optimize! (model)
382
+ x_val = round .(Int, MOI. get .(model, MOI. VariablePrimal (), x))
383
+ @test x_val == [3 , 1 , 2 ] || x_val == [2 , 3 , 1 ]
384
+ return
385
+ end
386
+
387
+ function setup_test (
388
+ :: typeof (test_cpsat_Circuit),
389
+ model:: MOIU.MockOptimizer ,
390
+ :: Config{T} ,
391
+ ) where {T}
392
+ MOIU. set_mock_optimize! (
393
+ model,
394
+ (mock:: MOIU.MockOptimizer ) -> MOIU. mock_optimize! (
395
+ mock,
396
+ MOI. OPTIMAL,
397
+ (MOI. FEASIBLE_POINT, T[3 , 1 , 2 ]),
398
+ ),
399
+ )
400
+ return
401
+ end
402
+
403
+ """
404
+ test_cpsat_Path(model::MOI.ModelLike, config::Config)
405
+
406
+ Add a VectorOfVariables-in-Path constraint.
407
+ """
408
+ function test_cpsat_Path (model:: MOI.ModelLike , config:: Config{T} ) where {T}
409
+ @requires MOI. supports_constraint (model, MOI. VectorOfVariables, MOI. Path)
410
+ @requires MOI. supports_add_constrained_variable (model, MOI. Integer)
411
+ @requires _supports (config, MOI. optimize!)
412
+ from = [1 , 1 , 2 , 2 , 3 ]
413
+ to = [2 , 3 , 3 , 4 , 4 ]
414
+ N, E = 4 , 5
415
+ s, _ = MOI. add_constrained_variable (model, MOI. Integer ())
416
+ t, _ = MOI. add_constrained_variable (model, MOI. Integer ())
417
+ ns = MOI. add_variables (model, N)
418
+ MOI. add_constraint .(model, ns, MOI. ZeroOne ())
419
+ es = MOI. add_variables (model, E)
420
+ MOI. add_constraint .(model, es, MOI. ZeroOne ())
421
+ MOI. add_constraint (
422
+ model,
423
+ MOI. VectorOfVariables ([s; t; ns; es]),
424
+ MOI. Path (from, to),
425
+ )
426
+ MOI. optimize! (model)
427
+ s_val = round (Int, MOI. get (model, MOI. VariablePrimal (), s))
428
+ @test 1 <= s_val <= 4
429
+ t_val = round (Int, MOI. get (model, MOI. VariablePrimal (), t))
430
+ @test 1 <= t_val <= 4
431
+ ns_val = round .(Int, MOI. get .(model, MOI. VariablePrimal (), ns))
432
+ es_val = round .(Int, MOI. get .(model, MOI. VariablePrimal (), es))
433
+ outs = Vector{Int}[[1 , 2 ], [3 , 4 ], [5 ], Int[]]
434
+ ins = Vector{Int}[[], [1 ], [2 , 3 ], [4 , 5 ]]
435
+ has_edges = s_val == t_val ? 0 : 1
436
+ # source: must have no incoming and one outgoing (if s != t)
437
+ @test sum (es_val[o] for o in ins[s_val]; init = 0 ) == 0
438
+ @test sum (es_val[o] for o in outs[s_val]; init = 0 ) == has_edges
439
+ # dest: must have no outgoing and one incoming (if s != t)
440
+ @test sum (es_val[o] for o in ins[t_val]; init = 0 ) == has_edges
441
+ @test sum (es_val[o] for o in outs[t_val]; init = 0 ) == 0
442
+ for i in 1 : 4
443
+ if i != s_val && i != t_val
444
+ # other nodes: must have one incoming and one outgoing iff node is
445
+ # in subgraph.
446
+ @test sum (es_val[o] for o in outs[i]; init = 0 ) == ns_val[i]
447
+ @test sum (es_val[o] for o in ins[i]; init = 0 ) == ns_val[i]
448
+ end
449
+ end
450
+ return
451
+ end
452
+
453
+ function setup_test (
454
+ :: typeof (test_cpsat_Path),
455
+ model:: MOIU.MockOptimizer ,
456
+ :: Config{T} ,
457
+ ) where {T}
458
+ MOIU. set_mock_optimize! (
459
+ model,
460
+ (mock:: MOIU.MockOptimizer ) -> MOIU. mock_optimize! (
461
+ mock,
462
+ MOI. OPTIMAL,
463
+ (MOI. FEASIBLE_POINT, T[1 , 4 , 1 , 1 , 0 , 1 , 1 , 0 , 0 , 1 , 0 ]),
464
+ ),
465
+ )
466
+ return
467
+ end
0 commit comments