14 package com.google.ortools.constraintsolver;
16 import static com.google.common.truth.Truth.assertThat;
17 import static org.junit.jupiter.api.Assertions.assertEquals;
18 import static org.junit.jupiter.api.Assertions.assertFalse;
19 import static org.junit.jupiter.api.Assertions.assertNotNull;
20 import static org.junit.jupiter.api.Assertions.assertTrue;
22 import com.google.common.collect.Iterables;
23 import com.google.ortools.Loader;
24 import com.google.ortools.constraintsolver.ConstraintSolverParameters;
25 import com.google.ortools.constraintsolver.RegularLimitParameters;
26 import java.util.ArrayList;
27 import java.util.concurrent.atomic.AtomicInteger;
28 import java.util.function.Consumer;
29 import java.util.function.Supplier;
30 import org.junit.jupiter.api.BeforeEach;
31 import org.junit.jupiter.api.Test;
42 final Solver solver =
new Solver(
"TestSolver");
43 assertNotNull(solver);
44 assertEquals(
"TestSolver", solver.model_name());
45 assertNotNull(solver.toString());
50 final Solver solver =
new Solver(
"Solver");
51 final IntVar var = solver.makeIntVar(3, 11,
"IntVar");
52 assertEquals(3, var.min());
53 assertEquals(11, var.max());
58 final Solver solver =
new Solver(
"Solver");
59 final IntVar[] vars = solver.makeIntVarArray(7, 3, 5,
"vars");
60 assertThat(vars).hasLength(7);
61 for (IntVar var : vars) {
62 assertEquals(3, var.min());
63 assertEquals(5, var.max());
69 final Solver solver =
new Solver(
"testRabbitsPheasants");
70 final IntVar rabbits = solver.makeIntVar(0, 100,
"rabbits");
71 final IntVar pheasants = solver.makeIntVar(0, 100,
"pheasants");
72 solver.addConstraint(solver.makeEquality(solver.makeSum(rabbits, pheasants), 20));
73 solver.addConstraint(solver.makeEquality(
74 solver.makeSum(solver.makeProd(rabbits, 4), solver.makeProd(pheasants, 2)), 56));
75 final DecisionBuilder db =
76 solver.makePhase(rabbits, pheasants, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE);
78 solver.nextSolution();
79 assertEquals(8, rabbits.value());
80 assertEquals(12, pheasants.value());
87 public Decision next(Solver solver)
throws Solver.FailException {
88 System.out.println(
"In Dummy Decision Builder");
93 public String toString() {
94 return "DummyDecisionBuilder";
100 final Solver solver =
new Solver(
"testDummyDecisionBuilder");
101 final DecisionBuilder db =
new DummyDecisionBuilder();
102 assertTrue(solver.solve(db));
110 public Decision next(Solver solver)
throws Solver.FailException {
111 System.out.println(
"In Fail Decision Builder");
119 final Solver solver =
new Solver(
"testFailDecisionBuilder");
120 final DecisionBuilder db =
new FailDecisionBuilder();
121 assertFalse(solver.solve(db));
128 final Solver solver =
new Solver(
"GR " + m);
130 final IntVar[] ticks = solver.makeIntVarArray(m, 0, (1 << (m + 1)) - 1,
"ticks");
132 solver.addConstraint(solver.makeEquality(ticks[0], 0));
134 for (
int i = 0; i < ticks.length - 1; i++) {
135 solver.addConstraint(solver.makeLess(ticks[i], ticks[i + 1]));
138 final ArrayList<IntVar> diff =
new ArrayList<>();
139 for (
int i = 0; i < m - 1; i++) {
140 for (
int j = i + 1; j < m; j++) {
141 diff.add(solver.makeDifference(ticks[j], ticks[i]).var());
145 solver.addConstraint(solver.makeAllDifferent(diff.toArray(
new IntVar[0]),
true));
149 solver.addConstraint(solver.makeLess(diff.get(0), Iterables.getLast(diff)));
152 final OptimizeVar opt = solver.makeMinimize(ticks[m - 1], 1);
153 final DecisionBuilder db =
154 solver.makePhase(ticks, Solver.CHOOSE_MIN_SIZE_LOWEST_MIN, Solver.ASSIGN_MIN_VALUE);
155 final SearchMonitor log = solver.makeSearchLog(10000, opt);
156 assertTrue(solver.solve(db, opt, log));
157 assertEquals(34, opt.best());
162 final Solver solver =
new Solver(
"testElementFunction");
163 final IntVar index = solver.makeIntVar(0, 10,
"index");
164 final IntExpr element = solver.makeElement((
long x) -> x * 2, index);
165 assertEquals(0, element.min());
166 assertEquals(20, element.max());
171 final ConstraintSolverParameters parameters =
172 Solver.defaultSolverParameters().toBuilder().setTraceSearch(
true).build();
173 final Solver solver =
new Solver(
"testSolverParameters", parameters);
174 final ConstraintSolverParameters stored = solver.parameters();
175 assertTrue(stored.getTraceSearch());
180 final Solver solver =
new Solver(
"testRegularLimitParameters");
181 final RegularLimitParameters protoLimit =
182 solver.makeDefaultRegularLimitParameters().toBuilder().setFailures(20000).build();
183 assertEquals(20000, protoLimit.getFailures());
184 final SearchLimit limit = solver.makeLimit(protoLimit);
185 assertNotNull(limit);
191 final StringProperty call =
new StringProperty(
"");
192 final Solver solver =
new Solver(
"ClosureDecisionTest");
193 final Decision decision = solver.makeDecision(
194 (Solver s) -> call.setValue(
"Apply"), (Solver s) -> call.setValue(
"Refute"));
197 decision.apply(solver);
198 assertEquals(
"Apply", call.toString());
200 decision.refute(solver);
201 assertEquals(
"Refute", call.toString());
206 final Solver solver =
new Solver(
"SolverTestName");
207 final String modelName = solver.model_name();
209 final AtomicInteger countApply =
new AtomicInteger(0);
210 final AtomicInteger countRefute =
new AtomicInteger(0);
211 assertEquals(0, countApply.intValue());
212 assertEquals(0, countRefute.intValue());
213 final Decision decision = solver.makeDecision(
216 assertEquals(s.model_name(), modelName);
217 countApply.addAndGet(1);
220 assertEquals(s.model_name(), modelName);
221 countRefute.addAndGet(1);
225 decision.apply(solver);
226 assertEquals(1, countApply.intValue());
227 assertEquals(0, countRefute.intValue());
229 decision.refute(solver);
230 assertEquals(1, countApply.intValue());
231 assertEquals(1, countRefute.intValue());
236 Consumer<Solver> apply;
237 Consumer<Solver> refute;
247 public Decision
next(Solver solver)
throws Solver.FailException {
252 return solver.makeDecision(apply, refute);
257 return "ActionDecisionBuilder";
264 final Solver solver =
new Solver(
"testActionDecisionBuilder");
266 final AtomicInteger countApply =
new AtomicInteger(0);
267 final AtomicInteger countRefute =
new AtomicInteger(0);
268 assertEquals(0, countApply.intValue());
269 assertEquals(0, countRefute.intValue());
271 (Solver s) -> countApply.addAndGet(1), (Solver s) -> countRefute.addAndGet(1));
272 solver.newSearch(db);
273 assertTrue(solver.nextSolution());
274 assertEquals(1, countApply.intValue());
275 assertEquals(0, countRefute.intValue());
276 assertTrue(solver.nextSolution());
277 assertEquals(1, countApply.intValue());
278 assertEquals(1, countRefute.intValue());
283 private static class MoveOneVar
extends IntVarLocalSearchOperator {
284 public MoveOneVar(IntVar[] variables) {
291 protected boolean oneNeighbor() {
292 long currentValue = oldValue(variableIndex);
294 setValue(variableIndex, currentValue + 1);
295 variableIndex = (variableIndex + 1) % size();
297 setValue(variableIndex, currentValue - 1);
304 public void onStart() {}
307 private long variableIndex;
309 private boolean moveUp;
314 final Solver solver =
new Solver(
"Solver");
315 final IntVar[] vars = solver.makeIntVarArray(4, 0, 4,
"vars");
316 final IntVar sumVar = solver.makeSum(vars).var();
317 final OptimizeVar obj = solver.makeMinimize(sumVar, 1);
318 final DecisionBuilder db =
319 solver.makePhase(vars, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MAX_VALUE);
320 final MoveOneVar moveOneVar =
new MoveOneVar(vars);
321 final LocalSearchPhaseParameters lsParams =
322 solver.makeLocalSearchPhaseParameters(sumVar, moveOneVar, db);
323 final DecisionBuilder ls = solver.makeLocalSearchPhase(vars, db, lsParams);
324 final SolutionCollector collector = solver.makeLastSolutionCollector();
325 collector.addObjective(sumVar);
326 final SearchMonitor log = solver.makeSearchLog(1000, obj);
328 assertTrue(solver.solve(ls, collector, obj, log));
331 private static class SumFilter
extends IntVarLocalSearchFilter {
332 public SumFilter(IntVar[] vars) {
338 protected void onSynchronize(Assignment unusedDelta) {
340 for (
int index = 0; index < size(); ++index) {
346 public boolean accept(Assignment delta, Assignment unusedDeltadelta,
long unusedObjectiveMin,
347 long unusedObjectiveMax) {
348 AssignmentIntContainer solutionDelta = delta.intVarContainer();
349 int solutionDeltaSize = solutionDelta.size();
351 for (
int i = 0; i < solutionDeltaSize; ++i) {
352 if (!solutionDelta.element(i).activated()) {
357 for (
int index = 0; index < solutionDeltaSize; ++index) {
358 int touchedVar = index(solutionDelta.element(index).var());
359 long oldValue = value(touchedVar);
360 long newValue = solutionDelta.element(index).value();
361 newSum += newValue - oldValue;
368 private static class StringProperty {
369 public StringProperty(String initialValue) {
370 value = initialValue;
372 public void setValue(String newValue) {
377 public String toString() {
380 private String value;
385 final Solver solver =
new Solver(
"Solver");
386 final IntVar[] vars = solver.makeIntVarArray(4, 0, 4,
"vars");
387 final IntVar sumVar = solver.makeSum(vars).var();
388 final OptimizeVar obj = solver.makeMinimize(sumVar, 1);
389 final DecisionBuilder db =
390 solver.makePhase(vars, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MAX_VALUE);
391 MoveOneVar moveOneVar =
new MoveOneVar(vars);
392 SumFilter filter =
new SumFilter(vars);
393 IntVarLocalSearchFilter[] filters =
new IntVarLocalSearchFilter[1];
395 LocalSearchFilterManager filterManager =
new LocalSearchFilterManager(filters);
396 LocalSearchPhaseParameters lsParams =
397 solver.makeLocalSearchPhaseParameters(sumVar, moveOneVar, db,
null, filterManager);
398 DecisionBuilder ls = solver.makeLocalSearchPhase(vars, db, lsParams);
399 SolutionCollector collector = solver.makeLastSolutionCollector();
400 collector.addObjective(sumVar);
401 SearchMonitor log = solver.makeSearchLog(1000, obj);
402 solver.solve(ls, collector, obj, log);
405 private static class OneVarLns
extends BaseLns {
406 public OneVarLns(IntVar[] vars) {
411 public void initFragments() {
416 public boolean nextFragment() {
419 appendToFragment(index);
431 final Solver solver =
new Solver(
"Solver");
432 final IntVar[] vars = solver.makeIntVarArray(4, 0, 4,
"vars");
433 final IntVar sumVar = solver.makeSum(vars).var();
434 final OptimizeVar obj = solver.makeMinimize(sumVar, 1);
435 final DecisionBuilder db =
436 solver.makePhase(vars, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MAX_VALUE);
437 final OneVarLns oneVarLns =
new OneVarLns(vars);
438 final LocalSearchPhaseParameters lsParams =
439 solver.makeLocalSearchPhaseParameters(sumVar, oneVarLns, db);
440 final DecisionBuilder ls = solver.makeLocalSearchPhase(vars, db, lsParams);
441 final SolutionCollector collector = solver.makeLastSolutionCollector();
442 collector.addObjective(sumVar);
443 final SearchMonitor log = solver.makeSearchLog(1000, obj);
444 solver.solve(ls, collector, obj, log);
450 private static void runSearchLog(SearchMonitor searchlog) {
451 searchlog.enterSearch();
452 searchlog.exitSearch();
453 searchlog.acceptSolution();
454 searchlog.atSolution();
455 searchlog.beginFail();
456 searchlog.noMoreSolutions();
457 searchlog.beginInitialPropagation();
458 searchlog.endInitialPropagation();
464 final Solver solver =
new Solver(
"TestSearchLog");
465 final IntVar var = solver.makeIntVar(1, 1,
"Variable");
466 solver.makeMinimize(var, 1);
467 final SearchMonitor searchlog = solver.makeSearchLog(0);
468 runSearchLog(searchlog);
471 private static class SearchCount
implements Supplier<String> {
472 public SearchCount(AtomicInteger initialCount) {
473 count = initialCount;
476 public String
get() {
478 return "display callback called...";
480 private final AtomicInteger count;
485 final Solver solver =
new Solver(
"TestSearchLog");
486 final AtomicInteger count =
new AtomicInteger(0);
487 final SearchMonitor searchlog = solver.makeSearchLog(0,
488 new SearchCount(count));
490 runSearchLog(searchlog);
491 assertEquals(1, count.intValue());
496 final Solver solver =
new Solver(
"TestSearchLog");
497 final AtomicInteger count =
new AtomicInteger(0);
498 final SearchMonitor searchlog = solver.makeSearchLog(0,
501 return "display callback called...";
504 runSearchLog(searchlog);
505 assertEquals(1, count.intValue());
510 final Solver solver =
new Solver(
"TestSearchLog");
511 final IntVar var = solver.makeIntVar(1, 1,
"Variable");
512 final AtomicInteger count =
new AtomicInteger(0);
513 final SearchMonitor searchlog = solver.makeSearchLog(0,
515 new SearchCount(count));
517 runSearchLog(searchlog);
518 assertEquals(1, count.intValue());
523 final Solver solver =
new Solver(
"TestSearchLog");
524 final IntVar var = solver.makeIntVar(1, 1,
"Variable");
525 final OptimizeVar objective = solver.makeMinimize(var, 1);
526 final AtomicInteger count =
new AtomicInteger(0);
527 final SearchMonitor searchlog = solver.makeSearchLog(0,
529 new SearchCount(count));
531 runSearchLog(searchlog);
532 assertEquals(1, count.intValue());