Java Reference

Java Reference

CpModel.java
Go to the documentation of this file.
1// Copyright 2010-2021 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14package com.google.ortools.sat;
15
16import com.google.ortools.sat.AllDifferentConstraintProto;
17import com.google.ortools.sat.AutomatonConstraintProto;
18import com.google.ortools.sat.BoolArgumentProto;
19import com.google.ortools.sat.CpModelProto;
20import com.google.ortools.sat.CpObjectiveProto;
21import com.google.ortools.sat.CumulativeConstraintProto;
22import com.google.ortools.sat.DecisionStrategyProto;
23import com.google.ortools.sat.ElementConstraintProto;
24import com.google.ortools.sat.FloatObjectiveProto;
25import com.google.ortools.sat.InverseConstraintProto;
26import com.google.ortools.sat.LinearArgumentProto;
27import com.google.ortools.sat.LinearConstraintProto;
28import com.google.ortools.sat.LinearExpressionProto;
29import com.google.ortools.sat.NoOverlapConstraintProto;
30import com.google.ortools.sat.ReservoirConstraintProto;
31import com.google.ortools.sat.TableConstraintProto;
32import com.google.ortools.util.Domain;
33import java.util.Arrays;
34import java.util.LinkedHashMap;
35import java.util.Map;
36
37// TODO(user): Rewrite API to be closer to the C++ CpModel class.
43public final class CpModel {
44 static class CpModelException extends RuntimeException {
45 public CpModelException(String methodName, String msg) {
46 // Call constructor of parent Exception
47 super(methodName + ": " + msg);
48 }
49 }
50
52 public static class MismatchedArrayLengths extends CpModelException {
53 public MismatchedArrayLengths(String methodName, String array1Name, String array2Name) {
54 super(methodName, array1Name + " and " + array2Name + " have mismatched lengths");
55 }
56 }
57
59 public static class WrongLength extends CpModelException {
60 public WrongLength(String methodName, String msg) {
61 super(methodName, msg);
62 }
63 }
64
65 public CpModel() {
66 modelBuilder = CpModelProto.newBuilder();
67 constantMap = new LinkedHashMap<>();
68 }
69
70 // Integer variables.
71
73 public IntVar newIntVar(long lb, long ub, String name) {
74 return new IntVar(modelBuilder, new Domain(lb, ub), name);
75 }
76
84 public IntVar newIntVarFromDomain(Domain domain, String name) {
85 return new IntVar(modelBuilder, domain, name);
86 }
87
89 public BoolVar newBoolVar(String name) {
90 return new BoolVar(modelBuilder, new Domain(0, 1), name);
91 }
92
94 public IntVar newConstant(long value) {
95 if (constantMap.containsKey(value)) {
96 return new IntVar(modelBuilder, constantMap.get(value));
97 }
98 IntVar cste = new IntVar(modelBuilder, new Domain(value), ""); // bounds and name.
99 constantMap.put(value, cste.getIndex());
100 return cste;
101 }
102
105 if (constantMap.containsKey(1L)) {
106 return new BoolVar(modelBuilder, constantMap.get(1L));
107 }
108 BoolVar cste = new BoolVar(modelBuilder, new Domain(1), ""); // bounds and name.
109 constantMap.put(1L, cste.getIndex());
110 return cste;
111 }
112
115 if (constantMap.containsKey(0L)) {
116 return new BoolVar(modelBuilder, constantMap.get(0L));
117 }
118 BoolVar cste = new BoolVar(modelBuilder, new Domain(0), ""); // bounds and name.
119 constantMap.put(0L, cste.getIndex());
120 return cste;
121 }
122
123 // Boolean Constraints.
124
126 public Constraint addBoolOr(Literal[] literals) {
127 return addBoolOr(Arrays.asList(literals));
128 }
129
131 public Constraint addBoolOr(Iterable<Literal> literals) {
132 Constraint ct = new Constraint(modelBuilder);
133 BoolArgumentProto.Builder boolOr = ct.getBuilder().getBoolOrBuilder();
134 for (Literal lit : literals) {
135 boolOr.addLiterals(lit.getIndex());
136 }
137 return ct;
138 }
139
141 public Constraint addAtLeastOne(Literal[] literals) {
142 return addBoolOr(Arrays.asList(literals));
143 }
144
146 public Constraint addAtLeastOne(Iterable<Literal> literals) {
147 return addBoolOr(literals);
148 }
149
151 public Constraint addAtMostOne(Literal[] literals) {
152 return addAtMostOne(Arrays.asList(literals));
153 }
154
156 public Constraint addAtMostOne(Iterable<Literal> literals) {
157 Constraint ct = new Constraint(modelBuilder);
158 BoolArgumentProto.Builder atMostOne = ct.getBuilder().getAtMostOneBuilder();
159 for (Literal lit : literals) {
160 atMostOne.addLiterals(lit.getIndex());
161 }
162 return ct;
163 }
164
166 public Constraint addExactlyOne(Literal[] literals) {
167 return addExactlyOne(Arrays.asList(literals));
168 }
169
171 public Constraint addExactlyOne(Iterable<Literal> literals) {
172 Constraint ct = new Constraint(modelBuilder);
173 BoolArgumentProto.Builder exactlyOne = ct.getBuilder().getExactlyOneBuilder();
174 for (Literal lit : literals) {
175 exactlyOne.addLiterals(lit.getIndex());
176 }
177 return ct;
178 }
179
181 public Constraint addBoolAnd(Literal[] literals) {
182 return addBoolAnd(Arrays.asList(literals));
183 }
184
186 public Constraint addBoolAnd(Iterable<Literal> literals) {
187 Constraint ct = new Constraint(modelBuilder);
188 BoolArgumentProto.Builder boolAnd = ct.getBuilder().getBoolAndBuilder();
189 for (Literal lit : literals) {
190 boolAnd.addLiterals(lit.getIndex());
191 }
192 return ct;
193 }
194
196 public Constraint addBoolXor(Literal[] literals) {
197 return addBoolXor(Arrays.asList(literals));
198 }
199
201 public Constraint addBoolXor(Iterable<Literal> literals) {
202 Constraint ct = new Constraint(modelBuilder);
203 BoolArgumentProto.Builder boolXOr = ct.getBuilder().getBoolXorBuilder();
204 for (Literal lit : literals) {
205 boolXOr.addLiterals(lit.getIndex());
206 }
207 return ct;
208 }
209
212 return addBoolOr(new Literal[] {a.not(), b});
213 }
214
215 // Linear constraints.
216
219 Constraint ct = new Constraint(modelBuilder);
220 LinearConstraintProto.Builder lin = ct.getBuilder().getLinearBuilder();
221 final LinearExpr e = expr.build();
222 for (int i = 0; i < e.numElements(); ++i) {
223 lin.addVars(e.getVariableIndex(i)).addCoeffs(e.getCoefficient(i));
224 }
225 long offset = e.getOffset();
226 for (long b : domain.flattenedIntervals()) {
227 if (b == Long.MIN_VALUE || b == Long.MAX_VALUE) {
228 lin.addDomain(b);
229 } else {
230 lin.addDomain(b - offset);
231 }
232 }
233 return ct;
234 }
235
237 public Constraint addLinearConstraint(LinearArgument expr, long lb, long ub) {
238 return addLinearExpressionInDomain(expr, new Domain(lb, ub));
239 }
240
242 public Constraint addEquality(LinearArgument expr, long value) {
243 return addLinearExpressionInDomain(expr, new Domain(value));
244 }
245
249 difference.addTerm(left, 1);
250 difference.addTerm(right, -1);
251 return addLinearExpressionInDomain(difference, new Domain(0));
252 }
253
255 public Constraint addLessOrEqual(LinearArgument expr, long value) {
256 return addLinearExpressionInDomain(expr, new Domain(Long.MIN_VALUE, value));
257 }
258
262 difference.addTerm(left, 1);
263 difference.addTerm(right, -1);
264 return addLinearExpressionInDomain(difference, new Domain(Long.MIN_VALUE, 0));
265 }
266
268 public Constraint addLessThan(LinearArgument expr, long value) {
269 return addLinearExpressionInDomain(expr, new Domain(Long.MIN_VALUE, value - 1));
270 }
271
275 difference.addTerm(left, 1);
276 difference.addTerm(right, -1);
277 return addLinearExpressionInDomain(difference, new Domain(Long.MIN_VALUE, -1));
278 }
279
281 public Constraint addGreaterOrEqual(LinearArgument expr, long value) {
282 return addLinearExpressionInDomain(expr, new Domain(value, Long.MAX_VALUE));
283 }
284
288 difference.addTerm(left, 1);
289 difference.addTerm(right, -1);
290 return addLinearExpressionInDomain(difference, new Domain(0, Long.MAX_VALUE));
291 }
292
294 public Constraint addGreaterThan(LinearArgument expr, long value) {
295 return addLinearExpressionInDomain(expr, new Domain(value + 1, Long.MAX_VALUE));
296 }
297
301 difference.addTerm(left, 1);
302 difference.addTerm(right, -1);
303 return addLinearExpressionInDomain(difference, new Domain(1, Long.MAX_VALUE));
304 }
305
307 public Constraint addDifferent(LinearArgument expr, long value) {
308 return addLinearExpressionInDomain(expr,
309 Domain.fromFlatIntervals(
310 new long[] {Long.MIN_VALUE, value - 1, value + 1, Long.MAX_VALUE}));
311 }
312
316 difference.addTerm(left, 1);
317 difference.addTerm(right, -1);
319 difference, Domain.fromFlatIntervals(new long[] {Long.MIN_VALUE, -1, 1, Long.MAX_VALUE}));
320 }
321
322 // Integer constraints.
323
333 return addAllDifferent(Arrays.asList(expressions));
334 }
335
341 public Constraint addAllDifferent(Iterable<? extends LinearArgument> expressions) {
342 Constraint ct = new Constraint(modelBuilder);
343 AllDifferentConstraintProto.Builder allDiff = ct.getBuilder().getAllDiffBuilder();
344 for (LinearArgument expr : expressions) {
345 allDiff.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/false));
346 }
347 return ct;
348 }
349
351 public Constraint addElement(IntVar index, IntVar[] variables, IntVar target) {
352 Constraint ct = new Constraint(modelBuilder);
353 ElementConstraintProto.Builder element =
354 ct.getBuilder().getElementBuilder().setIndex(index.getIndex());
355 for (IntVar var : variables) {
356 element.addVars(var.getIndex());
357 }
358 element.setTarget(target.getIndex());
359 return ct;
360 }
361
363 public Constraint addElement(IntVar index, long[] values, IntVar target) {
364 Constraint ct = new Constraint(modelBuilder);
365 ElementConstraintProto.Builder element =
366 ct.getBuilder().getElementBuilder().setIndex(index.getIndex());
367 for (long v : values) {
368 element.addVars(newConstant(v).getIndex());
369 }
370 element.setTarget(target.getIndex());
371 return ct;
372 }
373
375 public Constraint addElement(IntVar index, int[] values, IntVar target) {
376 Constraint ct = new Constraint(modelBuilder);
377 ElementConstraintProto.Builder element =
378 ct.getBuilder().getElementBuilder().setIndex(index.getIndex());
379 for (long v : values) {
380 element.addVars(newConstant(v).getIndex());
381 }
382 element.setTarget(target.getIndex());
383 return ct;
384 }
385
396 return new CircuitConstraint(modelBuilder);
397 }
398
410 return new MultipleCircuitConstraint(modelBuilder);
411 }
412
425 return addAllowedAssignments(Arrays.asList(variables));
426 }
427
433 public TableConstraint addAllowedAssignments(Iterable<IntVar> variables) {
434 TableConstraint ct = new TableConstraint(modelBuilder);
435 TableConstraintProto.Builder table = ct.getBuilder().getTableBuilder();
436 for (IntVar var : variables) {
437 table.addVars(var.getIndex());
438 }
439 table.setNegated(false);
440 return ct;
441 }
442
454 return addForbiddenAssignments(Arrays.asList(variables));
455 }
456
462 public TableConstraint addForbiddenAssignments(Iterable<IntVar> variables) {
463 TableConstraint ct = new TableConstraint(modelBuilder);
464 TableConstraintProto.Builder table = ct.getBuilder().getTableBuilder();
465 for (IntVar var : variables) {
466 table.addVars(var.getIndex());
467 }
468 table.setNegated(true);
469 return ct;
470 }
471
502 IntVar[] transitionVariables, long startingState, long[] finalStates) {
503 AutomatonConstraint ct = new AutomatonConstraint(modelBuilder);
504 AutomatonConstraintProto.Builder automaton = ct.getBuilder().getAutomatonBuilder();
505 for (IntVar var : transitionVariables) {
506 automaton.addVars(var.getIndex());
507 }
508 automaton.setStartingState(startingState);
509 for (long c : finalStates) {
510 automaton.addFinalStates(c);
511 }
512 return ct;
513 }
514
526 public Constraint addInverse(IntVar[] variables, IntVar[] inverseVariables) {
527 if (variables.length != inverseVariables.length) {
528 throw new MismatchedArrayLengths("CpModel.addInverse", "variables", "inverseVariables");
529 }
530 Constraint ct = new Constraint(modelBuilder);
531 InverseConstraintProto.Builder inverse = ct.getBuilder().getInverseBuilder();
532 for (IntVar var : variables) {
533 inverse.addFDirect(var.getIndex());
534 }
535 for (IntVar var : inverseVariables) {
536 inverse.addFInverse(var.getIndex());
537 }
538 return ct;
539 }
540
564 public ReservoirConstraint addReservoirConstraint(long minLevel, long maxLevel) {
565 if (minLevel > 0) {
566 throw new IllegalArgumentException("CpModel.addReservoirConstraint: minLevel must be <= 0");
567 }
568 if (maxLevel < 0) {
569 throw new IllegalArgumentException("CpModel.addReservoirConstraint: maxLevel must be >= 0");
570 }
572 ReservoirConstraintProto.Builder reservoir = ct.getBuilder().getReservoirBuilder();
573 reservoir.setMinLevel(minLevel).setMaxLevel(maxLevel);
574 return ct;
575 }
576
578 public void addMapDomain(IntVar var, Literal[] booleans, long offset) {
579 for (int i = 0; i < booleans.length; ++i) {
580 addEquality(var, offset + i).onlyEnforceIf(booleans[i]);
581 addDifferent(var, offset + i).onlyEnforceIf(booleans[i].not());
582 }
583 }
584
587 Constraint ct = new Constraint(modelBuilder);
588 LinearArgumentProto.Builder linMax = ct.getBuilder().getLinMaxBuilder();
589 linMax.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/true));
590 for (LinearArgument expr : exprs) {
591 linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/true));
592 }
593 return ct;
594 }
595
598 LinearArgument target, Iterable<? extends LinearArgument> exprs) {
599 Constraint ct = new Constraint(modelBuilder);
600 LinearArgumentProto.Builder linMax = ct.getBuilder().getLinMaxBuilder();
601 linMax.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/true));
602 for (LinearArgument expr : exprs) {
603 linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/true));
604 }
605 return ct;
606 }
607
610 Constraint ct = new Constraint(modelBuilder);
611 LinearArgumentProto.Builder linMax = ct.getBuilder().getLinMaxBuilder();
612 linMax.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false));
613 for (LinearArgument expr : exprs) {
614 linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/false));
615 }
616 return ct;
617 }
618
621 LinearArgument target, Iterable<? extends LinearArgument> exprs) {
622 Constraint ct = new Constraint(modelBuilder);
623 LinearArgumentProto.Builder linMax = ct.getBuilder().getLinMaxBuilder();
624 linMax.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false));
625 for (LinearArgument expr : exprs) {
626 linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/false));
627 }
628 return ct;
629 }
630
633 LinearArgument target, LinearArgument num, LinearArgument denom) {
634 Constraint ct = new Constraint(modelBuilder);
635 ct.getBuilder()
636 .getIntDivBuilder()
637 .setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false))
638 .addExprs(getLinearExpressionProtoBuilderFromLinearArgument(num, /*negate=*/false))
639 .addExprs(getLinearExpressionProtoBuilderFromLinearArgument(denom, /*negate=*/false));
640 return ct;
641 }
642
645 Constraint ct = new Constraint(modelBuilder);
646 LinearArgumentProto.Builder linMax = ct.getBuilder().getLinMaxBuilder();
647 linMax.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false));
648 linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/false));
649 linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/true));
650 return ct;
651 }
652
656 Constraint ct = new Constraint(modelBuilder);
657 ct.getBuilder()
658 .getIntModBuilder()
659 .setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false))
660 .addExprs(getLinearExpressionProtoBuilderFromLinearArgument(var, /*negate=*/false))
661 .addExprs(getLinearExpressionProtoBuilderFromLinearArgument(mod, /*negate=*/false));
662 return ct;
663 }
664
667 Constraint ct = new Constraint(modelBuilder);
668 ct.getBuilder()
669 .getIntModBuilder()
670 .setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false))
671 .addExprs(getLinearExpressionProtoBuilderFromLinearArgument(var, /*negate=*/false))
672 .addExprs(getLinearExpressionProtoBuilderFromLong(mod));
673 return ct;
674 }
675
678 Constraint ct = new Constraint(modelBuilder);
679 LinearArgumentProto.Builder intProd = ct.getBuilder().getIntProdBuilder();
680 intProd.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false));
681 for (LinearArgument expr : exprs) {
682 intProd.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/false));
683 }
684 return ct;
685 }
686
689 LinearArgument target, LinearArgument left, LinearArgument right) {
690 Constraint ct = new Constraint(modelBuilder);
691 LinearArgumentProto.Builder intProd = ct.getBuilder().getIntProdBuilder();
692 intProd.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false));
693 intProd.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(left, /*negate=*/false));
694 intProd.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(right, /*negate=*/false));
695 return ct;
696 }
697
698 // Scheduling support.
699
715 LinearArgument start, LinearArgument size, LinearArgument end, String name) {
716 addEquality(LinearExpr.newBuilder().add(start).add(size), end);
717 return new IntervalVar(modelBuilder,
718 getLinearExpressionProtoBuilderFromLinearArgument(start, /*negate=*/false),
719 getLinearExpressionProtoBuilderFromLinearArgument(size, /*negate=*/false),
720 getLinearExpressionProtoBuilderFromLinearArgument(end, /*negate=*/false), name);
721 }
722
734 public IntervalVar newFixedSizeIntervalVar(LinearArgument start, long size, String name) {
735 return new IntervalVar(modelBuilder,
736 getLinearExpressionProtoBuilderFromLinearArgument(start, /*negate=*/false),
737 getLinearExpressionProtoBuilderFromLong(size),
738 getLinearExpressionProtoBuilderFromLinearArgument(
739 LinearExpr.newBuilder().add(start).add(size), /*negate=*/false),
740 name);
741 }
742
744 public IntervalVar newFixedInterval(long start, long size, String name) {
745 return new IntervalVar(modelBuilder, getLinearExpressionProtoBuilderFromLong(start),
746 getLinearExpressionProtoBuilderFromLong(size),
747 getLinearExpressionProtoBuilderFromLong(start + size), name);
748 }
749
769 LinearArgument end, Literal isPresent, String name) {
770 addEquality(LinearExpr.newBuilder().add(start).add(size), end).onlyEnforceIf(isPresent);
771 return new IntervalVar(modelBuilder,
772 getLinearExpressionProtoBuilderFromLinearArgument(start, /*negate=*/false),
773 getLinearExpressionProtoBuilderFromLinearArgument(size, /*negate=*/false),
774 getLinearExpressionProtoBuilderFromLinearArgument(end, /*negate=*/false),
775 isPresent.getIndex(), name);
776 }
777
792 LinearArgument start, long size, Literal isPresent, String name) {
793 return new IntervalVar(modelBuilder,
794 getLinearExpressionProtoBuilderFromLinearArgument(start, /*negate=*/false),
795 getLinearExpressionProtoBuilderFromLong(size),
796 getLinearExpressionProtoBuilderFromLinearArgument(
797 LinearExpr.newBuilder().add(start).add(size), /*negate=*/false),
798 isPresent.getIndex(), name);
799 }
800
803 long start, long size, Literal isPresent, String name) {
804 return new IntervalVar(modelBuilder, getLinearExpressionProtoBuilderFromLong(start),
805 getLinearExpressionProtoBuilderFromLong(size),
806 getLinearExpressionProtoBuilderFromLong(start + size), isPresent.getIndex(), name);
807 }
808
817 public Constraint addNoOverlap(IntervalVar[] intervalVars) {
818 return addNoOverlap(Arrays.asList(intervalVars));
819 }
820
826 public Constraint addNoOverlap(Iterable<IntervalVar> intervalVars) {
827 Constraint ct = new Constraint(modelBuilder);
828 NoOverlapConstraintProto.Builder noOverlap = ct.getBuilder().getNoOverlapBuilder();
829 for (IntervalVar var : intervalVars) {
830 noOverlap.addIntervals(var.getIndex());
831 }
832 return ct;
833 }
834
848 return new NoOverlap2dConstraint(modelBuilder);
849 }
850
866 CumulativeConstraintProto.Builder cumul = ct.getBuilder().getCumulativeBuilder();
867 cumul.setCapacity(getLinearExpressionProtoBuilderFromLinearArgument(capacity, false));
868 return ct;
869 }
870
876 public CumulativeConstraint addCumulative(long capacity) {
878 CumulativeConstraintProto.Builder cumul = ct.getBuilder().getCumulativeBuilder();
879 cumul.setCapacity(getLinearExpressionProtoBuilderFromLong(capacity));
880 return ct;
881 }
882
884 public void addHint(IntVar var, long value) {
885 modelBuilder.getSolutionHintBuilder().addVars(var.getIndex());
886 modelBuilder.getSolutionHintBuilder().addValues(value);
887 }
888
890 public void clearHints() {
891 modelBuilder.clearSolutionHint();
892 }
893
895 public void addAssumption(Literal lit) {
896 modelBuilder.addAssumptions(lit.getIndex());
897 }
898
900 public void addAssumptions(Literal[] literals) {
901 for (Literal lit : literals) {
902 addAssumption(lit);
903 }
904 }
905
907 public void clearAssumptions() {
908 modelBuilder.clearAssumptions();
909 }
910
911 // Objective.
912
914 public void minimize(LinearArgument expr) {
915 modelBuilder.clearObjective();
916 modelBuilder.clearFloatingPointObjective();
917 CpObjectiveProto.Builder obj = modelBuilder.getObjectiveBuilder();
918 final LinearExpr e = expr.build();
919 for (int i = 0; i < e.numElements(); ++i) {
920 obj.addVars(e.getVariableIndex(i)).addCoeffs(e.getCoefficient(i));
921 }
922 obj.setOffset(e.getOffset());
923 }
924
925 public void minimize(DoubleLinearExpr expr) {
926 modelBuilder.clearObjective();
927 modelBuilder.clearFloatingPointObjective();
928 FloatObjectiveProto.Builder obj = modelBuilder.getFloatingPointObjectiveBuilder();
929 for (int i = 0; i < expr.numElements(); ++i) {
930 obj.addVars(expr.getVariableIndex(i)).addCoeffs(expr.getCoefficient(i));
931 }
932 obj.setOffset(expr.getOffset()).setMaximize(false);
933 }
934
936 public void maximize(LinearArgument expr) {
937 modelBuilder.clearObjective();
938 modelBuilder.clearFloatingPointObjective();
939 CpObjectiveProto.Builder obj = modelBuilder.getObjectiveBuilder();
940 final LinearExpr e = expr.build();
941 for (int i = 0; i < e.numElements(); ++i) {
942 obj.addVars(e.getVariableIndex(i)).addCoeffs(-e.getCoefficient(i));
943 }
944 obj.setOffset(-e.getOffset());
945 obj.setScalingFactor(-1.0);
946 }
947
948 public void maximize(DoubleLinearExpr expr) {
949 modelBuilder.clearObjective();
950 modelBuilder.clearFloatingPointObjective();
951 FloatObjectiveProto.Builder obj = modelBuilder.getFloatingPointObjectiveBuilder();
952 for (int i = 0; i < expr.numElements(); ++i) {
953 obj.addVars(expr.getVariableIndex(i)).addCoeffs(expr.getCoefficient(i));
954 }
955 obj.setOffset(expr.getOffset()).setMaximize(true);
956 }
957
958 // DecisionStrategy
959
961 public void addDecisionStrategy(IntVar[] variables,
962 DecisionStrategyProto.VariableSelectionStrategy varStr,
963 DecisionStrategyProto.DomainReductionStrategy domStr) {
964 DecisionStrategyProto.Builder ds = modelBuilder.addSearchStrategyBuilder();
965 for (IntVar var : variables) {
966 ds.addVariables(var.getIndex());
967 }
968 ds.setVariableSelectionStrategy(varStr).setDomainReductionStrategy(domStr);
969 }
970
972 public String modelStats() {
973 return CpSatHelper.modelStats(model());
974 }
975
977 public String validate() {
978 return CpSatHelper.validateModel(model());
979 }
980
989 public Boolean exportToFile(String file) {
990 return CpSatHelper.writeModelToFile(model(), file);
991 }
992
993 // Helpers
994 LinearExpressionProto.Builder getLinearExpressionProtoBuilderFromLinearArgument(
995 LinearArgument arg, boolean negate) {
996 LinearExpressionProto.Builder builder = LinearExpressionProto.newBuilder();
997 final LinearExpr expr = arg.build();
998 final int numVariables = expr.numElements();
999 final long mult = negate ? -1 : 1;
1000 for (int i = 0; i < numVariables; ++i) {
1001 builder.addVars(expr.getVariableIndex(i));
1002 builder.addCoeffs(expr.getCoefficient(i) * mult);
1003 }
1004 builder.setOffset(expr.getOffset() * mult);
1005 return builder;
1006 }
1007
1008 LinearExpressionProto.Builder getLinearExpressionProtoBuilderFromLong(long value) {
1009 LinearExpressionProto.Builder builder = LinearExpressionProto.newBuilder();
1010 builder.setOffset(value);
1011 return builder;
1012 }
1013
1014 // Getters.
1015
1016 public CpModelProto model() {
1017 return modelBuilder.build();
1018 }
1019
1020 public int negated(int index) {
1021 return -index - 1;
1022 }
1023
1025 public CpModelProto.Builder getBuilder() {
1026 return modelBuilder;
1027 }
1028
1029 private final CpModelProto.Builder modelBuilder;
1030 private final Map<Long, Integer> constantMap;
1031}
An Boolean variable.
Definition: BoolVar.java:20
Wrapper around a ConstraintProto.
Definition: Constraint.java:25
ConstraintProto.Builder getBuilder()
Returns the constraint builder.
Definition: Constraint.java:49
void onlyEnforceIf(Literal lit)
Adds a literal to the constraint.
Definition: Constraint.java:32
Exception thrown when parallel arrays have mismatched lengths.
Definition: CpModel.java:52
MismatchedArrayLengths(String methodName, String array1Name, String array2Name)
Definition: CpModel.java:53
Exception thrown when an array has a wrong length.
Definition: CpModel.java:59
WrongLength(String methodName, String msg)
Definition: CpModel.java:60
Main modeling class.
Definition: CpModel.java:43
Constraint addLessThan(LinearArgument expr, long value)
Adds expr < value.
Definition: CpModel.java:268
Constraint addLinearExpressionInDomain(LinearArgument expr, Domain domain)
Adds expr in domain.
Definition: CpModel.java:218
Constraint addEquality(LinearArgument expr, long value)
Adds expr == value.
Definition: CpModel.java:242
CumulativeConstraint addCumulative(LinearArgument capacity)
Adds Cumulative(capacity).
Definition: CpModel.java:864
IntervalVar newOptionalFixedSizeIntervalVar(LinearArgument start, long size, Literal isPresent, String name)
Creates an optional interval variable from an affine expression start, and a fixed size.
Definition: CpModel.java:791
IntVar newConstant(long value)
Creates a constant variable.
Definition: CpModel.java:94
NoOverlap2dConstraint addNoOverlap2D()
Adds NoOverlap2D(xIntervals, yIntervals).
Definition: CpModel.java:847
Constraint addAbsEquality(LinearArgument target, LinearArgument expr)
Adds target == Abs(expr).
Definition: CpModel.java:644
ReservoirConstraint addReservoirConstraint(long minLevel, long maxLevel)
Adds a reservoir constraint with optional refill/emptying events.
Definition: CpModel.java:564
void clearAssumptions()
Remove all assumptions from the model.
Definition: CpModel.java:907
Constraint addLessOrEqual(LinearArgument left, LinearArgument right)
Adds left <= right.
Definition: CpModel.java:260
TableConstraint addForbiddenAssignments(Iterable< IntVar > variables)
Adds ForbiddenAssignments(variables).
Definition: CpModel.java:462
Constraint addMultiplicationEquality(LinearArgument target, LinearArgument[] exprs)
Adds target == Product(exprs).
Definition: CpModel.java:677
Constraint addMaxEquality(LinearArgument target, Iterable<? extends LinearArgument > exprs)
Adds target == Max(exprs).
Definition: CpModel.java:620
Constraint addAllDifferent(Iterable<? extends LinearArgument > expressions)
Adds AllDifferent(expressions).
Definition: CpModel.java:341
void maximize(DoubleLinearExpr expr)
Definition: CpModel.java:948
CumulativeConstraint addCumulative(long capacity)
Adds Cumulative(capacity).
Definition: CpModel.java:876
Boolean exportToFile(String file)
Write the model as a protocol buffer to 'file'.
Definition: CpModel.java:989
BoolVar newBoolVar(String name)
Creates a Boolean variable with the given name.
Definition: CpModel.java:89
TableConstraint addAllowedAssignments(IntVar[] variables)
Adds AllowedAssignments(variables).
Definition: CpModel.java:424
IntervalVar newOptionalFixedInterval(long start, long size, Literal isPresent, String name)
Creates an optional fixed interval from start and size, and an isPresent literal.
Definition: CpModel.java:802
Constraint addElement(IntVar index, long[] values, IntVar target)
Adds the element constraint: values[index] == target.
Definition: CpModel.java:363
Constraint addBoolXor(Iterable< Literal > literals)
Adds XOr(literals) == true.
Definition: CpModel.java:201
CircuitConstraint addCircuit()
Adds Circuit().
Definition: CpModel.java:395
Literal falseLiteral()
Returns the false literal.
Definition: CpModel.java:114
void addAssumptions(Literal[] literals)
Adds multiple literals to the model as assumptions.
Definition: CpModel.java:900
Constraint addExactlyOne(Literal[] literals)
Adds ExactlyOne(literals): Sum(literals) == 1.
Definition: CpModel.java:166
Constraint addAtLeastOne(Literal[] literals)
Same as addBoolOr.
Definition: CpModel.java:141
void maximize(LinearArgument expr)
Adds a maximization objective of a linear expression.
Definition: CpModel.java:936
Constraint addGreaterThan(LinearArgument left, LinearArgument right)
Adds left > right.
Definition: CpModel.java:299
TableConstraint addAllowedAssignments(Iterable< IntVar > variables)
Adds AllowedAssignments(variables).
Definition: CpModel.java:433
void addAssumption(Literal lit)
Adds a literal to the model as assumption.
Definition: CpModel.java:895
IntervalVar newFixedSizeIntervalVar(LinearArgument start, long size, String name)
Creates an interval variable from an affine expression start, and a fixed size.
Definition: CpModel.java:734
void addHint(IntVar var, long value)
Adds hinting to a variable.
Definition: CpModel.java:884
IntervalVar newFixedInterval(long start, long size, String name)
Creates a fixed interval from its start and its size.
Definition: CpModel.java:744
Constraint addAtMostOne(Literal[] literals)
Adds AtMostOne(literals): Sum(literals) <= 1.
Definition: CpModel.java:151
Constraint addLessThan(LinearArgument left, LinearArgument right)
Adds left < right.
Definition: CpModel.java:273
Constraint addDivisionEquality(LinearArgument target, LinearArgument num, LinearArgument denom)
Adds target == num / denom, rounded towards 0.
Definition: CpModel.java:632
String modelStats()
Returns some statistics on model as a string.
Definition: CpModel.java:972
Constraint addElement(IntVar index, IntVar[] variables, IntVar target)
Adds the element constraint: variables[index] == target.
Definition: CpModel.java:351
IntervalVar newIntervalVar(LinearArgument start, LinearArgument size, LinearArgument end, String name)
Creates an interval variable from three affine expressions start, size, and end.
Definition: CpModel.java:714
Constraint addNoOverlap(Iterable< IntervalVar > intervalVars)
Adds NoOverlap(intervalVars).
Definition: CpModel.java:826
Constraint addGreaterThan(LinearArgument expr, long value)
Adds expr > value.
Definition: CpModel.java:294
Constraint addAtMostOne(Iterable< Literal > literals)
Adds AtMostOne(literals): Sum(literals) <= 1.
Definition: CpModel.java:156
Constraint addBoolOr(Iterable< Literal > literals)
Adds Or(literals) == true.
Definition: CpModel.java:131
Constraint addImplication(Literal a, Literal b)
Adds a => b.
Definition: CpModel.java:211
Constraint addBoolXor(Literal[] literals)
Adds XOr(literals) == true.
Definition: CpModel.java:196
Constraint addMaxEquality(LinearArgument target, LinearArgument[] exprs)
Adds target == Max(vars).
Definition: CpModel.java:609
Constraint addGreaterOrEqual(LinearArgument expr, long value)
Adds expr >= value.
Definition: CpModel.java:281
void minimize(DoubleLinearExpr expr)
Definition: CpModel.java:925
IntVar newIntVar(long lb, long ub, String name)
Creates an integer variable with domain [lb, ub].
Definition: CpModel.java:73
IntervalVar newOptionalIntervalVar(LinearArgument start, LinearArgument size, LinearArgument end, Literal isPresent, String name)
Creates an optional interval variable from three affine expressions start, size, end,...
Definition: CpModel.java:768
MultipleCircuitConstraint addMultipleCircuit()
Adds MultipleCircuit().
Definition: CpModel.java:409
Constraint addDifferent(LinearArgument expr, long value)
Adds expr != value.
Definition: CpModel.java:307
Constraint addDifferent(LinearArgument left, LinearArgument right)
Adds left != right.
Definition: CpModel.java:314
AutomatonConstraint addAutomaton(IntVar[] transitionVariables, long startingState, long[] finalStates)
Adds an automaton constraint.
Definition: CpModel.java:501
void addMapDomain(IntVar var, Literal[] booleans, long offset)
Adds var == i + offset <=> booleans[i] == true for all i in [0, booleans.length).
Definition: CpModel.java:578
void addDecisionStrategy(IntVar[] variables, DecisionStrategyProto.VariableSelectionStrategy varStr, DecisionStrategyProto.DomainReductionStrategy domStr)
Adds DecisionStrategy(variables, varStr, domStr).
Definition: CpModel.java:961
Constraint addInverse(IntVar[] variables, IntVar[] inverseVariables)
Adds Inverse(variables, inverseVariables).
Definition: CpModel.java:526
Constraint addModuloEquality(LinearArgument target, LinearArgument var, LinearArgument mod)
Adds target == var % mod.
Definition: CpModel.java:654
Constraint addNoOverlap(IntervalVar[] intervalVars)
Adds NoOverlap(intervalVars).
Definition: CpModel.java:817
Literal trueLiteral()
Returns the true literal.
Definition: CpModel.java:104
Constraint addElement(IntVar index, int[] values, IntVar target)
Adds the element constraint: values[index] == target.
Definition: CpModel.java:375
Constraint addLessOrEqual(LinearArgument expr, long value)
Adds expr <= value.
Definition: CpModel.java:255
void clearHints()
Remove all solution hints.
Definition: CpModel.java:890
Constraint addEquality(LinearArgument left, LinearArgument right)
Adds left == right.
Definition: CpModel.java:247
String validate()
Returns a non empty string explaining the issue if the model is invalid.
Definition: CpModel.java:977
void minimize(LinearArgument expr)
Adds a minimization objective of a linear expression.
Definition: CpModel.java:914
Constraint addMultiplicationEquality(LinearArgument target, LinearArgument left, LinearArgument right)
Adds target == left * right.
Definition: CpModel.java:688
Constraint addBoolOr(Literal[] literals)
Adds Or(literals) == true.
Definition: CpModel.java:126
Constraint addExactlyOne(Iterable< Literal > literals)
Adds ExactlyOne(literals): Sum(literals) == 1.
Definition: CpModel.java:171
IntVar newIntVarFromDomain(Domain domain, String name)
Creates an integer variable with given domain.
Definition: CpModel.java:84
Constraint addModuloEquality(LinearArgument target, LinearArgument var, long mod)
Adds target == var % mod.
Definition: CpModel.java:666
Constraint addLinearConstraint(LinearArgument expr, long lb, long ub)
Adds lb <= expr <= ub.
Definition: CpModel.java:237
Constraint addBoolAnd(Iterable< Literal > literals)
Adds And(literals) == true.
Definition: CpModel.java:186
Constraint addBoolAnd(Literal[] literals)
Adds And(literals) == true.
Definition: CpModel.java:181
TableConstraint addForbiddenAssignments(IntVar[] variables)
Adds ForbiddenAssignments(variables).
Definition: CpModel.java:453
Constraint addAtLeastOne(Iterable< Literal > literals)
Same as addBoolOr.
Definition: CpModel.java:146
Constraint addMinEquality(LinearArgument target, Iterable<? extends LinearArgument > exprs)
Adds target == Min(exprs).
Definition: CpModel.java:597
Constraint addAllDifferent(LinearArgument[] expressions)
Adds AllDifferent(expressions).
Definition: CpModel.java:332
CpModelProto.Builder getBuilder()
Returns the model builder.
Definition: CpModel.java:1025
Constraint addGreaterOrEqual(LinearArgument left, LinearArgument right)
Adds left >= right.
Definition: CpModel.java:286
Constraint addMinEquality(LinearArgument target, LinearArgument[] exprs)
Adds target == Min(vars).
Definition: CpModel.java:586
A linear expression interface that can be parsed.
int numElements()
Returns the number of elements in the interface.
double getCoefficient(int index)
Returns the ith coefficient.
double getOffset()
Returns the constant part of the expression.
int getVariableIndex(int index)
Returns the ith variable.
An integer variable.
Definition: IntVar.java:21
int getIndex()
Returns the index of the variable in the underlying CpModelProto.
Definition: IntVar.java:44
Builder class for the LinearExpr container.
LinearExprBuilder add(LinearArgument expr)
LinearExprBuilder addTerm(LinearArgument expr, long coeff)
Specialized assignment constraint.
A object that can build a LinearExpr object.
LinearExpr build()
Builds a linear expression.
A linear expression (sum (ai * xi) + b).
Definition: LinearExpr.java:19
long getCoefficient(int index)
Returns the ith coefficient.
int numElements()
Returns the number of terms (excluding the constant one) in this expression.
static LinearExprBuilder newBuilder()
Returns a builder.
Definition: LinearExpr.java:33
long getOffset()
Returns the constant part of the expression.
int getVariableIndex(int index)
Returns the index of the ith variable.
Interface to describe a boolean variable or its negation.
Definition: Literal.java:17
Literal not()
Returns the Boolean negation of the current literal.