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