Google OR-Tools v9.9
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
CpModel.java
Go to the documentation of this file.
1// Copyright 2010-2024 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
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
64 public CpModel() {
65 modelBuilder = CpModelProto.newBuilder();
66 constantMap = new LinkedHashMap<>();
67 }
68
69 public CpModel getClone() {
70 CpModel clone = new CpModel();
71 clone.modelBuilder.mergeFrom(modelBuilder.build());
72 clone.constantMap.clear();
73 clone.constantMap.putAll(constantMap);
74 return clone;
75 }
76
77 // Integer variables.
78
80 public IntVar newIntVar(long lb, long ub, String name) {
81 return new IntVar(modelBuilder, new Domain(lb, ub), name);
82 }
83
91 public IntVar newIntVarFromDomain(Domain domain, String name) {
92 return new IntVar(modelBuilder, domain, name);
93 }
94
96 public BoolVar newBoolVar(String name) {
97 return new BoolVar(modelBuilder, new Domain(0, 1), name);
98 }
99
101 public IntVar newConstant(long value) {
102 if (constantMap.containsKey(value)) {
103 return new IntVar(modelBuilder, constantMap.get(value));
104 }
105 IntVar cste = new IntVar(modelBuilder, new Domain(value), ""); // bounds and name.
106 constantMap.put(value, cste.getIndex());
107 return cste;
108 }
109
112 if (constantMap.containsKey(1L)) {
113 return new BoolVar(modelBuilder, constantMap.get(1L));
114 }
115 BoolVar cste = new BoolVar(modelBuilder, new Domain(1), ""); // bounds and name.
116 constantMap.put(1L, cste.getIndex());
117 return cste;
118 }
119
122 if (constantMap.containsKey(0L)) {
123 return new BoolVar(modelBuilder, constantMap.get(0L));
124 }
125 BoolVar cste = new BoolVar(modelBuilder, new Domain(0), ""); // bounds and name.
126 constantMap.put(0L, cste.getIndex());
127 return cste;
128 }
129
132 return new BoolVar(modelBuilder, index);
133 }
134
136 public IntVar getIntVarFromProtoIndex(int index) {
137 return new IntVar(modelBuilder, index);
138 }
139
140 // Boolean Constraints.
141
143 public Constraint addBoolOr(Literal[] literals) {
144 return addBoolOr(Arrays.asList(literals));
145 }
146
148 public Constraint addBoolOr(Iterable<Literal> literals) {
149 Constraint ct = new Constraint(modelBuilder);
150 BoolArgumentProto.Builder boolOr = ct.getBuilder().getBoolOrBuilder();
151 for (Literal lit : literals) {
152 boolOr.addLiterals(lit.getIndex());
153 }
154 return ct;
155 }
156
158 public Constraint addAtLeastOne(Literal[] literals) {
159 return addBoolOr(Arrays.asList(literals));
160 }
161
163 public Constraint addAtLeastOne(Iterable<Literal> literals) {
164 return addBoolOr(literals);
165 }
166
168 public Constraint addAtMostOne(Literal[] literals) {
169 return addAtMostOne(Arrays.asList(literals));
170 }
171
173 public Constraint addAtMostOne(Iterable<Literal> literals) {
174 Constraint ct = new Constraint(modelBuilder);
175 BoolArgumentProto.Builder atMostOne = ct.getBuilder().getAtMostOneBuilder();
176 for (Literal lit : literals) {
177 atMostOne.addLiterals(lit.getIndex());
178 }
179 return ct;
180 }
181
183 public Constraint addExactlyOne(Literal[] literals) {
184 return addExactlyOne(Arrays.asList(literals));
185 }
186
188 public Constraint addExactlyOne(Iterable<Literal> literals) {
189 Constraint ct = new Constraint(modelBuilder);
190 BoolArgumentProto.Builder exactlyOne = ct.getBuilder().getExactlyOneBuilder();
191 for (Literal lit : literals) {
192 exactlyOne.addLiterals(lit.getIndex());
193 }
194 return ct;
195 }
196
198 public Constraint addBoolAnd(Literal[] literals) {
199 return addBoolAnd(Arrays.asList(literals));
200 }
201
203 public Constraint addBoolAnd(Iterable<Literal> literals) {
204 Constraint ct = new Constraint(modelBuilder);
205 BoolArgumentProto.Builder boolAnd = ct.getBuilder().getBoolAndBuilder();
206 for (Literal lit : literals) {
207 boolAnd.addLiterals(lit.getIndex());
208 }
209 return ct;
210 }
211
213 public Constraint addBoolXor(Literal[] literals) {
214 return addBoolXor(Arrays.asList(literals));
215 }
216
218 public Constraint addBoolXor(Iterable<Literal> literals) {
219 Constraint ct = new Constraint(modelBuilder);
220 BoolArgumentProto.Builder boolXOr = ct.getBuilder().getBoolXorBuilder();
221 for (Literal lit : literals) {
222 boolXOr.addLiterals(lit.getIndex());
223 }
224 return ct;
225 }
226
229 return addBoolOr(new Literal[] {a.not(), b});
230 }
231
232 // Linear constraints.
233
236 Constraint ct = new Constraint(modelBuilder);
237 LinearConstraintProto.Builder lin = ct.getBuilder().getLinearBuilder();
238 final LinearExpr e = expr.build();
239 for (int i = 0; i < e.numElements(); ++i) {
240 lin.addVars(e.getVariableIndex(i)).addCoeffs(e.getCoefficient(i));
241 }
242 long offset = e.getOffset();
243 for (long b : domain.flattenedIntervals()) {
244 if (b == Long.MIN_VALUE || b == Long.MAX_VALUE) {
245 lin.addDomain(b);
246 } else {
247 lin.addDomain(b - offset);
248 }
249 }
250 return ct;
251 }
252
254 public Constraint addLinearConstraint(LinearArgument expr, long lb, long ub) {
255 return addLinearExpressionInDomain(expr, new Domain(lb, ub));
256 }
257
259 public Constraint addEquality(LinearArgument expr, long value) {
260 return addLinearExpressionInDomain(expr, new Domain(value));
261 }
262
266 difference.addTerm(left, 1);
267 difference.addTerm(right, -1);
268 return addLinearExpressionInDomain(difference, new Domain(0));
269 }
270
272 public Constraint addLessOrEqual(LinearArgument expr, long value) {
273 return addLinearExpressionInDomain(expr, new Domain(Long.MIN_VALUE, value));
274 }
275
279 difference.addTerm(left, 1);
280 difference.addTerm(right, -1);
281 return addLinearExpressionInDomain(difference, new Domain(Long.MIN_VALUE, 0));
282 }
283
285 public Constraint addLessThan(LinearArgument expr, long value) {
286 return addLinearExpressionInDomain(expr, new Domain(Long.MIN_VALUE, value - 1));
287 }
288
292 difference.addTerm(left, 1);
293 difference.addTerm(right, -1);
294 return addLinearExpressionInDomain(difference, new Domain(Long.MIN_VALUE, -1));
295 }
296
298 public Constraint addGreaterOrEqual(LinearArgument expr, long value) {
299 return addLinearExpressionInDomain(expr, new Domain(value, Long.MAX_VALUE));
300 }
301
305 difference.addTerm(left, 1);
306 difference.addTerm(right, -1);
307 return addLinearExpressionInDomain(difference, new Domain(0, Long.MAX_VALUE));
308 }
309
311 public Constraint addGreaterThan(LinearArgument expr, long value) {
312 return addLinearExpressionInDomain(expr, new Domain(value + 1, Long.MAX_VALUE));
313 }
314
318 difference.addTerm(left, 1);
319 difference.addTerm(right, -1);
320 return addLinearExpressionInDomain(difference, new Domain(1, Long.MAX_VALUE));
321 }
322
324 public Constraint addDifferent(LinearArgument expr, long value) {
325 return addLinearExpressionInDomain(expr,
327 new long[] {Long.MIN_VALUE, value - 1, value + 1, Long.MAX_VALUE}));
328 }
329
333 difference.addTerm(left, 1);
334 difference.addTerm(right, -1);
336 difference, Domain.fromFlatIntervals(new long[] {Long.MIN_VALUE, -1, 1, Long.MAX_VALUE}));
337 }
338
339 // Integer constraints.
340
350 return addAllDifferent(Arrays.asList(expressions));
351 }
352
358 public Constraint addAllDifferent(Iterable<? extends LinearArgument> expressions) {
359 Constraint ct = new Constraint(modelBuilder);
360 AllDifferentConstraintProto.Builder allDiff = ct.getBuilder().getAllDiffBuilder();
361 for (LinearArgument expr : expressions) {
362 allDiff.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/false));
363 }
364 return ct;
365 }
366
368 public Constraint addElement(IntVar index, IntVar[] variables, IntVar target) {
369 Constraint ct = new Constraint(modelBuilder);
370 ElementConstraintProto.Builder element =
371 ct.getBuilder().getElementBuilder().setIndex(index.getIndex());
372 for (IntVar var : variables) {
373 element.addVars(var.getIndex());
374 }
375 element.setTarget(target.getIndex());
376 return ct;
377 }
378
380 public Constraint addElement(IntVar index, long[] values, IntVar target) {
381 Constraint ct = new Constraint(modelBuilder);
382 ElementConstraintProto.Builder element =
383 ct.getBuilder().getElementBuilder().setIndex(index.getIndex());
384 for (long v : values) {
385 element.addVars(newConstant(v).getIndex());
386 }
387 element.setTarget(target.getIndex());
388 return ct;
389 }
390
392 public Constraint addElement(IntVar index, int[] values, IntVar target) {
393 Constraint ct = new Constraint(modelBuilder);
394 ElementConstraintProto.Builder element =
395 ct.getBuilder().getElementBuilder().setIndex(index.getIndex());
396 for (long v : values) {
397 element.addVars(newConstant(v).getIndex());
398 }
399 element.setTarget(target.getIndex());
400 return ct;
401 }
402
413 return new CircuitConstraint(modelBuilder);
414 }
415
427 return new MultipleCircuitConstraint(modelBuilder);
428 }
429
442 return addAllowedAssignments(Arrays.asList(variables));
443 }
444
450 public TableConstraint addAllowedAssignments(Iterable<IntVar> variables) {
451 TableConstraint ct = new TableConstraint(modelBuilder);
452 TableConstraintProto.Builder table = ct.getBuilder().getTableBuilder();
453 for (IntVar var : variables) {
454 table.addVars(var.getIndex());
455 }
456 table.setNegated(false);
457 return ct;
458 }
459
471 return addForbiddenAssignments(Arrays.asList(variables));
472 }
473
479 public TableConstraint addForbiddenAssignments(Iterable<IntVar> variables) {
480 TableConstraint ct = new TableConstraint(modelBuilder);
481 TableConstraintProto.Builder table = ct.getBuilder().getTableBuilder();
482 for (IntVar var : variables) {
483 table.addVars(var.getIndex());
484 }
485 table.setNegated(true);
486 return ct;
487 }
488
519 IntVar[] transitionVariables, long startingState, long[] finalStates) {
520 AutomatonConstraint ct = new AutomatonConstraint(modelBuilder);
521 AutomatonConstraintProto.Builder automaton = ct.getBuilder().getAutomatonBuilder();
522 for (IntVar var : transitionVariables) {
523 automaton.addVars(var.getIndex());
524 }
525 automaton.setStartingState(startingState);
526 for (long c : finalStates) {
527 automaton.addFinalStates(c);
528 }
529 return ct;
530 }
531
543 public Constraint addInverse(IntVar[] variables, IntVar[] inverseVariables) {
544 if (variables.length != inverseVariables.length) {
545 throw new MismatchedArrayLengths("CpModel.addInverse", "variables", "inverseVariables");
546 }
547 Constraint ct = new Constraint(modelBuilder);
548 InverseConstraintProto.Builder inverse = ct.getBuilder().getInverseBuilder();
549 for (IntVar var : variables) {
550 inverse.addFDirect(var.getIndex());
551 }
552 for (IntVar var : inverseVariables) {
553 inverse.addFInverse(var.getIndex());
554 }
555 return ct;
556 }
557
581 public ReservoirConstraint addReservoirConstraint(long minLevel, long maxLevel) {
582 if (minLevel > 0) {
583 throw new IllegalArgumentException("CpModel.addReservoirConstraint: minLevel must be <= 0");
584 }
585 if (maxLevel < 0) {
586 throw new IllegalArgumentException("CpModel.addReservoirConstraint: maxLevel must be >= 0");
587 }
589 ReservoirConstraintProto.Builder reservoir = ct.getBuilder().getReservoirBuilder();
590 reservoir.setMinLevel(minLevel).setMaxLevel(maxLevel);
591 return ct;
592 }
593
595 public void addMapDomain(IntVar var, Literal[] booleans, long offset) {
596 for (int i = 0; i < booleans.length; ++i) {
597 addEquality(var, offset + i).onlyEnforceIf(booleans[i]);
598 addDifferent(var, offset + i).onlyEnforceIf(booleans[i].not());
599 }
600 }
601
604 Constraint ct = new Constraint(modelBuilder);
605 LinearArgumentProto.Builder linMax = ct.getBuilder().getLinMaxBuilder();
606 linMax.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/true));
607 for (LinearArgument expr : exprs) {
608 linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/true));
609 }
610 return ct;
611 }
612
615 LinearArgument target, Iterable<? extends LinearArgument> exprs) {
616 Constraint ct = new Constraint(modelBuilder);
617 LinearArgumentProto.Builder linMax = ct.getBuilder().getLinMaxBuilder();
618 linMax.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/true));
619 for (LinearArgument expr : exprs) {
620 linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/true));
621 }
622 return ct;
623 }
624
627 Constraint ct = new Constraint(modelBuilder);
628 LinearArgumentProto.Builder linMax = ct.getBuilder().getLinMaxBuilder();
629 linMax.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false));
630 for (LinearArgument expr : exprs) {
631 linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/false));
632 }
633 return ct;
634 }
635
638 LinearArgument target, Iterable<? extends LinearArgument> exprs) {
639 Constraint ct = new Constraint(modelBuilder);
640 LinearArgumentProto.Builder linMax = ct.getBuilder().getLinMaxBuilder();
641 linMax.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false));
642 for (LinearArgument expr : exprs) {
643 linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/false));
644 }
645 return ct;
646 }
647
650 LinearArgument target, LinearArgument num, LinearArgument denom) {
651 Constraint ct = new Constraint(modelBuilder);
652 ct.getBuilder()
653 .getIntDivBuilder()
654 .setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false))
655 .addExprs(getLinearExpressionProtoBuilderFromLinearArgument(num, /*negate=*/false))
656 .addExprs(getLinearExpressionProtoBuilderFromLinearArgument(denom, /*negate=*/false));
657 return ct;
658 }
659
662 Constraint ct = new Constraint(modelBuilder);
663 LinearArgumentProto.Builder linMax = ct.getBuilder().getLinMaxBuilder();
664 linMax.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false));
665 linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/false));
666 linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/true));
667 return ct;
668 }
669
673 Constraint ct = new Constraint(modelBuilder);
674 ct.getBuilder()
675 .getIntModBuilder()
676 .setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false))
677 .addExprs(getLinearExpressionProtoBuilderFromLinearArgument(var, /*negate=*/false))
678 .addExprs(getLinearExpressionProtoBuilderFromLinearArgument(mod, /*negate=*/false));
679 return ct;
680 }
681
684 Constraint ct = new Constraint(modelBuilder);
685 ct.getBuilder()
686 .getIntModBuilder()
687 .setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false))
688 .addExprs(getLinearExpressionProtoBuilderFromLinearArgument(var, /*negate=*/false))
689 .addExprs(getLinearExpressionProtoBuilderFromLong(mod));
690 return ct;
691 }
692
695 Constraint ct = new Constraint(modelBuilder);
696 LinearArgumentProto.Builder intProd = ct.getBuilder().getIntProdBuilder();
697 intProd.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false));
698 for (LinearArgument expr : exprs) {
699 intProd.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/false));
700 }
701 return ct;
702 }
703
706 LinearArgument target, LinearArgument left, LinearArgument right) {
707 Constraint ct = new Constraint(modelBuilder);
708 LinearArgumentProto.Builder intProd = ct.getBuilder().getIntProdBuilder();
709 intProd.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false));
710 intProd.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(left, /*negate=*/false));
711 intProd.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(right, /*negate=*/false));
712 return ct;
713 }
714
715 // Scheduling support.
716
732 LinearArgument start, LinearArgument size, LinearArgument end, String name) {
733 addEquality(LinearExpr.newBuilder().add(start).add(size), end);
734 return new IntervalVar(modelBuilder,
735 getLinearExpressionProtoBuilderFromLinearArgument(start, /*negate=*/false),
736 getLinearExpressionProtoBuilderFromLinearArgument(size, /*negate=*/false),
737 getLinearExpressionProtoBuilderFromLinearArgument(end, /*negate=*/false), name);
738 }
739
751 public IntervalVar newFixedSizeIntervalVar(LinearArgument start, long size, String name) {
752 return new IntervalVar(modelBuilder,
753 getLinearExpressionProtoBuilderFromLinearArgument(start, /*negate=*/false),
754 getLinearExpressionProtoBuilderFromLong(size),
755 getLinearExpressionProtoBuilderFromLinearArgument(
756 LinearExpr.newBuilder().add(start).add(size), /*negate=*/false),
757 name);
758 }
759
761 public IntervalVar newFixedInterval(long start, long size, String name) {
762 return new IntervalVar(modelBuilder, getLinearExpressionProtoBuilderFromLong(start),
763 getLinearExpressionProtoBuilderFromLong(size),
764 getLinearExpressionProtoBuilderFromLong(start + size), name);
765 }
766
786 LinearArgument end, Literal isPresent, String name) {
787 addEquality(LinearExpr.newBuilder().add(start).add(size), end).onlyEnforceIf(isPresent);
788 return new IntervalVar(modelBuilder,
789 getLinearExpressionProtoBuilderFromLinearArgument(start, /*negate=*/false),
790 getLinearExpressionProtoBuilderFromLinearArgument(size, /*negate=*/false),
791 getLinearExpressionProtoBuilderFromLinearArgument(end, /*negate=*/false),
792 isPresent.getIndex(), name);
793 }
794
809 LinearArgument start, long size, Literal isPresent, String name) {
810 return new IntervalVar(modelBuilder,
811 getLinearExpressionProtoBuilderFromLinearArgument(start, /*negate=*/false),
812 getLinearExpressionProtoBuilderFromLong(size),
813 getLinearExpressionProtoBuilderFromLinearArgument(
814 LinearExpr.newBuilder().add(start).add(size), /*negate=*/false),
815 isPresent.getIndex(), name);
816 }
817
820 long start, long size, Literal isPresent, String name) {
821 return new IntervalVar(modelBuilder, getLinearExpressionProtoBuilderFromLong(start),
822 getLinearExpressionProtoBuilderFromLong(size),
823 getLinearExpressionProtoBuilderFromLong(start + size), isPresent.getIndex(), name);
824 }
825
834 public Constraint addNoOverlap(IntervalVar[] intervalVars) {
835 return addNoOverlap(Arrays.asList(intervalVars));
836 }
837
843 public Constraint addNoOverlap(Iterable<IntervalVar> intervalVars) {
844 Constraint ct = new Constraint(modelBuilder);
845 NoOverlapConstraintProto.Builder noOverlap = ct.getBuilder().getNoOverlapBuilder();
846 for (IntervalVar var : intervalVars) {
847 noOverlap.addIntervals(var.getIndex());
848 }
849 return ct;
850 }
851
865 return new NoOverlap2dConstraint(modelBuilder);
866 }
867
883 CumulativeConstraintProto.Builder cumul = ct.getBuilder().getCumulativeBuilder();
884 cumul.setCapacity(getLinearExpressionProtoBuilderFromLinearArgument(capacity, false));
885 return ct;
886 }
887
893 public CumulativeConstraint addCumulative(long capacity) {
895 CumulativeConstraintProto.Builder cumul = ct.getBuilder().getCumulativeBuilder();
896 cumul.setCapacity(getLinearExpressionProtoBuilderFromLong(capacity));
897 return ct;
898 }
899
901 public void addHint(IntVar var, long value) {
902 modelBuilder.getSolutionHintBuilder().addVars(var.getIndex());
903 modelBuilder.getSolutionHintBuilder().addValues(value);
904 }
905
907 public void clearHints() {
908 modelBuilder.clearSolutionHint();
909 }
910
912 public void addAssumption(Literal lit) {
913 modelBuilder.addAssumptions(lit.getIndex());
914 }
915
917 public void addAssumptions(Literal[] literals) {
918 for (Literal lit : literals) {
919 addAssumption(lit);
920 }
921 }
922
924 public void clearAssumptions() {
925 modelBuilder.clearAssumptions();
926 }
927
928 // Objective.
929
931 public void minimize(LinearArgument expr) {
933 CpObjectiveProto.Builder obj = modelBuilder.getObjectiveBuilder();
934 final LinearExpr e = expr.build();
935 for (int i = 0; i < e.numElements(); ++i) {
936 obj.addVars(e.getVariableIndex(i)).addCoeffs(e.getCoefficient(i));
937 }
938 obj.setOffset((double) e.getOffset());
939 }
940
942 public void minimize(DoubleLinearExpr expr) {
944 FloatObjectiveProto.Builder obj = modelBuilder.getFloatingPointObjectiveBuilder();
945 for (int i = 0; i < expr.numElements(); ++i) {
946 obj.addVars(expr.getVariableIndex(i)).addCoeffs(expr.getCoefficient(i));
947 }
948 obj.setOffset(expr.getOffset()).setMaximize(false);
949 }
950
952 public void maximize(LinearArgument expr) {
954 CpObjectiveProto.Builder obj = modelBuilder.getObjectiveBuilder();
955 final LinearExpr e = expr.build();
956 for (int i = 0; i < e.numElements(); ++i) {
957 obj.addVars(e.getVariableIndex(i)).addCoeffs(-e.getCoefficient(i));
958 }
959 obj.setOffset((double) -e.getOffset());
960 obj.setScalingFactor(-1.0);
961 }
962
964 public void maximize(DoubleLinearExpr expr) {
966 FloatObjectiveProto.Builder obj = modelBuilder.getFloatingPointObjectiveBuilder();
967 for (int i = 0; i < expr.numElements(); ++i) {
968 obj.addVars(expr.getVariableIndex(i)).addCoeffs(expr.getCoefficient(i));
969 }
970 obj.setOffset(expr.getOffset()).setMaximize(true);
971 }
972
974 public void clearObjective() {
975 modelBuilder.clearObjective();
976 modelBuilder.clearFloatingPointObjective();
977 }
978
980 public boolean hasObjective() {
981 return modelBuilder.hasObjective() || modelBuilder.hasFloatingPointObjective();
982 }
983
984 // DecisionStrategy
985
987 public void addDecisionStrategy(LinearArgument[] expressions,
990 DecisionStrategyProto.Builder ds = modelBuilder.addSearchStrategyBuilder();
991 for (LinearArgument arg : expressions) {
992 ds.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(arg, /* negate= */ false));
993 }
994 ds.setVariableSelectionStrategy(varStr).setDomainReductionStrategy(domStr);
995 }
996
998 public void addDecisionStrategy(Iterable<? extends LinearArgument> expressions,
1001 DecisionStrategyProto.Builder ds = modelBuilder.addSearchStrategyBuilder();
1002 for (LinearArgument arg : expressions) {
1003 ds.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(arg, /* negate= */ false));
1004 }
1005 ds.setVariableSelectionStrategy(varStr).setDomainReductionStrategy(domStr);
1006 }
1007
1009 public String modelStats() {
1010 return CpSatHelper.modelStats(model());
1011 }
1012
1014 public String validate() {
1016 }
1017
1026 public Boolean exportToFile(String file) {
1027 return CpSatHelper.writeModelToFile(model(), file);
1028 }
1029
1030 // Helpers
1031 LinearExpressionProto.Builder getLinearExpressionProtoBuilderFromLinearArgument(
1032 LinearArgument arg, boolean negate) {
1033 LinearExpressionProto.Builder builder = LinearExpressionProto.newBuilder();
1034 final LinearExpr expr = arg.build();
1035 final int numVariables = expr.numElements();
1036 final long mult = negate ? -1 : 1;
1037 for (int i = 0; i < numVariables; ++i) {
1038 builder.addVars(expr.getVariableIndex(i));
1039 builder.addCoeffs(expr.getCoefficient(i) * mult);
1040 }
1041 builder.setOffset(expr.getOffset() * mult);
1042 return builder;
1043 }
1044
1045 LinearExpressionProto.Builder getLinearExpressionProtoBuilderFromLong(long value) {
1046 LinearExpressionProto.Builder builder = LinearExpressionProto.newBuilder();
1047 builder.setOffset(value);
1048 return builder;
1049 }
1050
1051 // Getters.
1052
1054 return modelBuilder.build();
1055 }
1056
1057 public int negated(int index) {
1058 return -index - 1;
1059 }
1060
1062 public CpModelProto.Builder getBuilder() {
1063 return modelBuilder;
1064 }
1065
1066 private final CpModelProto.Builder modelBuilder;
1067 private final Map<Long, Integer> constantMap;
1068}
ConstraintProto.Builder getBuilder()
MismatchedArrayLengths(String methodName, String array1Name, String array2Name)
Definition CpModel.java:52
WrongLength(String methodName, String msg)
Definition CpModel.java:59
Constraint addDifferent(LinearArgument left, LinearArgument right)
Definition CpModel.java:331
IntVar newConstant(long value)
Definition CpModel.java:101
Constraint addAtMostOne(Iterable< Literal > literals)
Definition CpModel.java:173
BoolVar newBoolVar(String name)
Definition CpModel.java:96
Constraint addMinEquality(LinearArgument target, Iterable<? extends LinearArgument > exprs)
Definition CpModel.java:614
void addDecisionStrategy(LinearArgument[] expressions, DecisionStrategyProto.VariableSelectionStrategy varStr, DecisionStrategyProto.DomainReductionStrategy domStr)
DecisionStrategy.
Definition CpModel.java:987
ReservoirConstraint addReservoirConstraint(long minLevel, long maxLevel)
Definition CpModel.java:581
IntervalVar newOptionalIntervalVar(LinearArgument start, LinearArgument size, LinearArgument end, Literal isPresent, String name)
Definition CpModel.java:785
Constraint addBoolAnd(Literal[] literals)
Definition CpModel.java:198
Constraint addDivisionEquality(LinearArgument target, LinearArgument num, LinearArgument denom)
Definition CpModel.java:649
CpModelProto model()
Getters.
TableConstraint addAllowedAssignments(Iterable< IntVar > variables)
Definition CpModel.java:450
Constraint addDifferent(LinearArgument expr, long value)
Definition CpModel.java:324
Constraint addModuloEquality(LinearArgument target, LinearArgument var, LinearArgument mod)
Definition CpModel.java:671
Constraint addMaxEquality(LinearArgument target, LinearArgument[] exprs)
Definition CpModel.java:626
Constraint addAbsEquality(LinearArgument target, LinearArgument expr)
Definition CpModel.java:661
Constraint addBoolOr(Iterable< Literal > literals)
Definition CpModel.java:148
IntervalVar newOptionalFixedSizeIntervalVar(LinearArgument start, long size, Literal isPresent, String name)
Definition CpModel.java:808
CumulativeConstraint addCumulative(long capacity)
Definition CpModel.java:893
AutomatonConstraint addAutomaton(IntVar[] transitionVariables, long startingState, long[] finalStates)
Definition CpModel.java:518
NoOverlap2dConstraint addNoOverlap2D()
Definition CpModel.java:864
Boolean exportToFile(String file)
Constraint addAtLeastOne(Literal[] literals)
Definition CpModel.java:158
Constraint addLinearConstraint(LinearArgument expr, long lb, long ub)
Definition CpModel.java:254
MultipleCircuitConstraint addMultipleCircuit()
Definition CpModel.java:426
IntVar newIntVarFromDomain(Domain domain, String name)
Definition CpModel.java:91
CircuitConstraint addCircuit()
Definition CpModel.java:412
Constraint addGreaterOrEqual(LinearArgument expr, long value)
Definition CpModel.java:298
IntervalVar newOptionalFixedInterval(long start, long size, Literal isPresent, String name)
Definition CpModel.java:819
Constraint addMultiplicationEquality(LinearArgument target, LinearArgument left, LinearArgument right)
Definition CpModel.java:705
Constraint addEquality(LinearArgument left, LinearArgument right)
Definition CpModel.java:264
Constraint addMaxEquality(LinearArgument target, Iterable<? extends LinearArgument > exprs)
Definition CpModel.java:637
Constraint addBoolAnd(Iterable< Literal > literals)
Definition CpModel.java:203
void minimize(LinearArgument expr)
Objective.
Definition CpModel.java:931
Constraint addLessOrEqual(LinearArgument left, LinearArgument right)
Definition CpModel.java:277
Constraint addEquality(LinearArgument expr, long value)
Definition CpModel.java:259
TableConstraint addForbiddenAssignments(Iterable< IntVar > variables)
Definition CpModel.java:479
Constraint addNoOverlap(Iterable< IntervalVar > intervalVars)
Definition CpModel.java:843
void addAssumptions(Literal[] literals)
Definition CpModel.java:917
IntVar newIntVar(long lb, long ub, String name)
Integer variables.
Definition CpModel.java:80
Constraint addExactlyOne(Literal[] literals)
Definition CpModel.java:183
Constraint addAtLeastOne(Iterable< Literal > literals)
Definition CpModel.java:163
Constraint addLessOrEqual(LinearArgument expr, long value)
Definition CpModel.java:272
IntervalVar newFixedSizeIntervalVar(LinearArgument start, long size, String name)
Definition CpModel.java:751
Constraint addLessThan(LinearArgument expr, long value)
Definition CpModel.java:285
Constraint addElement(IntVar index, IntVar[] variables, IntVar target)
Definition CpModel.java:368
TableConstraint addAllowedAssignments(IntVar[] variables)
Definition CpModel.java:441
BoolVar getBoolVarFromProtoIndex(int index)
Definition CpModel.java:131
Constraint addGreaterOrEqual(LinearArgument left, LinearArgument right)
Definition CpModel.java:303
Constraint addMinEquality(LinearArgument target, LinearArgument[] exprs)
Definition CpModel.java:603
Constraint addLessThan(LinearArgument left, LinearArgument right)
Definition CpModel.java:290
CumulativeConstraint addCumulative(LinearArgument capacity)
Definition CpModel.java:881
Constraint addBoolXor(Iterable< Literal > literals)
Definition CpModel.java:218
Constraint addModuloEquality(LinearArgument target, LinearArgument var, long mod)
Definition CpModel.java:683
Constraint addGreaterThan(LinearArgument left, LinearArgument right)
Definition CpModel.java:316
void addMapDomain(IntVar var, Literal[] booleans, long offset)
Definition CpModel.java:595
void addDecisionStrategy(Iterable<? extends LinearArgument > expressions, DecisionStrategyProto.VariableSelectionStrategy varStr, DecisionStrategyProto.DomainReductionStrategy domStr)
Definition CpModel.java:998
Constraint addElement(IntVar index, int[] values, IntVar target)
Definition CpModel.java:392
Constraint addAllDifferent(LinearArgument[] expressions)
Integer constraints.
Definition CpModel.java:349
Constraint addNoOverlap(IntervalVar[] intervalVars)
Definition CpModel.java:834
void maximize(DoubleLinearExpr expr)
Definition CpModel.java:964
Constraint addBoolXor(Literal[] literals)
Definition CpModel.java:213
IntervalVar newFixedInterval(long start, long size, String name)
Definition CpModel.java:761
void maximize(LinearArgument expr)
Definition CpModel.java:952
TableConstraint addForbiddenAssignments(IntVar[] variables)
Definition CpModel.java:470
Constraint addAllDifferent(Iterable<? extends LinearArgument > expressions)
Definition CpModel.java:358
Constraint addExactlyOne(Iterable< Literal > literals)
Definition CpModel.java:188
Constraint addInverse(IntVar[] variables, IntVar[] inverseVariables)
Definition CpModel.java:543
Constraint addAtMostOne(Literal[] literals)
Definition CpModel.java:168
Constraint addElement(IntVar index, long[] values, IntVar target)
Definition CpModel.java:380
IntVar getIntVarFromProtoIndex(int index)
Definition CpModel.java:136
Constraint addImplication(Literal a, Literal b)
Definition CpModel.java:228
void minimize(DoubleLinearExpr expr)
Definition CpModel.java:942
Constraint addLinearExpressionInDomain(LinearArgument expr, Domain domain)
Linear constraints.
Definition CpModel.java:235
Constraint addGreaterThan(LinearArgument expr, long value)
Definition CpModel.java:311
Constraint addMultiplicationEquality(LinearArgument target, LinearArgument[] exprs)
Definition CpModel.java:694
void addAssumption(Literal lit)
Definition CpModel.java:912
CpModelProto.Builder getBuilder()
void addHint(IntVar var, long value)
Definition CpModel.java:901
Constraint addBoolOr(Literal[] literals)
Boolean Constraints.
Definition CpModel.java:143
IntervalVar newIntervalVar(LinearArgument start, LinearArgument size, LinearArgument end, String name)
Scheduling support.
Definition CpModel.java:731
static String validateModel(com.google.ortools.sat.CpModelProto model_proto)
static boolean writeModelToFile(com.google.ortools.sat.CpModelProto model_proto, String filename)
static String modelStats(com.google.ortools.sat.CpModelProto model_proto)
LinearExprBuilder add(LinearArgument expr)
LinearExprBuilder addTerm(LinearArgument expr, long coeff)
static Domain fromFlatIntervals(long[] flat_intervals)
Definition Domain.java:112
static LinearExprBuilder newBuilder()