@Test(groups = "10s", timeOut = 60000) public void test1() { boolean bounded; // true if domains are bounded, false if they are enumerated Random rand = new Random(0); for (int k = 0; k < 20000; k++) { long seed = System.currentTimeMillis(); rand.setSeed(seed); bounded = rand.nextBoolean(); int size = 5; // domain size int range = 15; // value range int[][] domains; if (bounded) { domains = DomainBuilder.buildFullDomains(3, size, range, rand); } else { domains = DomainBuilder.buildFullDomains2( 3, size, range, rand, rand.nextDouble(), rand.nextBoolean()); } // total number of solutions: brut force algorithm long base = brutForceTest(domains, bounded); Model s = modeler(domains, bounded, seed); // SearchMonitorFactory.log(s, false, false); try { while (s.getSolver().solve()) ; } catch (AssertionError ae) { System.err.printf("seed: %d\n", seed); throw ae; } long cp = s.getSolver().getSolutionCount(); Assert.assertEquals( cp, base, "found: " + cp + " solutions, while " + base + " are expected (" + seed + ")"); } }
@Test(groups = "1s", timeOut = 60000) public void testNominal() { Model model = new Model(); SetVar[] vars = model.setVarArray(5, new int[] {}, new int[] {1, 2, 3, 4}); model.symmetric(vars).post(); }
@Input(solutions = 513) public Object testSubstring(Model model) { return $( model.intVarArray("substring", 2, -1, 1), model.intVar("substringLength", 0, 2), model.intVar("index", 0, 2), model.intVarArray("supstring", 4, -1, 1)); }
@Test(groups = "1s", timeOut = 60000) public void test11() { Model model = new Model(); BoolVar a = model.boolVar("a"); BoolVar b = model.boolVar("b"); LogOp l = LogOp.or(LogOp.and(a, b.not()), LogOp.and(a.not(), b), LogOp.and(a.not(), b.not())); ILogical ll = LogicTreeToolBox.toCNF(l, model); Assert.assertEquals(ll.toString(), "(not(b) or not(a))"); }
@Test(groups = "1s", timeOut = 60000) public void test14() { Model model = new Model(); BoolVar a = model.boolVar("a"); BoolVar b = model.boolVar("b"); LogOp l = LogOp.or(a, b, a.not(), a.not()); ILogical ll = LogicTreeToolBox.toCNF(l, model); Assert.assertEquals(ll.toString(), "cste -- 1 = 1"); }
@Test public void test2() { Model s = new Model(); IntVar a = s.intVar("a", 0, 32, true); IntVar b = s.intVar("b", 0, 48, true); double q = 1.5; s.post(new RoundedUpDivision(a, b, q)); Assert.assertEquals(s.getSolver().findAllSolutions().size(), 49); // Assert.assertEquals(s.getNbSolutions(), 33); }
@Test(groups = "1s", timeOut = 60000) public void testTrue() { Model model = new Model(); int var = 10; SetVar setVar = model.setVar(new int[] {10}, new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); model.member(var, setVar).post(); assertEquals(model.getSolver().isSatisfied(), ESat.TRUE); checkSolutions(model, setVar, var); }
@Test(groups = "1s", timeOut = 60000) public void testNominal() { Model model = new Model(); IntVar var = model.intVar(10); SetVar setVar = model.setVar(new int[] {}, new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); model.member(var, setVar).post(); assertEquals(model.getSolver().isSatisfied(), ESat.UNDEFINED); checkSolutions(model, setVar, var.getValue()); }
@Test(groups = "1s", timeOut = 60000) public void test3() { Model model = new Model(); BoolVar a = model.boolVar("a"); BoolVar b = model.boolVar("b"); BoolVar c = model.boolVar("c"); LogOp root = LogOp.or(LogOp.and(a, b), c); root = LogicTreeToolBox.developOr(root); Assert.assertEquals(root.toString(), "((a or c) and (b or c))"); }
@Test(groups = "1s", timeOut = 60000) public void test6() { Model model = new Model(); BoolVar a = model.boolVar("a"); BoolVar b = model.boolVar("b"); LogOp root = LogOp.implies(a, b); ILogical l = LogicTreeToolBox.toCNF(root, model); Assert.assertEquals(l.toString(), "(b or not(a))"); }
@Test(groups = "1s", timeOut = 60000) public void testHeadOnly() { Model model = new Model(); SetVar[] vars = model.setVarArray(5, new int[] {}, new int[] {0, 1}); model.symmetric(vars).post(); int nbSol = checkSolutions(model, vars); // The number of results must be the same as a 2-sized array model = new Model(); vars = model.setVarArray(2, new int[] {}, new int[] {0, 1}); model.symmetric(vars).post(); assertEquals(nbSol, checkSolutions(model, vars)); }
@Test(groups = "1s", timeOut = 60000) public void test7() { Model model = new Model(); BoolVar a = model.boolVar("a"); BoolVar b = model.boolVar("b"); BoolVar c = model.boolVar("c"); LogOp root = LogOp.ifThenElse(a, b, c); ILogical l = LogicTreeToolBox.toCNF(root, model); Assert.assertEquals(l.toString(), "((a or c) and (b or c) and (b or not(a)))"); }
public Model modeler(int[][] domains, boolean bounded, long seed) { Model s = new Model(); IntVar[] vars = new IntVar[3]; for (int i = 0; i < 3; i++) { if (bounded) { vars[i] = s.intVar("x_" + i, domains[i][0], domains[i][1], true); } else { vars[i] = s.intVar("x_" + i, domains[i]); } } Constraint div = make(vars, s); div.post(); s.getSolver().setSearch(randomSearch(vars, seed)); return s; }
@Test(groups = "1s", timeOut = 60000) public void test4() { Model model = new Model(); BoolVar a = model.boolVar("a").not(); BoolVar b = model.boolVar("b"); BoolVar c = model.boolVar("c"); BoolVar d = model.boolVar("d"); LogOp root = LogOp.nor(LogOp.or(LogOp.nand(a, b), c), d); LogicTreeToolBox.expandNot(root); Assert.assertEquals(root.toString(), "(((not(a) and b) and not(c)) and not(d))"); }
@Test(groups = "1s", timeOut = 60000) public void test1() { Model model = new Model(); BoolVar a = model.boolVar("a"); BoolVar b = model.boolVar("b"); BoolVar c = model.boolVar("c"); BoolVar d = model.boolVar("d"); LogOp root = LogOp.nand(LogOp.nor(a, b), LogOp.or(c, d)); ILogical l = LogicTreeToolBox.toCNF(root, model); Assert.assertEquals(l.toString(), "((a or b or not(c)) and (a or b or not(d)))"); }
@Test(groups = "1s", timeOut = 60000) public void test2() { Model model = new Model(); BoolVar a = model.boolVar("a").not(); BoolVar b = model.boolVar("b"); BoolVar c = model.boolVar("c"); BoolVar d = model.boolVar("d"); LogOp root = LogOp.or(LogOp.or(LogOp.or(a, b), c), d); LogicTreeToolBox.merge(LogOp.Operator.OR, root); Assert.assertEquals(root.toString(), "(d or c or not(a) or b)"); }
@Test(groups = "1s", timeOut = 60000) public void test9() { Model model = new Model(); BoolVar a = model.boolVar("a"); BoolVar na = a.not(); BoolVar b = model.boolVar("b"); BoolVar c = model.boolVar("c"); BoolVar d = model.boolVar("d"); LogOp root = LogOp.and(a, b, na, c, d); ILogical l = LogicTreeToolBox.toCNF(root, model); Assert.assertEquals(l.toString(), "cste -- 0 = 0"); }
@Test(groups = "1s", timeOut = 60000) public void test8() { Model model = new Model(); BoolVar a = model.boolVar("a"); BoolVar na = a.not(); BoolVar b = model.boolVar("b"); BoolVar nb = b.not(); BoolVar c = model.boolVar("c"); BoolVar d = model.boolVar("d"); LogOp root = LogOp.and(LogOp.or(a, b, na), LogOp.or(c, d), LogOp.or(b, nb)); ILogical l = LogicTreeToolBox.toCNF(root, model); Assert.assertEquals(l.toString(), "(c or d)"); }
private int checkSolutions(Model model, SetVar set, int value) { int nbSol = 0; while (model.getSolver().solve()) { nbSol++; assertTrue(set.getValue().contains(value)); } assertTrue(nbSol > 0); return nbSol; }
private int checkSolutions(Model model, SetVar[] vars) { int nbSol = 0; while (model.getSolver().solve()) { nbSol++; for (int i = 0; i < vars.length; i++) { for (Integer value : vars[i].getValue()) { assertTrue(vars[value].getValue().contains(i)); } } } assertTrue(nbSol > 0); return nbSol; }
@Override public IntVar intVar() { if (me == null) { IntVar v = e.intVar(); switch (op) { case NEG: me = model.intMinusView(v); break; case ABS: me = model.intAbsView(v); break; case SQR: int[] bounds = VariableUtils.boundsForMultiplication(v, v); me = model.intVar(model.generateName("sqr_exp_"), bounds[0], bounds[1]); model.times(v, v, me).post(); break; default: throw new UnsupportedOperationException( "Unary arithmetic expressions does not support " + op.name()); } } return me; }
@Test(groups = "1s", timeOut = 60000) public void testFalse() { Model model = new Model(); IntVar var = model.intVar(12); SetVar setVar = model.setVar(new int[] {10}, new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); model.member(var, setVar).post(); assertEquals(model.getSolver().isSatisfied(), ESat.FALSE); assertFalse(model.getSolver().solve()); }
@Test(groups = "1s", timeOut = 60000) public void test17() { Model model = new Model(); IntVar a = model.intVar("a", -1, 1, false); BoolVar b1 = model.boolVar("b1"); BoolVar b2 = model.boolVar("b2"); model.arithm(a, "=", 0).reifyWith(b1); model.arithm(a, ">", 0).reifyWith(b2); model.addClauses(new BoolVar[0], new BoolVar[] {b1, b2}); model.getMinisat().getPropSat().initialize(); try { model.getSolver().propagate(); b1.instantiateTo(1, Cause.Null); model.getSolver().propagate(); } catch (ContradictionException ex) { Assert.fail(); } Assert.assertTrue(b1.isInstantiatedTo(1)); Assert.assertTrue(b2.isInstantiatedTo(0)); Assert.assertTrue(a.isInstantiatedTo(0)); }
@Override protected Constraint make(IntVar[] vars, Model model) { return model.max(vars[0], vars[1], vars[2]); }
@Test(groups = "1s", timeOut = 60000) public void test10() { Model model = new Model(); BoolVar[] rows = model.boolVarArray("b", 3); model.ifThen(rows[0], model.arithm(rows[1], "+", rows[2], "=", 2)); model.ifThen(rows[0].not(), model.arithm(rows[1], "+", rows[2], "<=", 1)); // SearchMonitorFactory.log(solver, true, true); while (model.getSolver().solve()) ; long nbSol = model.getSolver().getSolutionCount(); for (int seed = 0; seed < 2000; seed++) { Model sCNF = new Model(); BoolVar[] rCNF = sCNF.boolVarArray("b", 3); LogOp tree = ifOnlyIf(rCNF[0], and(rCNF[1], rCNF[2])); sCNF.addClauses(tree); sCNF.getSolver().setSearch(randomSearch(rCNF, seed)); // SearchMonitorFactory.log(sCNF, true, true); while (sCNF.getSolver().solve()) ; assertEquals(sCNF.getSolver().getSolutionCount(), nbSol); } }
/** * Creates a default search strategy for the given model. This heuristic is complete (handles * IntVar, BoolVar, SetVar and RealVar) * * @param model a model requiring a default search strategy */ public static AbstractStrategy defaultSearch(Model model) { Solver r = model.getSolver(); // 1. retrieve variables, keeping the declaration order, and put them in four groups: List<IntVar> livars = new ArrayList<>(); // integer and boolean variables List<SetVar> lsvars = new ArrayList<>(); // set variables List<RealVar> lrvars = new ArrayList<>(); // real variables. Variable[] variables = model.getVars(); Variable objective = null; for (Variable var : variables) { int type = var.getTypeAndKind(); if ((type & Variable.CSTE) == 0) { int kind = type & Variable.KIND; switch (kind) { case Variable.BOOL: case Variable.INT: livars.add((IntVar) var); break; case Variable.SET: lsvars.add((SetVar) var); break; case Variable.REAL: lrvars.add((RealVar) var); break; default: break; // do not throw exception to allow ad hoc variable kinds } } } // 2. extract the objective variable if any (to avoid branching on it) if (r.getObjectiveManager().isOptimization()) { objective = r.getObjectiveManager().getObjective(); if ((objective.getTypeAndKind() & Variable.REAL) != 0) { lrvars.remove(objective); // real var objective } else { assert (objective.getTypeAndKind() & Variable.INT) != 0; livars.remove(objective); // bool/int var objective } } // 3. Creates a default search strategy for each variable kind ArrayList<AbstractStrategy> strats = new ArrayList<>(); if (livars.size() > 0) { strats.add(intVarSearch(livars.toArray(new IntVar[livars.size()]))); } if (lsvars.size() > 0) { strats.add(setVarSearch(lsvars.toArray(new SetVar[lsvars.size()]))); } if (lrvars.size() > 0) { strats.add(realVarSearch(lrvars.toArray(new RealVar[lrvars.size()]))); } // 4. lexico LB/UB branching for the objective variable if (objective != null) { boolean max = r.getObjectiveManager().getPolicy() == ResolutionPolicy.MAXIMIZE; if ((objective.getTypeAndKind() & Variable.REAL) != 0) { strats.add( realVarSearch( new Cyclic<>(), max ? new RealDomainMax() : new RealDomainMin(), (RealVar) objective)); } else { strats.add(max ? minDomUBSearch((IntVar) objective) : minDomLBSearch((IntVar) objective)); } } // 5. avoid null pointers in case all variables are instantiated if (strats.isEmpty()) { strats.add(minDomLBSearch(model.boolVar(true))); } // 6. add last conflict return lastConflict(sequencer(strats.toArray(new AbstractStrategy[strats.size()]))); }
/** * Make a new model. * * @param p the RP to use as a basis. * @param e the VM managed by the action * @throws org.btrplace.scheduler.SchedulerException if an error occurred */ public RelocatableVM(ReconfigurationProblem p, VM e) throws SchedulerException { // Get vars vm = e; rp = p; src = rp.getSourceModel().getMapping().getVMLocation(e); org.chocosolver.solver.Model csp = rp.getModel(); Model mo = rp.getSourceModel(); // Default values start = rp.getStart(); end = rp.getStart(); duration = csp.intVar(0); state = csp.boolVar(true); // If not manageable, the VM stays on the current host if (!p.getManageableVMs().contains(e)) { stay = csp.boolVar(true); doReinstantiation = csp.boolVar(false); manageable = false; IntVar host = rp.makeCurrentHost(vm, PREFIX_STAY, vm, ").host"); cSlice = new SliceBuilder(rp, vm, PREFIX_STAY, vm.toString(), ").cSlice") .setHoster(host) .setEnd(rp.makeUnboundedDuration(PREFIX_STAY, vm, ").cSlice_end")) .build(); dSlice = new SliceBuilder(rp, vm, PREFIX_STAY, vm, ").dSlice") .setHoster(host) .setStart(cSlice.getEnd()) .build(); return; } // The VM can move (to re-instantiate or migrate) OR STAY to the same host stay = csp.boolVar(rp.makeVarLabel(vm, "stay")); cSlice = new SliceBuilder(rp, vm, PREFIX, vm, ").cSlice") .setHoster(rp.getNode(rp.getSourceModel().getMapping().getVMLocation(vm))) .setEnd(rp.makeUnboundedDuration(PREFIX, vm, ").cSlice_end")) .build(); dSlice = new SliceBuilder(rp, vm, PREFIX, vm, ").dSlice") .setStart(rp.makeUnboundedDuration(PREFIX, vm, ").dSlice_start")) .build(); // Update start and end vars of the action start = dSlice.getStart(); end = cSlice.getEnd(); csp.post(new Arithmetic(end, Operator.LE, rp.getEnd())); // Get some static durations from evaluators DurationEvaluators dev = rp.getDurationEvaluators(); int migrateDuration = dev.evaluate(rp.getSourceModel(), MigrateVM.class, vm); int bootDuration = dev.evaluate(rp.getSourceModel(), org.btrplace.plan.event.BootVM.class, vm); int forgeD = p.getDurationEvaluators() .evaluate(p.getSourceModel(), org.btrplace.plan.event.ForgeVM.class, vm); // Compute the re-instantiation duration int reInstantiateDuration = bootDuration + forgeD; reInstantiateDuration = forgeD; // Compliant with CMaxOnlineTest and others // Get the networking view if attached Network network = Network.get(mo); IntVar migrationDuration; if (network != null) { // Set the migration algorithm postCopy = mo.getAttributes().get(vm, "postCopy", false); // Create unbounded/large domain vars for migration duration and bandwidth migrationDuration = p.makeUnboundedDuration("migration(", vm, ").duration"); bandwidth = csp.intVar(PREFIX + vm + ").bandwidth", 0, Integer.MAX_VALUE / 100, true); } // No networking view, set the duration from the evaluator else { // The duration can still be 0 => the VM STAY ! migrationDuration = csp.intVar( rp.makeVarLabel("migration(", vm, ").duration"), new int[] {0, migrateDuration}); bandwidth = null; } // Possibly re-instantiate (if some attributes are defined) if (mo.getAttributes().get(vm, "clone", false) && mo.getAttributes().isSet(vm, "template")) { doReinstantiation = csp.boolVar(rp.makeVarLabel("relocation_method(", vm, ")")); duration = csp.intVar( rp.makeVarLabel(PREFIX, vm, ").duration"), Math.min(migrationDuration.getLB(), reInstantiateDuration), Math.max(migrationDuration.getUB(), reInstantiateDuration), true); // Re-instantiate or migrate // (Prefer the re-instantiation if the duration are the same, otherwise choose the min) rp.getModel() .ifThenElse( rp.getModel() .or( new Arithmetic( doReinstantiation, Operator.EQ, 0), // can be instantiated externally ! new Arithmetic(migrationDuration, Operator.LT, reInstantiateDuration)), new Arithmetic(duration, Operator.EQ, migrationDuration), new Arithmetic(duration, Operator.EQ, reInstantiateDuration)); // If it is a re-instantiation then specify that the dSlice must start AFTER the Forge delay IntVar time = csp.intVar(rp.makeVarLabel(doReinstantiation.getName(), " * ", forgeD), 0, forgeD, false); csp.post(csp.times(doReinstantiation, forgeD, time)); csp.post(new Arithmetic(start, Operator.GE, time)); // Be sure that doReinstantiation will be instantiated csp.post(new FastIFFEq(doReinstantiation, duration, reInstantiateDuration)); } // The VM either migrate or stay but won't be re-instantiated for sure else { doReinstantiation = csp.boolVar(false); duration = migrationDuration; } // If the VM stay (src host == dst host), then duration = 0 csp.post(new FastIFFEq(stay, dSlice.getHoster(), cSlice.getHoster().getValue())); csp.post(new FastIFFEq(stay, duration, 0)); // We have to force the migration duration equals to 0 if it stays // otherwise, the variable will be free csp.post(new FastIFFEq(stay, migrationDuration, 0)); // Create the task ('default' cumulative constraint with a height of 1) migrationTask = new Task(start, duration, end); }