简体   繁体   中英

Reusing choco solver model to further constrain the solution

I'm using the choco solver library to generate a set of puzzles. I need to run the solver, check how many solutions there are and if there is more than one, add an extra constraint. Repeating this will give me a set of constraints (clues) that has a unique solution.

However once I've run model.getSolver(findAllSolutions()) any additional checks return zero solutions.

I'm guessing I need to somehow reset the model solver but can't find a way of achieving this - I'd rather not generate a new model and recreate the exiting constraints if I have to.

The original code has 110 IntVar's and a huge number of constraints, but I've created a much smaller example.

Note: in the real application I use model.getSolver().findAllSolutions(new SolutionCounter(model,2)) to speed things up, but I've omitted that step here.

Model model = new Model();
// setup two doors A and B, one has the value 0 the other 1
IntVar doorA = model.intVar("Door A", 0, 1);
IntVar doorB = model.intVar("Door B", 0, 1);
model.allDifferent(new IntVar[]{doorA, doorB}).post();
// setup two windows A and B, one has the value 0 the other 1
IntVar windowA = model.intVar("Window A", 0, 1);
IntVar windowB = model.intVar("Window B", 0, 1);
model.allDifferent(new IntVar[]{windowA, windowB}).post();
// assign the first constraint and count the solutions
model.arithm(doorA,"=",0).post();
// this should force door B to be 1 - there are two remaining solutions
List<Solution> solutions = model.getSolver().findAllSolutions();
System.out.println("results after first clue");
for (Solution s : solutions) {
     System.out.println(">"+s.toString());
}
assertEquals("First clue leaves two solutions",2,solutions.size());
// add second clue
model.arithm(windowA,"=",1).post();
// this should force window B to by 0 - only one valid solution
List<Solution> solutions2 = model.getSolver().findAllSolutions();
System.out.println("results after second clue");
for (Solution s : solutions2) {
   System.out.println(">"+s.toString());
}
assertEquals("Second clue leaves one solution",1,solutions2.size());

For anybody else looking for this, it turns out that the answer is simple.

model.getSolver().reset();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM