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.CircuitConstraintProto;
20import com.google.ortools.sat.CpModelProto;
21import com.google.ortools.sat.CpObjectiveProto;
22import com.google.ortools.sat.CumulativeConstraintProto;
23import com.google.ortools.sat.DecisionStrategyProto;
24import com.google.ortools.sat.ElementConstraintProto;
25import com.google.ortools.sat.IntegerArgumentProto;
26import com.google.ortools.sat.InverseConstraintProto;
27import com.google.ortools.sat.LinearConstraintProto;
28import com.google.ortools.sat.LinearExpressionProto;
29import com.google.ortools.sat.NoOverlap2DConstraintProto;
30import com.google.ortools.sat.NoOverlapConstraintProto;
31import com.google.ortools.sat.ReservoirConstraintProto;
32import com.google.ortools.sat.TableConstraintProto;
33import com.google.ortools.util.Domain;
34import java.util.LinkedHashMap;
35import java.util.Map;
36
42public final class CpModel {
43 static class CpModelException extends RuntimeException {
44 public CpModelException(String methodName, String msg) {
45 // Call constructor of parent Exception
46 super(methodName + ": " + msg);
47 }
48 }
49
51 public static class MismatchedArrayLengths extends CpModelException {
52 public MismatchedArrayLengths(String methodName, String array1Name, String array2Name) {
53 super(methodName, array1Name + " and " + array2Name + " have mismatched lengths");
54 }
55 }
56
58 public static class WrongLength extends CpModelException {
59 public WrongLength(String methodName, String msg) {
60 super(methodName, msg);
61 }
62 }
63 public CpModel() {
64 modelBuilder = CpModelProto.newBuilder();
65 constantMap = new LinkedHashMap<>();
66 }
67
68 // Integer variables.
69
71 public IntVar newIntVar(long lb, long ub, String name) {
72 return new IntVar(modelBuilder, new Domain(lb, ub), name);
73 }
74
82 public IntVar newIntVarFromDomain(Domain domain, String name) {
83 return new IntVar(modelBuilder, domain, name);
84 }
85
87 public IntVar newBoolVar(String name) {
88 return new IntVar(modelBuilder, new Domain(0, 1), name);
89 }
90
92 public IntVar newConstant(long value) {
93 if (constantMap.containsKey(value)) {
94 return constantMap.get(value);
95 }
96 IntVar cste = new IntVar(modelBuilder, new Domain(value), ""); // bounds and name.
97 constantMap.put(value, cste);
98 return cste;
99 }
100
103 return newConstant(1);
104 }
105
108 return newConstant(0);
109 }
110
111 // Boolean Constraints.
112
114 public Constraint addBoolOr(Literal[] literals) {
115 Constraint ct = new Constraint(modelBuilder);
116 BoolArgumentProto.Builder boolOr = ct.getBuilder().getBoolOrBuilder();
117 for (Literal lit : literals) {
118 boolOr.addLiterals(lit.getIndex());
119 }
120 return ct;
121 }
122
124 public Constraint addBoolAnd(Literal[] literals) {
125 Constraint ct = new Constraint(modelBuilder);
126 BoolArgumentProto.Builder boolOr = ct.getBuilder().getBoolAndBuilder();
127 for (Literal lit : literals) {
128 boolOr.addLiterals(lit.getIndex());
129 }
130 return ct;
131 }
132
134 public Constraint addBoolXor(Literal[] literals) {
135 Constraint ct = new Constraint(modelBuilder);
136 BoolArgumentProto.Builder boolOr = ct.getBuilder().getBoolXorBuilder();
137 for (Literal lit : literals) {
138 boolOr.addLiterals(lit.getIndex());
139 }
140 return ct;
141 }
142
145 return addBoolOr(new Literal[] {a.not(), b});
146 }
147
148 // Linear constraints.
149
152 Constraint ct = new Constraint(modelBuilder);
153 LinearConstraintProto.Builder lin = ct.getBuilder().getLinearBuilder();
154 for (int i = 0; i < expr.numElements(); ++i) {
155 lin.addVars(expr.getVariable(i).getIndex()).addCoeffs(expr.getCoefficient(i));
156 }
157 long offset = expr.getOffset();
158 if (offset != 0) {
159 lin.addVars(newConstant(1).getIndex()).addCoeffs(offset);
160 }
161 for (long b : domain.flattenedIntervals()) {
162 lin.addDomain(b);
163 }
164 return ct;
165 }
166
168 public Constraint addLinearConstraint(LinearExpr expr, long lb, long ub) {
169 return addLinearExpressionInDomain(expr, new Domain(lb, ub));
170 }
171
173 public Constraint addEquality(LinearExpr expr, long value) {
174 return addLinearExpressionInDomain(expr, new Domain(value));
175 }
176
179 return addLinearExpressionInDomain(new Difference(left, right), new Domain(0));
180 }
181
183 public Constraint addEqualityWithOffset(LinearExpr left, LinearExpr right, long offset) {
184 return addLinearExpressionInDomain(new Difference(left, right), new Domain(-offset));
185 }
186
188 public Constraint addLessOrEqual(LinearExpr expr, long value) {
189 return addLinearExpressionInDomain(expr, new Domain(Long.MIN_VALUE, value));
190 }
191
194 return addLinearExpressionInDomain(new Difference(left, right), new Domain(Long.MIN_VALUE, 0));
195 }
196
198 public Constraint addLessThan(LinearExpr expr, long value) {
199 return addLinearExpressionInDomain(expr, new Domain(Long.MIN_VALUE, value - 1));
200 }
201
204 return addLinearExpressionInDomain(new Difference(left, right), new Domain(Long.MIN_VALUE, -1));
205 }
206
208 public Constraint addLessOrEqualWithOffset(LinearExpr left, LinearExpr right, long offset) {
210 new Difference(left, right), new Domain(Long.MIN_VALUE, -offset));
211 }
212
214 public Constraint addGreaterOrEqual(LinearExpr expr, long value) {
215 return addLinearExpressionInDomain(expr, new Domain(value, Long.MAX_VALUE));
216 }
217
220 return addLinearExpressionInDomain(new Difference(left, right), new Domain(0, Long.MAX_VALUE));
221 }
222
224 public Constraint addGreaterThan(LinearExpr expr, long value) {
225 return addLinearExpressionInDomain(expr, new Domain(value + 1, Long.MAX_VALUE));
226 }
227
230 return addLinearExpressionInDomain(new Difference(left, right), new Domain(1, Long.MAX_VALUE));
231 }
232
236 new Difference(left, right), new Domain(-offset, Long.MAX_VALUE));
237 }
238
240 public Constraint addDifferent(LinearExpr expr, long value) {
241 return addLinearExpressionInDomain(expr,
243 new long[] {Long.MIN_VALUE, value - 1, value + 1, Long.MAX_VALUE}));
244 }
245
248 return addLinearExpressionInDomain(new Difference(left, right),
249 Domain.fromFlatIntervals(new long[] {Long.MIN_VALUE, -1, 1, Long.MAX_VALUE}));
250 }
251
253 public Constraint addDifferentWithOffset(LinearExpr left, LinearExpr right, long offset) {
254 return addLinearExpressionInDomain(new Difference(left, right),
256 new long[] {Long.MIN_VALUE, -offset - 1, -offset + 1, Long.MAX_VALUE}));
257 }
258
259 // Integer constraints.
260
269 public Constraint addAllDifferent(IntVar[] variables) {
270 Constraint ct = new Constraint(modelBuilder);
271 AllDifferentConstraintProto.Builder allDiff = ct.getBuilder().getAllDiffBuilder();
272 for (IntVar var : variables) {
273 allDiff.addVars(var.getIndex());
274 }
275 return ct;
276 }
277
279 public Constraint addElement(IntVar index, IntVar[] variables, IntVar target) {
280 Constraint ct = new Constraint(modelBuilder);
282 ct.getBuilder().getElementBuilder().setIndex(index.getIndex());
283 for (IntVar var : variables) {
284 element.addVars(var.getIndex());
285 }
286 element.setTarget(target.getIndex());
287 return ct;
288 }
289
291 public Constraint addElement(IntVar index, long[] values, IntVar target) {
292 Constraint ct = new Constraint(modelBuilder);
294 ct.getBuilder().getElementBuilder().setIndex(index.getIndex());
295 for (long v : values) {
296 element.addVars(indexFromConstant(v));
297 }
298 element.setTarget(target.getIndex());
299 return ct;
300 }
301
303 public Constraint addElement(IntVar index, int[] values, IntVar target) {
304 Constraint ct = new Constraint(modelBuilder);
306 ct.getBuilder().getElementBuilder().setIndex(index.getIndex());
307 for (long v : values) {
308 element.addVars(indexFromConstant(v));
309 }
310 element.setTarget(target.getIndex());
311 return ct;
312 }
313
329 public Constraint addCircuit(int[] tails, int[] heads, Literal[] literals) {
330 if (tails.length != heads.length) {
331 throw new MismatchedArrayLengths("CpModel.addCircuit", "tails", "heads");
332 }
333 if (tails.length != literals.length) {
334 throw new MismatchedArrayLengths("CpModel.addCircuit", "tails", "literals");
335 }
336
337 Constraint ct = new Constraint(modelBuilder);
338 CircuitConstraintProto.Builder circuit = ct.getBuilder().getCircuitBuilder();
339 for (int t : tails) {
340 circuit.addTails(t);
341 }
342 for (int h : heads) {
343 circuit.addHeads(h);
344 }
345 for (Literal lit : literals) {
346 circuit.addLiterals(lit.getIndex());
347 }
348 return ct;
349 }
350
364 public Constraint addAllowedAssignments(IntVar[] variables, long[][] tuplesList) {
365 Constraint ct = new Constraint(modelBuilder);
366 TableConstraintProto.Builder table = ct.getBuilder().getTableBuilder();
367 for (IntVar var : variables) {
368 table.addVars(var.getIndex());
369 }
370 int numVars = variables.length;
371 for (int t = 0; t < tuplesList.length; ++t) {
372 if (tuplesList[t].length != numVars) {
373 throw new WrongLength("CpModel.addAllowedAssignments",
374 "tuple " + t + " does not have the same length as the variables");
375 }
376 for (int i = 0; i < tuplesList[t].length; ++i) {
377 table.addValues(tuplesList[t][i]);
378 }
379 }
380 return ct;
381 }
382
388 public Constraint addAllowedAssignments(IntVar[] variables, int[][] tuplesList) {
389 Constraint ct = new Constraint(modelBuilder);
390 TableConstraintProto.Builder table = ct.getBuilder().getTableBuilder();
391 for (IntVar var : variables) {
392 table.addVars(var.getIndex());
393 }
394 int numVars = variables.length;
395 for (int t = 0; t < tuplesList.length; ++t) {
396 if (tuplesList[t].length != numVars) {
397 throw new WrongLength("CpModel.addAllowedAssignments",
398 "tuple " + t + " does not have the same length as the variables");
399 }
400 for (int i = 0; i < tuplesList[t].length; ++i) {
401 table.addValues(tuplesList[t][i]);
402 }
403 }
404 return ct;
405 }
406
419 public Constraint addForbiddenAssignments(IntVar[] variables, long[][] tuplesList) {
420 Constraint ct = addAllowedAssignments(variables, tuplesList);
421 // Reverse the flag.
422 ct.getBuilder().getTableBuilder().setNegated(true);
423 return ct;
424 }
425
431 public Constraint addForbiddenAssignments(IntVar[] variables, int[][] tuplesList) {
432 Constraint ct = addAllowedAssignments(variables, tuplesList);
433 // Reverse the flag.
434 ct.getBuilder().getTableBuilder().setNegated(true);
435 return ct;
436 }
437
470 IntVar[] transitionVariables, long startingState, long[] finalStates, long[][] transitions) {
471 Constraint ct = new Constraint(modelBuilder);
472 AutomatonConstraintProto.Builder automaton = ct.getBuilder().getAutomatonBuilder();
473 for (IntVar var : transitionVariables) {
474 automaton.addVars(var.getIndex());
475 }
476 automaton.setStartingState(startingState);
477 for (long c : finalStates) {
478 automaton.addFinalStates(c);
479 }
480 for (long[] t : transitions) {
481 if (t.length != 3) {
482 throw new WrongLength("CpModel.addAutomaton", "transition does not have length 3");
483 }
484 automaton.addTransitionTail(t[0]).addTransitionLabel(t[1]).addTransitionHead(t[2]);
485 }
486 return ct;
487 }
488
500 public Constraint addInverse(IntVar[] variables, IntVar[] inverseVariables) {
501 if (variables.length != inverseVariables.length) {
502 throw new MismatchedArrayLengths("CpModel.addInverse", "variables", "inverseVariables");
503 }
504 Constraint ct = new Constraint(modelBuilder);
505 InverseConstraintProto.Builder inverse = ct.getBuilder().getInverseBuilder();
506 for (IntVar var : variables) {
507 inverse.addFDirect(var.getIndex());
508 }
509 for (IntVar var : inverseVariables) {
510 inverse.addFInverse(var.getIndex());
511 }
512 return ct;
513 }
514
539 IntVar[] times, long[] demands, long minLevel, long maxLevel) {
540 if (times.length != demands.length) {
541 throw new MismatchedArrayLengths("CpModel.addReservoirConstraint", "times", "demands");
542 }
543 if (minLevel > 0) {
544 throw new IllegalArgumentException("CpModel.addReservoirConstraint: minLevel must be <= 0");
545 }
546 if (maxLevel < 0) {
547 throw new IllegalArgumentException("CpModel.addReservoirConstraint: maxLevel must be >= 0");
548 }
549 Constraint ct = new Constraint(modelBuilder);
550 ReservoirConstraintProto.Builder reservoir = ct.getBuilder().getReservoirBuilder();
551 for (IntVar var : times) {
552 reservoir.addTimes(var.getIndex());
553 }
554 for (long d : demands) {
555 reservoir.addDemands(d);
556 }
557 reservoir.setMinLevel(minLevel).setMaxLevel(maxLevel);
558 return ct;
559 }
560
567 IntVar[] times, int[] demands, long minLevel, long maxLevel) {
568 return addReservoirConstraint(times, toLongArray(demands), minLevel, maxLevel);
569 }
570
595 IntVar[] times, long[] demands, IntVar[] actives, long minLevel, long maxLevel) {
596 if (times.length != demands.length) {
597 throw new MismatchedArrayLengths(
598 "CpModel.addReservoirConstraintWithActive", "times", "demands");
599 }
600 if (times.length != actives.length) {
601 throw new MismatchedArrayLengths(
602 "CpModel.addReservoirConstraintWithActive", "times", "actives");
603 }
604 if (minLevel > 0) {
605 throw new IllegalArgumentException(
606 "CpModel.addReservoirConstraintWithActive: minLevel must be <= 0");
607 }
608 if (maxLevel < 0) {
609 throw new IllegalArgumentException(
610 "CpModel.addReservoirConstraintWithActive: maxLevel must be >= 0");
611 }
612
613 Constraint ct = new Constraint(modelBuilder);
614 ReservoirConstraintProto.Builder reservoir = ct.getBuilder().getReservoirBuilder();
615 for (IntVar var : times) {
616 reservoir.addTimes(var.getIndex());
617 }
618 for (long d : demands) {
619 reservoir.addDemands(d);
620 }
621 for (IntVar var : actives) {
622 reservoir.addActives(var.getIndex());
623 }
624 reservoir.setMinLevel(minLevel).setMaxLevel(maxLevel);
625 return ct;
626 }
627
634 IntVar[] times, int[] demands, IntVar[] actives, long minLevel, long maxLevel) {
636 times, toLongArray(demands), actives, minLevel, maxLevel);
637 }
638
640 public void addMapDomain(IntVar var, Literal[] booleans, long offset) {
641 for (int i = 0; i < booleans.length; ++i) {
642 addEquality(var, offset + i).onlyEnforceIf(booleans[i]);
643 addDifferent(var, offset + i).onlyEnforceIf(booleans[i].not());
644 }
645 }
646
648 public Constraint addMinEquality(IntVar target, IntVar[] vars) {
649 Constraint ct = new Constraint(modelBuilder);
651 ct.getBuilder().getIntMinBuilder().setTarget(target.getIndex());
652 for (IntVar var : vars) {
653 intMin.addVars(var.getIndex());
654 }
655 return ct;
656 }
657
659 public Constraint addMaxEquality(IntVar target, IntVar[] vars) {
660 Constraint ct = new Constraint(modelBuilder);
662 ct.getBuilder().getIntMaxBuilder().setTarget(target.getIndex());
663 for (IntVar var : vars) {
664 intMax.addVars(var.getIndex());
665 }
666 return ct;
667 }
668
670 public Constraint addDivisionEquality(IntVar target, IntVar num, IntVar denom) {
671 Constraint ct = new Constraint(modelBuilder);
672 ct.getBuilder()
673 .getIntDivBuilder()
674 .setTarget(target.getIndex())
675 .addVars(num.getIndex())
676 .addVars(denom.getIndex());
677 return ct;
678 }
679
682 Constraint ct = new Constraint(modelBuilder);
683 ct.getBuilder()
684 .getIntMaxBuilder()
685 .setTarget(target.getIndex())
686 .addVars(var.getIndex())
687 .addVars(-var.getIndex() - 1);
688 return ct;
689 }
690
693 Constraint ct = new Constraint(modelBuilder);
694 ct.getBuilder()
695 .getIntModBuilder()
696 .setTarget(target.getIndex())
697 .addVars(var.getIndex())
698 .addVars(mod.getIndex());
699 return ct;
700 }
701
703 public Constraint addModuloEquality(IntVar target, IntVar var, long mod) {
704 Constraint ct = new Constraint(modelBuilder);
705 ct.getBuilder()
706 .getIntModBuilder()
707 .setTarget(target.getIndex())
708 .addVars(var.getIndex())
709 .addVars(indexFromConstant(mod));
710 return ct;
711 }
712
715 Constraint ct = new Constraint(modelBuilder);
717 ct.getBuilder().getIntProdBuilder().setTarget(target.getIndex());
718 for (IntVar var : vars) {
719 intProd.addVars(var.getIndex());
720 }
721 return ct;
722 }
723
724 // Scheduling support.
725
741 LinearExpr start, LinearExpr size, LinearExpr end, String name) {
742 addEquality(new Sum(start, size), end);
743 return new IntervalVar(modelBuilder, getLinearExpressionProtoBuilderFromLinearExpr(start),
744 getLinearExpressionProtoBuilderFromLinearExpr(size),
745 getLinearExpressionProtoBuilderFromLinearExpr(end), name);
746 }
747
759 public IntervalVar newFixedSizeIntervalVar(LinearExpr start, long size, String name) {
760 return new IntervalVar(modelBuilder, getLinearExpressionProtoBuilderFromLinearExpr(start),
761 getLinearExpressionProtoBuilderFromLong(size),
762 getLinearExpressionProtoBuilderFromLinearExpr(new Sum(start, size)), name);
763 }
764
766 public IntervalVar newFixedInterval(long start, long size, String name) {
767 return new IntervalVar(modelBuilder, getLinearExpressionProtoBuilderFromLong(start),
768 getLinearExpressionProtoBuilderFromLong(size),
769 getLinearExpressionProtoBuilderFromLong(start + size), name);
770 }
771
791 LinearExpr start, LinearExpr size, LinearExpr end, Literal isPresent, String name) {
792 addEquality(new Sum(start, size), end).onlyEnforceIf(isPresent);
793 return new IntervalVar(modelBuilder, getLinearExpressionProtoBuilderFromLinearExpr(start),
794 getLinearExpressionProtoBuilderFromLinearExpr(size),
795 getLinearExpressionProtoBuilderFromLinearExpr(end), isPresent.getIndex(), name);
796 }
797
812 LinearExpr start, long size, Literal isPresent, String name) {
813 return new IntervalVar(modelBuilder, getLinearExpressionProtoBuilderFromLinearExpr(start),
814 getLinearExpressionProtoBuilderFromLong(size),
815 getLinearExpressionProtoBuilderFromLinearExpr(new Sum(start, size)), isPresent.getIndex(),
816 name);
817 }
818
821 long start, long size, Literal isPresent, String name) {
822 return new IntervalVar(modelBuilder, getLinearExpressionProtoBuilderFromLong(start),
823 getLinearExpressionProtoBuilderFromLong(size),
824 getLinearExpressionProtoBuilderFromLong(start + size), isPresent.getIndex(), name);
825 }
826
835 public Constraint addNoOverlap(IntervalVar[] intervalVars) {
836 Constraint ct = new Constraint(modelBuilder);
837 NoOverlapConstraintProto.Builder noOverlap = ct.getBuilder().getNoOverlapBuilder();
838 for (IntervalVar var : intervalVars) {
839 noOverlap.addIntervals(var.getIndex());
840 }
841 return ct;
842 }
843
855 public Constraint addNoOverlap2D(IntervalVar[] xIntervals, IntervalVar[] yIntervals) {
856 Constraint ct = new Constraint(modelBuilder);
857 NoOverlap2DConstraintProto.Builder noOverlap2d = ct.getBuilder().getNoOverlap2DBuilder();
858 for (IntervalVar x : xIntervals) {
859 noOverlap2d.addXIntervals(x.getIndex());
860 }
861 for (IntervalVar y : yIntervals) {
862 noOverlap2d.addYIntervals(y.getIndex());
863 }
864 return ct;
865 }
866
882 public Constraint addCumulative(IntervalVar[] intervals, IntVar[] demands, IntVar capacity) {
883 Constraint ct = new Constraint(modelBuilder);
884 CumulativeConstraintProto.Builder cumul = ct.getBuilder().getCumulativeBuilder();
885 for (IntervalVar interval : intervals) {
886 cumul.addIntervals(interval.getIndex());
887 }
888 for (IntVar var : demands) {
889 cumul.addDemands(var.getIndex());
890 }
891 cumul.setCapacity(capacity.getIndex());
892 return ct;
893 }
894
900 public Constraint addCumulative(IntervalVar[] intervals, long[] demands, IntVar capacity) {
901 Constraint ct = new Constraint(modelBuilder);
902 CumulativeConstraintProto.Builder cumul = ct.getBuilder().getCumulativeBuilder();
903 for (IntervalVar interval : intervals) {
904 cumul.addIntervals(interval.getIndex());
905 }
906 for (long d : demands) {
907 cumul.addDemands(indexFromConstant(d));
908 }
909 cumul.setCapacity(capacity.getIndex());
910 return ct;
911 }
912
918 public Constraint addCumulative(IntervalVar[] intervals, int[] demands, IntVar capacity) {
919 return addCumulative(intervals, toLongArray(demands), capacity);
920 }
921
927 public Constraint addCumulative(IntervalVar[] intervals, IntVar[] demands, long capacity) {
928 Constraint ct = new Constraint(modelBuilder);
929 CumulativeConstraintProto.Builder cumul = ct.getBuilder().getCumulativeBuilder();
930 for (IntervalVar interval : intervals) {
931 cumul.addIntervals(interval.getIndex());
932 }
933 for (IntVar var : demands) {
934 cumul.addDemands(var.getIndex());
935 }
936 cumul.setCapacity(indexFromConstant(capacity));
937 return ct;
938 }
939
945 public Constraint addCumulative(IntervalVar[] intervals, long[] demands, long capacity) {
946 Constraint ct = new Constraint(modelBuilder);
947 CumulativeConstraintProto.Builder cumul = ct.getBuilder().getCumulativeBuilder();
948 for (IntervalVar interval : intervals) {
949 cumul.addIntervals(interval.getIndex());
950 }
951 for (long d : demands) {
952 cumul.addDemands(indexFromConstant(d));
953 }
954 cumul.setCapacity(indexFromConstant(capacity));
955 return ct;
956 }
957
963 public Constraint addCumulative(IntervalVar[] intervals, int[] demands, long capacity) {
964 return addCumulative(intervals, toLongArray(demands), capacity);
965 }
966
968 public void addHint(IntVar var, long value) {
969 modelBuilder.getSolutionHintBuilder().addVars(var.getIndex());
970 modelBuilder.getSolutionHintBuilder().addValues(value);
971 }
972
974 public void clearHints() {
975 modelBuilder.clearSolutionHint();
976 }
977
979 public void addAssumption(Literal lit) {
980 modelBuilder.addAssumptions(lit.getIndex());
981 }
982
984 public void addAssumptions(Literal[] literals) {
985 for (Literal lit : literals) {
986 addAssumption(lit);
987 }
988 }
989
991 public void clearAssumptions() {
992 modelBuilder.clearAssumptions();
993 }
994
995 // Objective.
996
998 public void minimize(LinearExpr expr) {
999 CpObjectiveProto.Builder obj = modelBuilder.getObjectiveBuilder();
1000 for (int i = 0; i < expr.numElements(); ++i) {
1001 obj.addVars(expr.getVariable(i).getIndex()).addCoeffs(expr.getCoefficient(i));
1002 }
1003 obj.setOffset(expr.getOffset());
1004 }
1005
1007 public void maximize(LinearExpr expr) {
1008 CpObjectiveProto.Builder obj = modelBuilder.getObjectiveBuilder();
1009 for (int i = 0; i < expr.numElements(); ++i) {
1010 obj.addVars(expr.getVariable(i).getIndex()).addCoeffs(-expr.getCoefficient(i));
1011 }
1012 obj.setOffset(-expr.getOffset());
1013 obj.setScalingFactor(-1.0);
1014 }
1015
1016 // DecisionStrategy
1017
1019 public void addDecisionStrategy(IntVar[] variables,
1022 DecisionStrategyProto.Builder ds = modelBuilder.addSearchStrategyBuilder();
1023 for (IntVar var : variables) {
1024 ds.addVariables(var.getIndex());
1025 }
1026 ds.setVariableSelectionStrategy(varStr).setDomainReductionStrategy(domStr);
1027 }
1028
1030 public String modelStats() {
1031 return CpSatHelper.modelStats(model());
1032 }
1033
1035 public String validate() {
1037 }
1038
1047 public Boolean exportToFile(String file) {
1048 return CpSatHelper.writeModelToFile(model(), file);
1049 }
1050
1051 // Helpers
1052
1053 long[] toLongArray(int[] values) {
1054 long[] result = new long[values.length];
1055 for (int i = 0; i < values.length; ++i) {
1056 result[i] = values[i];
1057 }
1058 return result;
1059 }
1060
1061 int indexFromConstant(long constant) {
1062 IntVar constVar = newConstant(constant);
1063 return constVar.getIndex();
1064 }
1065
1066 LinearExpressionProto.Builder getLinearExpressionProtoBuilderFromLinearExpr(LinearExpr expr) {
1067 LinearExpressionProto.Builder builder = LinearExpressionProto.newBuilder();
1068 final int numVariables = expr.numElements();
1069 for (int i = 0; i < numVariables; ++i) {
1070 builder.addVars(expr.getVariable(i).getIndex());
1071 builder.addCoeffs(expr.getCoefficient(i));
1072 }
1073 builder.setOffset(expr.getOffset());
1074 return builder;
1075 }
1076
1077 LinearExpressionProto.Builder getLinearExpressionProtoBuilderFromLong(long value) {
1078 LinearExpressionProto.Builder builder = LinearExpressionProto.newBuilder();
1079 builder.setOffset(value);
1080 return builder;
1081 }
1082
1083 // Getters.
1084
1086 return modelBuilder.build();
1087 }
1088
1089 public int negated(int index) {
1090 return -index - 1;
1091 }
1092
1095 return modelBuilder;
1096 }
1097
1098 private final CpModelProto.Builder modelBuilder;
1099 private final Map<Long, IntVar> constantMap;
1100}
ConstraintProto.Builder getBuilder()
Returns the constraint builder.
void onlyEnforceIf(Literal lit)
Adds a literal to the constraint.
Exception thrown when parallel arrays have mismatched lengths.
Definition: CpModel.java:51
MismatchedArrayLengths(String methodName, String array1Name, String array2Name)
Definition: CpModel.java:52
Exception thrown when an array has a wrong length.
Definition: CpModel.java:58
WrongLength(String methodName, String msg)
Definition: CpModel.java:59
Main modeling class.
Definition: CpModel.java:42
Constraint addAllowedAssignments(IntVar[] variables, int[][] tuplesList)
Adds.
Definition: CpModel.java:388
IntervalVar newIntervalVar(LinearExpr start, LinearExpr size, LinearExpr end, String name)
Creates an interval variable from three affine expressions start, size, and end.
Definition: CpModel.java:740
IntVar newConstant(long value)
Creates a constant variable.
Definition: CpModel.java:92
Constraint addCumulative(IntervalVar[] intervals, long[] demands, long capacity)
Adds.
Definition: CpModel.java:945
IntVar newBoolVar(String name)
Creates a Boolean variable with the given name.
Definition: CpModel.java:87
Constraint addGreaterOrEqual(LinearExpr expr, long value)
Adds.
Definition: CpModel.java:214
Constraint addForbiddenAssignments(IntVar[] variables, int[][] tuplesList)
Adds.
Definition: CpModel.java:431
void clearAssumptions()
Remove all assumptions from the model.
Definition: CpModel.java:991
Constraint addReservoirConstraintWithActive(IntVar[] times, long[] demands, IntVar[] actives, long minLevel, long maxLevel)
Adds.
Definition: CpModel.java:594
Constraint addGreaterOrEqual(LinearExpr left, LinearExpr right)
Adds.
Definition: CpModel.java:219
Constraint addAutomaton(IntVar[] transitionVariables, long startingState, long[] finalStates, long[][] transitions)
Adds an automaton constraint.
Definition: CpModel.java:469
Constraint addModuloEquality(IntVar target, IntVar var, long mod)
Adds.
Definition: CpModel.java:703
Boolean exportToFile(String file)
Write the model as a protocol buffer to 'file'.
Definition: CpModel.java:1047
Constraint addLessOrEqual(LinearExpr expr, long value)
Adds.
Definition: CpModel.java:188
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:820
Constraint addLessThan(LinearExpr expr, long value)
Adds.
Definition: CpModel.java:198
Constraint addElement(IntVar index, long[] values, IntVar target)
Adds the element constraint:
Definition: CpModel.java:291
Literal falseLiteral()
Returns the false literal.
Definition: CpModel.java:107
Constraint addLessOrEqualWithOffset(LinearExpr left, LinearExpr right, long offset)
Adds.
Definition: CpModel.java:208
IntervalVar newOptionalFixedSizeIntervalVar(LinearExpr start, long size, Literal isPresent, String name)
Creates an optional interval variable from an affine expression start, and a fixed size.
Definition: CpModel.java:811
void addAssumptions(Literal[] literals)
Adds multiple literals to the model as assumptions.
Definition: CpModel.java:984
Constraint addEquality(LinearExpr left, LinearExpr right)
Adds.
Definition: CpModel.java:178
void minimize(LinearExpr expr)
Adds a minimization objective of a linear expression.
Definition: CpModel.java:998
Constraint addDivisionEquality(IntVar target, IntVar num, IntVar denom)
Adds.
Definition: CpModel.java:670
IntervalVar newFixedSizeIntervalVar(LinearExpr start, long size, String name)
Creates an interval variable from an affine expression start, and a fixed size.
Definition: CpModel.java:759
Constraint addReservoirConstraint(IntVar[] times, int[] demands, long minLevel, long maxLevel)
Adds.
Definition: CpModel.java:566
Constraint addDifferentWithOffset(LinearExpr left, LinearExpr right, long offset)
Adds.
Definition: CpModel.java:253
Constraint addGreaterThan(LinearExpr expr, long value)
Adds.
Definition: CpModel.java:224
void addAssumption(Literal lit)
Adds a literal to the model as assumption.
Definition: CpModel.java:979
Constraint addProductEquality(IntVar target, IntVar[] vars)
Adds.
Definition: CpModel.java:714
Constraint addReservoirConstraint(IntVar[] times, long[] demands, long minLevel, long maxLevel)
Adds.
Definition: CpModel.java:538
void addHint(IntVar var, long value)
Adds hinting to a variable.
Definition: CpModel.java:968
Constraint addModuloEquality(IntVar target, IntVar var, IntVar mod)
Adds.
Definition: CpModel.java:692
IntervalVar newFixedInterval(long start, long size, String name)
Creates a fixed interval from its start and its size.
Definition: CpModel.java:766
Constraint addGreaterThan(LinearExpr left, LinearExpr right)
Adds.
Definition: CpModel.java:229
Constraint addCircuit(int[] tails, int[] heads, Literal[] literals)
Adds.
Definition: CpModel.java:329
String modelStats()
Returns some statistics on model as a string.
Definition: CpModel.java:1030
Constraint addEqualityWithOffset(LinearExpr left, LinearExpr right, long offset)
Adds.
Definition: CpModel.java:183
Constraint addElement(IntVar index, IntVar[] variables, IntVar target)
Adds the element constraint:
Definition: CpModel.java:279
Constraint addAbsEquality(IntVar target, IntVar var)
Adds.
Definition: CpModel.java:681
Constraint addAllowedAssignments(IntVar[] variables, long[][] tuplesList)
Adds.
Definition: CpModel.java:364
Constraint addCumulative(IntervalVar[] intervals, int[] demands, IntVar capacity)
Adds.
Definition: CpModel.java:918
Constraint addReservoirConstraintWithActive(IntVar[] times, int[] demands, IntVar[] actives, long minLevel, long maxLevel)
Adds.
Definition: CpModel.java:633
void maximize(LinearExpr expr)
Adds a maximization objective of a linear expression.
Definition: CpModel.java:1007
Constraint addAllDifferent(IntVar[] variables)
Adds.
Definition: CpModel.java:269
Constraint addImplication(Literal a, Literal b)
Adds.
Definition: CpModel.java:144
Constraint addBoolXor(Literal[] literals)
Adds.
Definition: CpModel.java:134
Constraint addCumulative(IntervalVar[] intervals, IntVar[] demands, IntVar capacity)
Adds.
Definition: CpModel.java:882
Constraint addLessThan(LinearExpr left, LinearExpr right)
Adds.
Definition: CpModel.java:203
Constraint addMinEquality(IntVar target, IntVar[] vars)
Adds.
Definition: CpModel.java:648
Constraint addCumulative(IntervalVar[] intervals, IntVar[] demands, long capacity)
Adds.
Definition: CpModel.java:927
IntVar newIntVar(long lb, long ub, String name)
Creates an integer variable with domain [lb, ub].
Definition: CpModel.java:71
void addMapDomain(IntVar var, Literal[] booleans, long offset)
Adds.
Definition: CpModel.java:640
void addDecisionStrategy(IntVar[] variables, DecisionStrategyProto.VariableSelectionStrategy varStr, DecisionStrategyProto.DomainReductionStrategy domStr)
Adds.
Definition: CpModel.java:1019
Constraint addInverse(IntVar[] variables, IntVar[] inverseVariables)
Adds.
Definition: CpModel.java:500
Constraint addNoOverlap2D(IntervalVar[] xIntervals, IntervalVar[] yIntervals)
Adds.
Definition: CpModel.java:855
IntervalVar newOptionalIntervalVar(LinearExpr start, LinearExpr size, LinearExpr end, Literal isPresent, String name)
Creates an optional interval variable from three affine expressions start, size, end,...
Definition: CpModel.java:790
Constraint addLinearConstraint(LinearExpr expr, long lb, long ub)
Adds.
Definition: CpModel.java:168
Constraint addNoOverlap(IntervalVar[] intervalVars)
Adds.
Definition: CpModel.java:835
Literal trueLiteral()
Returns the true literal.
Definition: CpModel.java:102
Constraint addForbiddenAssignments(IntVar[] variables, long[][] tuplesList)
Adds.
Definition: CpModel.java:419
Constraint addDifferent(LinearExpr expr, long value)
Adds.
Definition: CpModel.java:240
Constraint addElement(IntVar index, int[] values, IntVar target)
Adds the element constraint:
Definition: CpModel.java:303
Constraint addEquality(LinearExpr expr, long value)
Adds.
Definition: CpModel.java:173
void clearHints()
Remove all solution hints.
Definition: CpModel.java:974
String validate()
Returns a non empty string explaining the issue if the model is invalid.
Definition: CpModel.java:1035
Constraint addGreaterOrEqualWithOffset(LinearExpr left, LinearExpr right, long offset)
Adds.
Definition: CpModel.java:234
Constraint addMaxEquality(IntVar target, IntVar[] vars)
Adds.
Definition: CpModel.java:659
Constraint addCumulative(IntervalVar[] intervals, int[] demands, long capacity)
Adds.
Definition: CpModel.java:963
Constraint addDifferent(LinearExpr left, LinearExpr right)
Adds.
Definition: CpModel.java:247
Constraint addBoolOr(Literal[] literals)
Adds.
Definition: CpModel.java:114
IntVar newIntVarFromDomain(Domain domain, String name)
Creates an integer variable with given domain.
Definition: CpModel.java:82
Constraint addLinearExpressionInDomain(LinearExpr expr, Domain domain)
Adds.
Definition: CpModel.java:151
Constraint addBoolAnd(Literal[] literals)
Adds.
Definition: CpModel.java:124
Constraint addCumulative(IntervalVar[] intervals, long[] demands, IntVar capacity)
Adds.
Definition: CpModel.java:900
Constraint addLessOrEqual(LinearExpr left, LinearExpr right)
Adds.
Definition: CpModel.java:193
CpModelProto.Builder getBuilder()
Returns the model builder.
Definition: CpModel.java:1094
static String validateModel(com.google.ortools.sat.CpModelProto model_proto)
static String modelStats(com.google.ortools.sat.CpModelProto model_proto)
static boolean writeModelToFile(com.google.ortools.sat.CpModelProto model_proto, String filename)
int getIndex()
Internal, returns the index of the variable in the underlying CpModelProto.
We call domain any subset of Int64 = [kint64min, kint64max].
Definition: Domain.java:21
static Domain fromFlatIntervals(long[] flat_intervals)
This method is available in Python, Java and .NET.
Definition: Domain.java:100
long[] flattenedIntervals()
This method returns the flattened list of interval bounds of the domain.
Definition: Domain.java:111
A linear expression interface that can be parsed.
Definition: LinearExpr.java:17
long getCoefficient(int index)
Returns the ith coefficient.
int numElements()
Returns the number of elements in the interface.
long getOffset()
Returns the constant part of the expression.
IntVar getVariable(int index)
Returns 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.