Java Reference

Java Reference

CpModel.java
Go to the documentation of this file.
1 // Copyright 2010-2022 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 
14 package com.google.ortools.sat;
15 
16 import com.google.ortools.sat.AllDifferentConstraintProto;
17 import com.google.ortools.sat.AutomatonConstraintProto;
18 import com.google.ortools.sat.BoolArgumentProto;
19 import com.google.ortools.sat.CpModelProto;
20 import com.google.ortools.sat.CpObjectiveProto;
21 import com.google.ortools.sat.CumulativeConstraintProto;
22 import com.google.ortools.sat.DecisionStrategyProto;
23 import com.google.ortools.sat.ElementConstraintProto;
24 import com.google.ortools.sat.FloatObjectiveProto;
25 import com.google.ortools.sat.InverseConstraintProto;
26 import com.google.ortools.sat.LinearArgumentProto;
27 import com.google.ortools.sat.LinearConstraintProto;
28 import com.google.ortools.sat.LinearExpressionProto;
29 import com.google.ortools.sat.NoOverlapConstraintProto;
30 import com.google.ortools.sat.ReservoirConstraintProto;
31 import com.google.ortools.sat.TableConstraintProto;
32 import com.google.ortools.util.Domain;
33 import java.util.Arrays;
34 import java.util.LinkedHashMap;
35 import java.util.Map;
36 
42 public 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  // Integer variables.
70 
72  public IntVar newIntVar(long lb, long ub, String name) {
73  return new IntVar(modelBuilder, new Domain(lb, ub), name);
74  }
75 
83  public IntVar newIntVarFromDomain(Domain domain, String name) {
84  return new IntVar(modelBuilder, domain, name);
85  }
86 
88  public BoolVar newBoolVar(String name) {
89  return new BoolVar(modelBuilder, new Domain(0, 1), name);
90  }
91 
93  public IntVar newConstant(long value) {
94  if (constantMap.containsKey(value)) {
95  return new IntVar(modelBuilder, constantMap.get(value));
96  }
97  IntVar cste = new IntVar(modelBuilder, new Domain(value), ""); // bounds and name.
98  constantMap.put(value, cste.getIndex());
99  return cste;
100  }
101 
103  public Literal trueLiteral() {
104  if (constantMap.containsKey(1L)) {
105  return new BoolVar(modelBuilder, constantMap.get(1L));
106  }
107  BoolVar cste = new BoolVar(modelBuilder, new Domain(1), ""); // bounds and name.
108  constantMap.put(1L, cste.getIndex());
109  return cste;
110  }
111 
114  if (constantMap.containsKey(0L)) {
115  return new BoolVar(modelBuilder, constantMap.get(0L));
116  }
117  BoolVar cste = new BoolVar(modelBuilder, new Domain(0), ""); // bounds and name.
118  constantMap.put(0L, cste.getIndex());
119  return cste;
120  }
121 
122  // Boolean Constraints.
123 
125  public Constraint addBoolOr(Literal[] literals) {
126  return addBoolOr(Arrays.asList(literals));
127  }
128 
130  public Constraint addBoolOr(Iterable<Literal> literals) {
131  Constraint ct = new Constraint(modelBuilder);
132  BoolArgumentProto.Builder boolOr = ct.getBuilder().getBoolOrBuilder();
133  for (Literal lit : literals) {
134  boolOr.addLiterals(lit.getIndex());
135  }
136  return ct;
137  }
138 
140  public Constraint addAtLeastOne(Literal[] literals) {
141  return addBoolOr(Arrays.asList(literals));
142  }
143 
145  public Constraint addAtLeastOne(Iterable<Literal> literals) {
146  return addBoolOr(literals);
147  }
148 
150  public Constraint addAtMostOne(Literal[] literals) {
151  return addAtMostOne(Arrays.asList(literals));
152  }
153 
155  public Constraint addAtMostOne(Iterable<Literal> literals) {
156  Constraint ct = new Constraint(modelBuilder);
157  BoolArgumentProto.Builder atMostOne = ct.getBuilder().getAtMostOneBuilder();
158  for (Literal lit : literals) {
159  atMostOne.addLiterals(lit.getIndex());
160  }
161  return ct;
162  }
163 
165  public Constraint addExactlyOne(Literal[] literals) {
166  return addExactlyOne(Arrays.asList(literals));
167  }
168 
170  public Constraint addExactlyOne(Iterable<Literal> literals) {
171  Constraint ct = new Constraint(modelBuilder);
172  BoolArgumentProto.Builder exactlyOne = ct.getBuilder().getExactlyOneBuilder();
173  for (Literal lit : literals) {
174  exactlyOne.addLiterals(lit.getIndex());
175  }
176  return ct;
177  }
178 
180  public Constraint addBoolAnd(Literal[] literals) {
181  return addBoolAnd(Arrays.asList(literals));
182  }
183 
185  public Constraint addBoolAnd(Iterable<Literal> literals) {
186  Constraint ct = new Constraint(modelBuilder);
187  BoolArgumentProto.Builder boolAnd = ct.getBuilder().getBoolAndBuilder();
188  for (Literal lit : literals) {
189  boolAnd.addLiterals(lit.getIndex());
190  }
191  return ct;
192  }
193 
195  public Constraint addBoolXor(Literal[] literals) {
196  return addBoolXor(Arrays.asList(literals));
197  }
198 
200  public Constraint addBoolXor(Iterable<Literal> literals) {
201  Constraint ct = new Constraint(modelBuilder);
202  BoolArgumentProto.Builder boolXOr = ct.getBuilder().getBoolXorBuilder();
203  for (Literal lit : literals) {
204  boolXOr.addLiterals(lit.getIndex());
205  }
206  return ct;
207  }
208 
211  return addBoolOr(new Literal[] {a.not(), b});
212  }
213 
214  // Linear constraints.
215 
218  Constraint ct = new Constraint(modelBuilder);
219  LinearConstraintProto.Builder lin = ct.getBuilder().getLinearBuilder();
220  final LinearExpr e = expr.build();
221  for (int i = 0; i < e.numElements(); ++i) {
222  lin.addVars(e.getVariableIndex(i)).addCoeffs(e.getCoefficient(i));
223  }
224  long offset = e.getOffset();
225  for (long b : domain.flattenedIntervals()) {
226  if (b == Long.MIN_VALUE || b == Long.MAX_VALUE) {
227  lin.addDomain(b);
228  } else {
229  lin.addDomain(b - offset);
230  }
231  }
232  return ct;
233  }
234 
236  public Constraint addLinearConstraint(LinearArgument expr, long lb, long ub) {
237  return addLinearExpressionInDomain(expr, new Domain(lb, ub));
238  }
239 
241  public Constraint addEquality(LinearArgument expr, long value) {
242  return addLinearExpressionInDomain(expr, new Domain(value));
243  }
244 
247  LinearExprBuilder difference = LinearExpr.newBuilder();
248  difference.addTerm(left, 1);
249  difference.addTerm(right, -1);
250  return addLinearExpressionInDomain(difference, new Domain(0));
251  }
252 
254  public Constraint addLessOrEqual(LinearArgument expr, long value) {
255  return addLinearExpressionInDomain(expr, new Domain(Long.MIN_VALUE, value));
256  }
257 
260  LinearExprBuilder difference = LinearExpr.newBuilder();
261  difference.addTerm(left, 1);
262  difference.addTerm(right, -1);
263  return addLinearExpressionInDomain(difference, new Domain(Long.MIN_VALUE, 0));
264  }
265 
267  public Constraint addLessThan(LinearArgument expr, long value) {
268  return addLinearExpressionInDomain(expr, new Domain(Long.MIN_VALUE, value - 1));
269  }
270 
273  LinearExprBuilder difference = LinearExpr.newBuilder();
274  difference.addTerm(left, 1);
275  difference.addTerm(right, -1);
276  return addLinearExpressionInDomain(difference, new Domain(Long.MIN_VALUE, -1));
277  }
278 
280  public Constraint addGreaterOrEqual(LinearArgument expr, long value) {
281  return addLinearExpressionInDomain(expr, new Domain(value, Long.MAX_VALUE));
282  }
283 
286  LinearExprBuilder difference = LinearExpr.newBuilder();
287  difference.addTerm(left, 1);
288  difference.addTerm(right, -1);
289  return addLinearExpressionInDomain(difference, new Domain(0, Long.MAX_VALUE));
290  }
291 
293  public Constraint addGreaterThan(LinearArgument expr, long value) {
294  return addLinearExpressionInDomain(expr, new Domain(value + 1, Long.MAX_VALUE));
295  }
296 
299  LinearExprBuilder difference = LinearExpr.newBuilder();
300  difference.addTerm(left, 1);
301  difference.addTerm(right, -1);
302  return addLinearExpressionInDomain(difference, new Domain(1, Long.MAX_VALUE));
303  }
304 
306  public Constraint addDifferent(LinearArgument expr, long value) {
307  return addLinearExpressionInDomain(expr,
308  Domain.fromFlatIntervals(
309  new long[] {Long.MIN_VALUE, value - 1, value + 1, Long.MAX_VALUE}));
310  }
311 
314  LinearExprBuilder difference = LinearExpr.newBuilder();
315  difference.addTerm(left, 1);
316  difference.addTerm(right, -1);
318  difference, Domain.fromFlatIntervals(new long[] {Long.MIN_VALUE, -1, 1, Long.MAX_VALUE}));
319  }
320 
321  // Integer constraints.
322 
331  public Constraint addAllDifferent(LinearArgument[] expressions) {
332  return addAllDifferent(Arrays.asList(expressions));
333  }
334 
340  public Constraint addAllDifferent(Iterable<? extends LinearArgument> expressions) {
341  Constraint ct = new Constraint(modelBuilder);
342  AllDifferentConstraintProto.Builder allDiff = ct.getBuilder().getAllDiffBuilder();
343  for (LinearArgument expr : expressions) {
344  allDiff.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/false));
345  }
346  return ct;
347  }
348 
350  public Constraint addElement(IntVar index, IntVar[] variables, IntVar target) {
351  Constraint ct = new Constraint(modelBuilder);
352  ElementConstraintProto.Builder element =
353  ct.getBuilder().getElementBuilder().setIndex(index.getIndex());
354  for (IntVar var : variables) {
355  element.addVars(var.getIndex());
356  }
357  element.setTarget(target.getIndex());
358  return ct;
359  }
360 
362  public Constraint addElement(IntVar index, long[] values, IntVar target) {
363  Constraint ct = new Constraint(modelBuilder);
364  ElementConstraintProto.Builder element =
365  ct.getBuilder().getElementBuilder().setIndex(index.getIndex());
366  for (long v : values) {
367  element.addVars(newConstant(v).getIndex());
368  }
369  element.setTarget(target.getIndex());
370  return ct;
371  }
372 
374  public Constraint addElement(IntVar index, int[] values, IntVar target) {
375  Constraint ct = new Constraint(modelBuilder);
376  ElementConstraintProto.Builder element =
377  ct.getBuilder().getElementBuilder().setIndex(index.getIndex());
378  for (long v : values) {
379  element.addVars(newConstant(v).getIndex());
380  }
381  element.setTarget(target.getIndex());
382  return ct;
383  }
384 
395  return new CircuitConstraint(modelBuilder);
396  }
397 
409  return new MultipleCircuitConstraint(modelBuilder);
410  }
411 
424  return addAllowedAssignments(Arrays.asList(variables));
425  }
426 
432  public TableConstraint addAllowedAssignments(Iterable<IntVar> variables) {
433  TableConstraint ct = new TableConstraint(modelBuilder);
434  TableConstraintProto.Builder table = ct.getBuilder().getTableBuilder();
435  for (IntVar var : variables) {
436  table.addVars(var.getIndex());
437  }
438  table.setNegated(false);
439  return ct;
440  }
441 
453  return addForbiddenAssignments(Arrays.asList(variables));
454  }
455 
461  public TableConstraint addForbiddenAssignments(Iterable<IntVar> variables) {
462  TableConstraint ct = new TableConstraint(modelBuilder);
463  TableConstraintProto.Builder table = ct.getBuilder().getTableBuilder();
464  for (IntVar var : variables) {
465  table.addVars(var.getIndex());
466  }
467  table.setNegated(true);
468  return ct;
469  }
470 
501  IntVar[] transitionVariables, long startingState, long[] finalStates) {
502  AutomatonConstraint ct = new AutomatonConstraint(modelBuilder);
503  AutomatonConstraintProto.Builder automaton = ct.getBuilder().getAutomatonBuilder();
504  for (IntVar var : transitionVariables) {
505  automaton.addVars(var.getIndex());
506  }
507  automaton.setStartingState(startingState);
508  for (long c : finalStates) {
509  automaton.addFinalStates(c);
510  }
511  return ct;
512  }
513 
525  public Constraint addInverse(IntVar[] variables, IntVar[] inverseVariables) {
526  if (variables.length != inverseVariables.length) {
527  throw new MismatchedArrayLengths("CpModel.addInverse", "variables", "inverseVariables");
528  }
529  Constraint ct = new Constraint(modelBuilder);
530  InverseConstraintProto.Builder inverse = ct.getBuilder().getInverseBuilder();
531  for (IntVar var : variables) {
532  inverse.addFDirect(var.getIndex());
533  }
534  for (IntVar var : inverseVariables) {
535  inverse.addFInverse(var.getIndex());
536  }
537  return ct;
538  }
539 
563  public ReservoirConstraint addReservoirConstraint(long minLevel, long maxLevel) {
564  if (minLevel > 0) {
565  throw new IllegalArgumentException("CpModel.addReservoirConstraint: minLevel must be <= 0");
566  }
567  if (maxLevel < 0) {
568  throw new IllegalArgumentException("CpModel.addReservoirConstraint: maxLevel must be >= 0");
569  }
571  ReservoirConstraintProto.Builder reservoir = ct.getBuilder().getReservoirBuilder();
572  reservoir.setMinLevel(minLevel).setMaxLevel(maxLevel);
573  return ct;
574  }
575 
577  public void addMapDomain(IntVar var, Literal[] booleans, long offset) {
578  for (int i = 0; i < booleans.length; ++i) {
579  addEquality(var, offset + i).onlyEnforceIf(booleans[i]);
580  addDifferent(var, offset + i).onlyEnforceIf(booleans[i].not());
581  }
582  }
583 
586  Constraint ct = new Constraint(modelBuilder);
587  LinearArgumentProto.Builder linMax = ct.getBuilder().getLinMaxBuilder();
588  linMax.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/true));
589  for (LinearArgument expr : exprs) {
590  linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/true));
591  }
592  return ct;
593  }
594 
597  LinearArgument target, Iterable<? extends LinearArgument> exprs) {
598  Constraint ct = new Constraint(modelBuilder);
599  LinearArgumentProto.Builder linMax = ct.getBuilder().getLinMaxBuilder();
600  linMax.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/true));
601  for (LinearArgument expr : exprs) {
602  linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/true));
603  }
604  return ct;
605  }
606 
609  Constraint ct = new Constraint(modelBuilder);
610  LinearArgumentProto.Builder linMax = ct.getBuilder().getLinMaxBuilder();
611  linMax.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false));
612  for (LinearArgument expr : exprs) {
613  linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/false));
614  }
615  return ct;
616  }
617 
620  LinearArgument target, Iterable<? extends LinearArgument> exprs) {
621  Constraint ct = new Constraint(modelBuilder);
622  LinearArgumentProto.Builder linMax = ct.getBuilder().getLinMaxBuilder();
623  linMax.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false));
624  for (LinearArgument expr : exprs) {
625  linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/false));
626  }
627  return ct;
628  }
629 
632  LinearArgument target, LinearArgument num, LinearArgument denom) {
633  Constraint ct = new Constraint(modelBuilder);
634  ct.getBuilder()
635  .getIntDivBuilder()
636  .setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false))
637  .addExprs(getLinearExpressionProtoBuilderFromLinearArgument(num, /*negate=*/false))
638  .addExprs(getLinearExpressionProtoBuilderFromLinearArgument(denom, /*negate=*/false));
639  return ct;
640  }
641 
644  Constraint ct = new Constraint(modelBuilder);
645  LinearArgumentProto.Builder linMax = ct.getBuilder().getLinMaxBuilder();
646  linMax.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false));
647  linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/false));
648  linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/true));
649  return ct;
650  }
651 
654  LinearArgument target, LinearArgument var, LinearArgument mod) {
655  Constraint ct = new Constraint(modelBuilder);
656  ct.getBuilder()
657  .getIntModBuilder()
658  .setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false))
659  .addExprs(getLinearExpressionProtoBuilderFromLinearArgument(var, /*negate=*/false))
660  .addExprs(getLinearExpressionProtoBuilderFromLinearArgument(mod, /*negate=*/false));
661  return ct;
662  }
663 
666  Constraint ct = new Constraint(modelBuilder);
667  ct.getBuilder()
668  .getIntModBuilder()
669  .setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false))
670  .addExprs(getLinearExpressionProtoBuilderFromLinearArgument(var, /*negate=*/false))
671  .addExprs(getLinearExpressionProtoBuilderFromLong(mod));
672  return ct;
673  }
674 
677  Constraint ct = new Constraint(modelBuilder);
678  LinearArgumentProto.Builder intProd = ct.getBuilder().getIntProdBuilder();
679  intProd.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false));
680  for (LinearArgument expr : exprs) {
681  intProd.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr, /*negate=*/false));
682  }
683  return ct;
684  }
685 
688  LinearArgument target, LinearArgument left, LinearArgument right) {
689  Constraint ct = new Constraint(modelBuilder);
690  LinearArgumentProto.Builder intProd = ct.getBuilder().getIntProdBuilder();
691  intProd.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target, /*negate=*/false));
692  intProd.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(left, /*negate=*/false));
693  intProd.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(right, /*negate=*/false));
694  return ct;
695  }
696 
697  // Scheduling support.
698 
714  LinearArgument start, LinearArgument size, LinearArgument end, String name) {
715  addEquality(LinearExpr.newBuilder().add(start).add(size), end);
716  return new IntervalVar(modelBuilder,
717  getLinearExpressionProtoBuilderFromLinearArgument(start, /*negate=*/false),
718  getLinearExpressionProtoBuilderFromLinearArgument(size, /*negate=*/false),
719  getLinearExpressionProtoBuilderFromLinearArgument(end, /*negate=*/false), name);
720  }
721 
733  public IntervalVar newFixedSizeIntervalVar(LinearArgument start, long size, String name) {
734  return new IntervalVar(modelBuilder,
735  getLinearExpressionProtoBuilderFromLinearArgument(start, /*negate=*/false),
736  getLinearExpressionProtoBuilderFromLong(size),
737  getLinearExpressionProtoBuilderFromLinearArgument(
738  LinearExpr.newBuilder().add(start).add(size), /*negate=*/false),
739  name);
740  }
741 
743  public IntervalVar newFixedInterval(long start, long size, String name) {
744  return new IntervalVar(modelBuilder, getLinearExpressionProtoBuilderFromLong(start),
745  getLinearExpressionProtoBuilderFromLong(size),
746  getLinearExpressionProtoBuilderFromLong(start + size), name);
747  }
748 
768  LinearArgument end, Literal isPresent, String name) {
769  addEquality(LinearExpr.newBuilder().add(start).add(size), end).onlyEnforceIf(isPresent);
770  return new IntervalVar(modelBuilder,
771  getLinearExpressionProtoBuilderFromLinearArgument(start, /*negate=*/false),
772  getLinearExpressionProtoBuilderFromLinearArgument(size, /*negate=*/false),
773  getLinearExpressionProtoBuilderFromLinearArgument(end, /*negate=*/false),
774  isPresent.getIndex(), name);
775  }
776 
791  LinearArgument start, long size, Literal isPresent, String name) {
792  return new IntervalVar(modelBuilder,
793  getLinearExpressionProtoBuilderFromLinearArgument(start, /*negate=*/false),
794  getLinearExpressionProtoBuilderFromLong(size),
795  getLinearExpressionProtoBuilderFromLinearArgument(
796  LinearExpr.newBuilder().add(start).add(size), /*negate=*/false),
797  isPresent.getIndex(), name);
798  }
799 
802  long start, long size, Literal isPresent, String name) {
803  return new IntervalVar(modelBuilder, getLinearExpressionProtoBuilderFromLong(start),
804  getLinearExpressionProtoBuilderFromLong(size),
805  getLinearExpressionProtoBuilderFromLong(start + size), isPresent.getIndex(), name);
806  }
807 
816  public Constraint addNoOverlap(IntervalVar[] intervalVars) {
817  return addNoOverlap(Arrays.asList(intervalVars));
818  }
819 
825  public Constraint addNoOverlap(Iterable<IntervalVar> intervalVars) {
826  Constraint ct = new Constraint(modelBuilder);
827  NoOverlapConstraintProto.Builder noOverlap = ct.getBuilder().getNoOverlapBuilder();
828  for (IntervalVar var : intervalVars) {
829  noOverlap.addIntervals(var.getIndex());
830  }
831  return ct;
832  }
833 
847  return new NoOverlap2dConstraint(modelBuilder);
848  }
849 
865  CumulativeConstraintProto.Builder cumul = ct.getBuilder().getCumulativeBuilder();
866  cumul.setCapacity(getLinearExpressionProtoBuilderFromLinearArgument(capacity, false));
867  return ct;
868  }
869 
875  public CumulativeConstraint addCumulative(long capacity) {
877  CumulativeConstraintProto.Builder cumul = ct.getBuilder().getCumulativeBuilder();
878  cumul.setCapacity(getLinearExpressionProtoBuilderFromLong(capacity));
879  return ct;
880  }
881 
883  public void addHint(IntVar var, long value) {
884  modelBuilder.getSolutionHintBuilder().addVars(var.getIndex());
885  modelBuilder.getSolutionHintBuilder().addValues(value);
886  }
887 
889  public void clearHints() {
890  modelBuilder.clearSolutionHint();
891  }
892 
894  public void addAssumption(Literal lit) {
895  modelBuilder.addAssumptions(lit.getIndex());
896  }
897 
899  public void addAssumptions(Literal[] literals) {
900  for (Literal lit : literals) {
901  addAssumption(lit);
902  }
903  }
904 
906  public void clearAssumptions() {
907  modelBuilder.clearAssumptions();
908  }
909 
910  // Objective.
911 
913  public void minimize(LinearArgument expr) {
914  clearObjective();
915  CpObjectiveProto.Builder obj = modelBuilder.getObjectiveBuilder();
916  final LinearExpr e = expr.build();
917  for (int i = 0; i < e.numElements(); ++i) {
918  obj.addVars(e.getVariableIndex(i)).addCoeffs(e.getCoefficient(i));
919  }
920  obj.setOffset((double) e.getOffset());
921  }
922 
924  public void minimize(DoubleLinearExpr expr) {
925  clearObjective();
926  FloatObjectiveProto.Builder obj = modelBuilder.getFloatingPointObjectiveBuilder();
927  for (int i = 0; i < expr.numElements(); ++i) {
928  obj.addVars(expr.getVariableIndex(i)).addCoeffs(expr.getCoefficient(i));
929  }
930  obj.setOffset(expr.getOffset()).setMaximize(false);
931  }
932 
934  public void maximize(LinearArgument expr) {
935  clearObjective();
936  CpObjectiveProto.Builder obj = modelBuilder.getObjectiveBuilder();
937  final LinearExpr e = expr.build();
938  for (int i = 0; i < e.numElements(); ++i) {
939  obj.addVars(e.getVariableIndex(i)).addCoeffs(-e.getCoefficient(i));
940  }
941  obj.setOffset((double) -e.getOffset());
942  obj.setScalingFactor(-1.0);
943  }
944 
946  public void maximize(DoubleLinearExpr expr) {
947  clearObjective();
948  FloatObjectiveProto.Builder obj = modelBuilder.getFloatingPointObjectiveBuilder();
949  for (int i = 0; i < expr.numElements(); ++i) {
950  obj.addVars(expr.getVariableIndex(i)).addCoeffs(expr.getCoefficient(i));
951  }
952  obj.setOffset(expr.getOffset()).setMaximize(true);
953  }
954 
956  public void clearObjective() {
957  modelBuilder.clearObjective();
958  modelBuilder.clearFloatingPointObjective();
959  }
960 
962  public boolean hasObjective() {
963  return modelBuilder.hasObjective() || modelBuilder.hasFloatingPointObjective();
964  }
965 
966  // DecisionStrategy
967 
969  public void addDecisionStrategy(IntVar[] variables,
970  DecisionStrategyProto.VariableSelectionStrategy varStr,
971  DecisionStrategyProto.DomainReductionStrategy domStr) {
972  DecisionStrategyProto.Builder ds = modelBuilder.addSearchStrategyBuilder();
973  for (IntVar var : variables) {
974  ds.addVariables(var.getIndex());
975  }
976  ds.setVariableSelectionStrategy(varStr).setDomainReductionStrategy(domStr);
977  }
978 
980  public String modelStats() {
981  return CpSatHelper.modelStats(model());
982  }
983 
985  public String validate() {
986  return CpSatHelper.validateModel(model());
987  }
988 
997  public Boolean exportToFile(String file) {
998  return CpSatHelper.writeModelToFile(model(), file);
999  }
1000 
1001  // Helpers
1002  LinearExpressionProto.Builder getLinearExpressionProtoBuilderFromLinearArgument(
1003  LinearArgument arg, boolean negate) {
1004  LinearExpressionProto.Builder builder = LinearExpressionProto.newBuilder();
1005  final LinearExpr expr = arg.build();
1006  final int numVariables = expr.numElements();
1007  final long mult = negate ? -1 : 1;
1008  for (int i = 0; i < numVariables; ++i) {
1009  builder.addVars(expr.getVariableIndex(i));
1010  builder.addCoeffs(expr.getCoefficient(i) * mult);
1011  }
1012  builder.setOffset(expr.getOffset() * mult);
1013  return builder;
1014  }
1015 
1016  LinearExpressionProto.Builder getLinearExpressionProtoBuilderFromLong(long value) {
1017  LinearExpressionProto.Builder builder = LinearExpressionProto.newBuilder();
1018  builder.setOffset(value);
1019  return builder;
1020  }
1021 
1022  // Getters.
1023 
1024  public CpModelProto model() {
1025  return modelBuilder.build();
1026  }
1027 
1028  public int negated(int index) {
1029  return -index - 1;
1030  }
1031 
1033  public CpModelProto.Builder getBuilder() {
1034  return modelBuilder;
1035  }
1036 
1037  private final CpModelProto.Builder modelBuilder;
1038  private final Map<Long, Integer> constantMap;
1039 }
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: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 addLessThan(LinearArgument expr, long value)
Adds.
Definition: CpModel.java:267
Constraint addLinearExpressionInDomain(LinearArgument expr, Domain domain)
Adds.
Definition: CpModel.java:217
Constraint addEquality(LinearArgument expr, long value)
Adds.
Definition: CpModel.java:241
CumulativeConstraint addCumulative(LinearArgument capacity)
Adds.
Definition: CpModel.java:863
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:790
IntVar newConstant(long value)
Creates a constant variable.
Definition: CpModel.java:93
NoOverlap2dConstraint addNoOverlap2D()
Adds.
Definition: CpModel.java:846
Constraint addAbsEquality(LinearArgument target, LinearArgument expr)
Adds.
Definition: CpModel.java:643
ReservoirConstraint addReservoirConstraint(long minLevel, long maxLevel)
Adds a reservoir constraint with optional refill/emptying events.
Definition: CpModel.java:563
void clearAssumptions()
Remove all assumptions from the model.
Definition: CpModel.java:906
Constraint addLessOrEqual(LinearArgument left, LinearArgument right)
Adds.
Definition: CpModel.java:259
TableConstraint addForbiddenAssignments(Iterable< IntVar > variables)
Adds.
Definition: CpModel.java:461
Constraint addMultiplicationEquality(LinearArgument target, LinearArgument[] exprs)
Adds.
Definition: CpModel.java:676
Constraint addMaxEquality(LinearArgument target, Iterable<? extends LinearArgument > exprs)
Adds.
Definition: CpModel.java:619
Constraint addAllDifferent(Iterable<? extends LinearArgument > expressions)
Adds.
Definition: CpModel.java:340
void maximize(DoubleLinearExpr expr)
Adds a maximization objective of a linear expression.
Definition: CpModel.java:946
CumulativeConstraint addCumulative(long capacity)
Adds.
Definition: CpModel.java:875
Boolean exportToFile(String file)
Write the model as a protocol buffer to 'file'.
Definition: CpModel.java:997
BoolVar newBoolVar(String name)
Creates a Boolean variable with the given name.
Definition: CpModel.java:88
TableConstraint addAllowedAssignments(IntVar[] variables)
Adds.
Definition: CpModel.java:423
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:801
Constraint addElement(IntVar index, long[] values, IntVar target)
Adds the element constraint:
Definition: CpModel.java:362
Constraint addBoolXor(Iterable< Literal > literals)
Adds.
Definition: CpModel.java:200
CircuitConstraint addCircuit()
Adds.
Definition: CpModel.java:394
Literal falseLiteral()
Returns the false literal.
Definition: CpModel.java:113
void addAssumptions(Literal[] literals)
Adds multiple literals to the model as assumptions.
Definition: CpModel.java:899
Constraint addExactlyOne(Literal[] literals)
Adds.
Definition: CpModel.java:165
Constraint addAtLeastOne(Literal[] literals)
Same as addBoolOr.
Definition: CpModel.java:140
void maximize(LinearArgument expr)
Adds a maximization objective of a linear expression.
Definition: CpModel.java:934
Constraint addGreaterThan(LinearArgument left, LinearArgument right)
Adds.
Definition: CpModel.java:298
TableConstraint addAllowedAssignments(Iterable< IntVar > variables)
Adds.
Definition: CpModel.java:432
void addAssumption(Literal lit)
Adds a literal to the model as assumption.
Definition: CpModel.java:894
IntervalVar newFixedSizeIntervalVar(LinearArgument start, long size, String name)
Creates an interval variable from an affine expression start, and a fixed size.
Definition: CpModel.java:733
void clearObjective()
Clears the objective.
Definition: CpModel.java:956
void addHint(IntVar var, long value)
Adds hinting to a variable.
Definition: CpModel.java:883
IntervalVar newFixedInterval(long start, long size, String name)
Creates a fixed interval from its start and its size.
Definition: CpModel.java:743
Constraint addAtMostOne(Literal[] literals)
Adds.
Definition: CpModel.java:150
Constraint addLessThan(LinearArgument left, LinearArgument right)
Adds.
Definition: CpModel.java:272
Constraint addDivisionEquality(LinearArgument target, LinearArgument num, LinearArgument denom)
Adds.
Definition: CpModel.java:631
boolean hasObjective()
Checks if the model contains an objective.
Definition: CpModel.java:962
String modelStats()
Returns some statistics on model as a string.
Definition: CpModel.java:980
Constraint addElement(IntVar index, IntVar[] variables, IntVar target)
Adds the element constraint:
Definition: CpModel.java:350
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:713
Constraint addNoOverlap(Iterable< IntervalVar > intervalVars)
Adds.
Definition: CpModel.java:825
Constraint addGreaterThan(LinearArgument expr, long value)
Adds.
Definition: CpModel.java:293
Constraint addAtMostOne(Iterable< Literal > literals)
Adds.
Definition: CpModel.java:155
Constraint addBoolOr(Iterable< Literal > literals)
Adds.
Definition: CpModel.java:130
Constraint addImplication(Literal a, Literal b)
Adds.
Definition: CpModel.java:210
Constraint addBoolXor(Literal[] literals)
Adds.
Definition: CpModel.java:195
Constraint addMaxEquality(LinearArgument target, LinearArgument[] exprs)
Adds.
Definition: CpModel.java:608
Constraint addGreaterOrEqual(LinearArgument expr, long value)
Adds.
Definition: CpModel.java:280
void minimize(DoubleLinearExpr expr)
Adds a minimization objective of a linear expression.
Definition: CpModel.java:924
IntVar newIntVar(long lb, long ub, String name)
Creates an integer variable with domain [lb, ub].
Definition: CpModel.java:72
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:767
MultipleCircuitConstraint addMultipleCircuit()
Adds.
Definition: CpModel.java:408
Constraint addDifferent(LinearArgument expr, long value)
Adds.
Definition: CpModel.java:306
Constraint addDifferent(LinearArgument left, LinearArgument right)
Adds.
Definition: CpModel.java:313
AutomatonConstraint addAutomaton(IntVar[] transitionVariables, long startingState, long[] finalStates)
Adds an automaton constraint.
Definition: CpModel.java:500
void addMapDomain(IntVar var, Literal[] booleans, long offset)
Adds.
Definition: CpModel.java:577
void addDecisionStrategy(IntVar[] variables, DecisionStrategyProto.VariableSelectionStrategy varStr, DecisionStrategyProto.DomainReductionStrategy domStr)
Adds.
Definition: CpModel.java:969
Constraint addInverse(IntVar[] variables, IntVar[] inverseVariables)
Adds.
Definition: CpModel.java:525
Constraint addModuloEquality(LinearArgument target, LinearArgument var, LinearArgument mod)
Adds.
Definition: CpModel.java:653
Constraint addNoOverlap(IntervalVar[] intervalVars)
Adds.
Definition: CpModel.java:816
Literal trueLiteral()
Returns the true literal.
Definition: CpModel.java:103
Constraint addElement(IntVar index, int[] values, IntVar target)
Adds the element constraint:
Definition: CpModel.java:374
Constraint addLessOrEqual(LinearArgument expr, long value)
Adds.
Definition: CpModel.java:254
void clearHints()
Remove all solution hints.
Definition: CpModel.java:889
Constraint addEquality(LinearArgument left, LinearArgument right)
Adds.
Definition: CpModel.java:246
String validate()
Returns a non empty string explaining the issue if the model is invalid.
Definition: CpModel.java:985
void minimize(LinearArgument expr)
Adds a minimization objective of a linear expression.
Definition: CpModel.java:913
Constraint addMultiplicationEquality(LinearArgument target, LinearArgument left, LinearArgument right)
Adds.
Definition: CpModel.java:687
Constraint addBoolOr(Literal[] literals)
Adds.
Definition: CpModel.java:125
Constraint addExactlyOne(Iterable< Literal > literals)
Adds.
Definition: CpModel.java:170
IntVar newIntVarFromDomain(Domain domain, String name)
Creates an integer variable with given domain.
Definition: CpModel.java:83
Constraint addModuloEquality(LinearArgument target, LinearArgument var, long mod)
Adds.
Definition: CpModel.java:665
Constraint addLinearConstraint(LinearArgument expr, long lb, long ub)
Adds.
Definition: CpModel.java:236
Constraint addBoolAnd(Iterable< Literal > literals)
Adds.
Definition: CpModel.java:185
Constraint addBoolAnd(Literal[] literals)
Adds.
Definition: CpModel.java:180
TableConstraint addForbiddenAssignments(IntVar[] variables)
Adds.
Definition: CpModel.java:452
Constraint addAtLeastOne(Iterable< Literal > literals)
Same as addBoolOr.
Definition: CpModel.java:145
Constraint addMinEquality(LinearArgument target, Iterable<? extends LinearArgument > exprs)
Adds.
Definition: CpModel.java:596
Constraint addAllDifferent(LinearArgument[] expressions)
Adds.
Definition: CpModel.java:331
CpModelProto.Builder getBuilder()
Returns the model builder.
Definition: CpModel.java:1033
Constraint addGreaterOrEqual(LinearArgument left, LinearArgument right)
Adds.
Definition: CpModel.java:285
Constraint addMinEquality(LinearArgument target, LinearArgument[] exprs)
Adds.
Definition: CpModel.java:585
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).
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.
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.