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