From c10c6ed709a0b1e2032ad556470f31077a2e2cf7 Mon Sep 17 00:00:00 2001 From: Dimos Tsouros Date: Fri, 15 Sep 2023 17:50:11 +0200 Subject: [PATCH] tests for choco --- tests/test_solvers.py | 109 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/tests/test_solvers.py b/tests/test_solvers.py index e8f06849b..a38878204 100644 --- a/tests/test_solvers.py +++ b/tests/test_solvers.py @@ -8,6 +8,8 @@ from cpmpy.solvers.minizinc import CPM_minizinc from cpmpy.solvers.gurobi import CPM_gurobi from cpmpy.solvers.exact import CPM_exact +from cpmpy.solvers.choco import CPM_choco + from cpmpy.exceptions import MinizincNameException @@ -526,6 +528,113 @@ def test_false(self): if cls.supported(): self.assertFalse(m.solve(solver=name)) + @pytest.mark.skipif(not CPM_choco.supported(), + reason="pychoco not installed") + def test_choco(self): + bv = cp.boolvar(shape=3) + iv = cp.intvar(0, 9, shape=3) + # circular 'bigger then', UNSAT + m = cp.Model([ + bv[0].implies(iv[0] > iv[1]), + bv[1].implies(iv[1] > iv[2]), + bv[2].implies(iv[2] > iv[0]) + ]) + m += sum(bv) == len(bv) + s = cp.SolverLookup.get("choco", m) + self.assertFalse(s.solve()) + + m = cp.Model(~(iv[0] != iv[1])) + s = cp.SolverLookup.get("choco", m) + self.assertTrue(s.solve()) + + m = cp.Model((iv[0] == 0) & ((iv[0] != iv[1]) == 0)) + s = cp.SolverLookup.get("choco", m) + self.assertTrue(s.solve()) + + m = cp.Model([~bv, ~((iv[0] + abs(iv[1])) == sum(iv))]) + s = cp.SolverLookup.get("choco", m) + self.assertTrue(s.solve()) + + @pytest.mark.skipif(not CPM_choco.supported(), + reason="pychoco not installed") + def test_choco_element(self): + + # test 1-D + iv = cp.intvar(-8, 8, 3) + idx = cp.intvar(-8, 8) + # test directly the constraint + constraints = [cp.Element(iv, idx) == 8] + model = cp.Model(constraints) + s = cp.SolverLookup.get("choco", model) + self.assertTrue(s.solve()) + self.assertTrue(iv.value()[idx.value()] == 8) + self.assertTrue(cp.Element(iv, idx).value() == 8) + # test through __get_item__ + constraints = [iv[idx] == 8] + model = cp.Model(constraints) + s = cp.SolverLookup.get("choco", model) + self.assertTrue(s.solve()) + self.assertTrue(iv.value()[idx.value()] == 8) + self.assertTrue(cp.Element(iv, idx).value() == 8) + # test 2-D + iv = cp.intvar(-8, 8, shape=(3, 3)) + idx = cp.intvar(0, 3) + idx2 = cp.intvar(0, 3) + constraints = [iv[idx, idx2] == 8] + model = cp.Model(constraints) + s = cp.SolverLookup.get("choco", model) + self.assertTrue(s.solve()) + self.assertTrue(iv.value()[idx.value(), idx2.value()] == 8) + + @pytest.mark.skipif(not CPM_choco.supported(), + reason="pychoco not installed") + def test_choco_gcc_alldiff(self): + + iv = cp.intvar(-8, 8, shape=5) + occ = cp.intvar(0, len(iv), shape=3) + val = [1, 4, 5] + model = cp.Model([cp.GlobalCardinalityCount(iv, val, occ)]) + solver = cp.SolverLookup.get("choco", model) + self.assertTrue(solver.solve()) + self.assertTrue(cp.GlobalCardinalityCount(iv, val, occ).value()) + self.assertTrue(all(cp.Count(iv, val[i]).value() == occ[i].value() for i in range(len(val)))) + occ = [2, 3, 0] + model = cp.Model([cp.GlobalCardinalityCount(iv, val, occ), cp.AllDifferent(val)]) + solver = cp.SolverLookup.get("choco", model) + self.assertTrue(solver.solve()) + self.assertTrue(cp.GlobalCardinalityCount(iv, val, occ).value()) + self.assertTrue(all(cp.Count(iv, val[i]).value() == occ[i] for i in range(len(val)))) + self.assertTrue(cp.GlobalCardinalityCount([iv[0],iv[2],iv[1],iv[4],iv[3]], val, occ).value()) + + def test_choco_inverse(self): + from cpmpy.solvers.ortools import CPM_ortools + + fwd = cp.intvar(0, 9, shape=10) + rev = cp.intvar(0, 9, shape=10) + + # Fixed value for `fwd` + fixed_fwd = [9, 4, 7, 2, 1, 3, 8, 6, 0, 5] + # Inverse of the above + expected_inverse = [8, 4, 3, 5, 1, 9, 7, 2, 6, 0] + + model = cp.Model(cp.Inverse(fwd, rev), fwd == fixed_fwd) + + solver = cp.SolverLookup.get("choco", model) + self.assertTrue(solver.solve()) + self.assertEqual(list(rev.value()), expected_inverse) + + def test_choco_objective(self): + iv = cp.intvar(0,10, shape=2) + m = cp.Model(iv >= 1, iv <= 5, maximize=sum(iv)) + s = cp.SolverLookup.get("choco", m) + self.assertTrue( s.solve() ) + self.assertEqual( s.objective_value(), 10) + + m = cp.Model(iv >= 1, iv <= 5, minimize=sum(iv)) + s = cp.SolverLookup.get("choco", m) + self.assertTrue( s.solve() ) + self.assertEqual(s.objective_value(), 2) + @pytest.mark.skipif(not CPM_gurobi.supported(), reason="Gurobi not installed") def test_gurobi_element(self):