Java Reference

Java Reference

CpModel.java
Go to the documentation of this file.
1 // Copyright 2010-2018 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.CircuitConstraintProto;
20 import com.google.ortools.sat.CpModelProto;
21 import com.google.ortools.sat.CpObjectiveProto;
22 import com.google.ortools.sat.CumulativeConstraintProto;
23 import com.google.ortools.sat.DecisionStrategyProto;
24 import com.google.ortools.sat.ElementConstraintProto;
25 import com.google.ortools.sat.IntegerArgumentProto;
26 import com.google.ortools.sat.InverseConstraintProto;
27 import com.google.ortools.sat.LinearConstraintProto;
28 import com.google.ortools.sat.NoOverlap2DConstraintProto;
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.LinkedHashMap;
34 import java.util.Map;
35 
41 public final class CpModel {
42  static class CpModelException extends Exception {
43  public CpModelException(String methodName, String msg) {
44  // Call constructor of parent Exception
45  super(methodName + ": " + msg);
46  }
47  }
48 
50  public static class MismatchedArrayLengths extends CpModelException {
51  public MismatchedArrayLengths(String methodName, String array1Name, String array2Name) {
52  super(methodName, array1Name + " and " + array2Name + " have mismatched lengths");
53  }
54  }
55 
57  public static class WrongLength extends CpModelException {
58  public WrongLength(String methodName, String msg) {
59  super(methodName, msg);
60  }
61  }
62  public CpModel() {
63  modelBuilder = CpModelProto.newBuilder();
64  constantMap = new LinkedHashMap<>();
65  }
66 
67  // Integer variables.
68 
70  public IntVar newIntVar(long lb, long ub, String name) {
71  return new IntVar(modelBuilder, new Domain(lb, ub), name);
72  }
73 
81  public IntVar newIntVarFromDomain(Domain domain, String name) {
82  return new IntVar(modelBuilder, domain, name);
83  }
84 
86  public IntVar newBoolVar(String name) {
87  return new IntVar(modelBuilder, new Domain(0, 1), name);
88  }
89 
91  public IntVar newConstant(long value) {
92  if (constantMap.containsKey(value)) {
93  return constantMap.get(value);
94  }
95  IntVar cste = new IntVar(modelBuilder, new Domain(value), ""); // bounds and name.
96  constantMap.put(value, cste);
97  return cste;
98  }
99 
101  public Literal trueLiteral() {
102  return newConstant(1);
103  }
104 
107  return newConstant(0);
108  }
109 
110  // Boolean Constraints.
111 
113  public Constraint addBoolOr(Literal[] literals) {
114  Constraint ct = new Constraint(modelBuilder);
115  BoolArgumentProto.Builder boolOr = ct.getBuilder().getBoolOrBuilder();
116  for (Literal lit : literals) {
117  boolOr.addLiterals(lit.getIndex());
118  }
119  return ct;
120  }
121 
123  public Constraint addBoolAnd(Literal[] literals) {
124  Constraint ct = new Constraint(modelBuilder);
125  BoolArgumentProto.Builder boolOr = ct.getBuilder().getBoolAndBuilder();
126  for (Literal lit : literals) {
127  boolOr.addLiterals(lit.getIndex());
128  }
129  return ct;
130  }
131 
133  public Constraint addBoolXor(Literal[] literals) {
134  Constraint ct = new Constraint(modelBuilder);
135  BoolArgumentProto.Builder boolOr = ct.getBuilder().getBoolXorBuilder();
136  for (Literal lit : literals) {
137  boolOr.addLiterals(lit.getIndex());
138  }
139  return ct;
140  }
141 
144  return addBoolOr(new Literal[] {a.not(), b});
145  }
146 
147  // Linear constraints.
148 
151  Constraint ct = new Constraint(modelBuilder);
152  LinearConstraintProto.Builder lin = ct.getBuilder().getLinearBuilder();
153  for (int i = 0; i < expr.numElements(); ++i) {
154  lin.addVars(expr.getVariable(i).getIndex()).addCoeffs(expr.getCoefficient(i));
155  }
156  long offset = expr.getOffset();
157  if (offset != 0) {
158  lin.addVars(newConstant(1).getIndex()).addCoeffs(offset);
159  }
160  for (long b : domain.flattenedIntervals()) {
161  lin.addDomain(b);
162  }
163  return ct;
164  }
165 
167  public Constraint addLinearConstraint(LinearExpr expr, long lb, long ub) {
168  return addLinearExpressionInDomain(expr, new Domain(lb, ub));
169  }
170 
172  public Constraint addEquality(LinearExpr expr, long value) {
173  return addLinearExpressionInDomain(expr, new Domain(value));
174  }
175 
178  return addLinearExpressionInDomain(new Difference(left, right), new Domain(0));
179  }
180 
182  public Constraint addEqualityWithOffset(LinearExpr left, LinearExpr right, long offset) {
183  return addLinearExpressionInDomain(new Difference(left, right), new Domain(-offset));
184  }
185 
187  public Constraint addLessOrEqual(LinearExpr expr, long value) {
188  return addLinearExpressionInDomain(expr, new Domain(Long.MIN_VALUE, value));
189  }
190 
193  return addLinearExpressionInDomain(new Difference(left, right), new Domain(Long.MIN_VALUE, 0));
194  }
195 
197  public Constraint addLessThan(LinearExpr expr, long value) {
198  return addLinearExpressionInDomain(expr, new Domain(Long.MIN_VALUE, value - 1));
199  }
200 
203  return addLinearExpressionInDomain(new Difference(left, right), new Domain(Long.MIN_VALUE, -1));
204  }
205 
207  public Constraint addLessOrEqualWithOffset(LinearExpr left, LinearExpr right, long offset) {
209  new Difference(left, right), new Domain(Long.MIN_VALUE, -offset));
210  }
211 
213  public Constraint addGreaterOrEqual(LinearExpr expr, long value) {
214  return addLinearExpressionInDomain(expr, new Domain(value, Long.MAX_VALUE));
215  }
216 
219  return addLinearExpressionInDomain(new Difference(left, right), new Domain(0, Long.MAX_VALUE));
220  }
221 
223  public Constraint addGreaterThan(LinearExpr expr, long value) {
224  return addLinearExpressionInDomain(expr, new Domain(value + 1, Long.MAX_VALUE));
225  }
226 
229  return addLinearExpressionInDomain(new Difference(left, right), new Domain(1, Long.MAX_VALUE));
230  }
231 
233  public Constraint addGreaterOrEqualWithOffset(LinearExpr left, LinearExpr right, long offset) {
235  new Difference(left, right), new Domain(-offset, Long.MAX_VALUE));
236  }
237 
239  public Constraint addDifferent(LinearExpr expr, long value) {
240  return addLinearExpressionInDomain(expr,
242  new long[] {Long.MIN_VALUE, value - 1, value + 1, Long.MAX_VALUE}));
243  }
244 
246  public Constraint addDifferent(IntVar left, IntVar right) {
247  return addLinearExpressionInDomain(new Difference(left, right),
248  Domain.fromFlatIntervals(new long[] {Long.MIN_VALUE, -1, 1, Long.MAX_VALUE}));
249  }
250 
252  public Constraint addDifferentWithOffset(IntVar left, IntVar right, long offset) {
253  return addLinearExpressionInDomain(new Difference(left, right),
255  new long[] {Long.MIN_VALUE, -offset - 1, -offset + 1, Long.MAX_VALUE}));
256  }
257 
258  // Integer constraints.
259 
268  public Constraint addAllDifferent(IntVar[] variables) {
269  Constraint ct = new Constraint(modelBuilder);
270  AllDifferentConstraintProto.Builder allDiff = ct.getBuilder().getAllDiffBuilder();
271  for (IntVar var : variables) {
272  allDiff.addVars(var.getIndex());
273  }
274  return ct;
275  }
276 
278  public Constraint addElement(IntVar index, IntVar[] variables, IntVar target) {
279  Constraint ct = new Constraint(modelBuilder);
281  ct.getBuilder().getElementBuilder().setIndex(index.getIndex());
282  for (IntVar var : variables) {
283  element.addVars(var.getIndex());
284  }
285  element.setTarget(target.getIndex());
286  return ct;
287  }
288 
290  public Constraint addElement(IntVar index, long[] values, IntVar target) {
291  Constraint ct = new Constraint(modelBuilder);
293  ct.getBuilder().getElementBuilder().setIndex(index.getIndex());
294  for (long v : values) {
295  element.addVars(indexFromConstant(v));
296  }
297  element.setTarget(target.getIndex());
298  return ct;
299  }
300 
302  public Constraint addElement(IntVar index, int[] values, IntVar target) {
303  Constraint ct = new Constraint(modelBuilder);
305  ct.getBuilder().getElementBuilder().setIndex(index.getIndex());
306  for (long v : values) {
307  element.addVars(indexFromConstant(v));
308  }
309  element.setTarget(target.getIndex());
310  return ct;
311  }
312 
328  public Constraint addCircuit(int[] tails, int[] heads, Literal[] literals)
329  throws MismatchedArrayLengths {
330  if (tails.length != heads.length) {
331  throw new MismatchedArrayLengths("CpModel.addCircuit", "tails", "heads");
332  }
333  if (tails.length != literals.length) {
334  throw new MismatchedArrayLengths("CpModel.addCircuit", "tails", "literals");
335  }
336 
337  Constraint ct = new Constraint(modelBuilder);
338  CircuitConstraintProto.Builder circuit = ct.getBuilder().getCircuitBuilder();
339  for (int t : tails) {
340  circuit.addTails(t);
341  }
342  for (int h : heads) {
343  circuit.addHeads(h);
344  }
345  for (Literal lit : literals) {
346  circuit.addLiterals(lit.getIndex());
347  }
348  return ct;
349  }
350 
364  public Constraint addAllowedAssignments(IntVar[] variables, long[][] tuplesList)
365  throws WrongLength {
366  Constraint ct = new Constraint(modelBuilder);
367  TableConstraintProto.Builder table = ct.getBuilder().getTableBuilder();
368  for (IntVar var : variables) {
369  table.addVars(var.getIndex());
370  }
371  int numVars = variables.length;
372  for (int t = 0; t < tuplesList.length; ++t) {
373  if (tuplesList[t].length != numVars) {
374  throw new WrongLength("CpModel.addAllowedAssignments",
375  "tuple " + t + " does not have the same length as the variables");
376  }
377  for (int i = 0; i < tuplesList[t].length; ++i) {
378  table.addValues(tuplesList[t][i]);
379  }
380  }
381  return ct;
382  }
383 
389  public Constraint addAllowedAssignments(IntVar[] variables, int[][] tuplesList)
390  throws WrongLength {
391  Constraint ct = new Constraint(modelBuilder);
392  TableConstraintProto.Builder table = ct.getBuilder().getTableBuilder();
393  for (IntVar var : variables) {
394  table.addVars(var.getIndex());
395  }
396  int numVars = variables.length;
397  for (int t = 0; t < tuplesList.length; ++t) {
398  if (tuplesList[t].length != numVars) {
399  throw new WrongLength("CpModel.addAllowedAssignments",
400  "tuple " + t + " does not have the same length as the variables");
401  }
402  for (int i = 0; i < tuplesList[t].length; ++i) {
403  table.addValues(tuplesList[t][i]);
404  }
405  }
406  return ct;
407  }
408 
421  public Constraint addForbiddenAssignments(IntVar[] variables, long[][] tuplesList)
422  throws WrongLength {
423  Constraint ct = addAllowedAssignments(variables, tuplesList);
424  // Reverse the flag.
425  ct.getBuilder().getTableBuilder().setNegated(true);
426  return ct;
427  }
428 
434  public Constraint addForbiddenAssignments(IntVar[] variables, int[][] tuplesList)
435  throws WrongLength {
436  Constraint ct = addAllowedAssignments(variables, tuplesList);
437  // Reverse the flag.
438  ct.getBuilder().getTableBuilder().setNegated(true);
439  return ct;
440  }
441 
473  public Constraint addAutomaton(IntVar[] transitionVariables, long startingState,
474  long[] finalStates, long[][] transitions) throws WrongLength {
475  Constraint ct = new Constraint(modelBuilder);
476  AutomatonConstraintProto.Builder automaton = ct.getBuilder().getAutomatonBuilder();
477  for (IntVar var : transitionVariables) {
478  automaton.addVars(var.getIndex());
479  }
480  automaton.setStartingState(startingState);
481  for (long c : finalStates) {
482  automaton.addFinalStates(c);
483  }
484  for (long[] t : transitions) {
485  if (t.length != 3) {
486  throw new WrongLength("CpModel.addAutomaton", "transition does not have length 3");
487  }
488  automaton.addTransitionTail(t[0]).addTransitionLabel(t[1]).addTransitionHead(t[2]);
489  }
490  return ct;
491  }
492 
504  public Constraint addInverse(IntVar[] variables, IntVar[] inverseVariables)
505  throws MismatchedArrayLengths {
506  if (variables.length != inverseVariables.length) {
507  throw new MismatchedArrayLengths("CpModel.addInverse", "variables", "inverseVariables");
508  }
509  Constraint ct = new Constraint(modelBuilder);
510  InverseConstraintProto.Builder inverse = ct.getBuilder().getInverseBuilder();
511  for (IntVar var : variables) {
512  inverse.addFDirect(var.getIndex());
513  }
514  for (IntVar var : inverseVariables) {
515  inverse.addFInverse(var.getIndex());
516  }
517  return ct;
518  }
519 
544  IntVar[] times, long[] demands, long minLevel, long maxLevel) throws MismatchedArrayLengths {
545  if (times.length != demands.length) {
546  throw new MismatchedArrayLengths("CpModel.addReservoirConstraint", "times", "demands");
547  }
548  if (minLevel > 0) {
549  throw new IllegalArgumentException("CpModel.addReservoirConstraint: minLevel must be <= 0");
550  }
551  if (maxLevel < 0) {
552  throw new IllegalArgumentException("CpModel.addReservoirConstraint: maxLevel must be >= 0");
553  }
554  Constraint ct = new Constraint(modelBuilder);
555  ReservoirConstraintProto.Builder reservoir = ct.getBuilder().getReservoirBuilder();
556  for (IntVar var : times) {
557  reservoir.addTimes(var.getIndex());
558  }
559  for (long d : demands) {
560  reservoir.addDemands(d);
561  }
562  reservoir.setMinLevel(minLevel).setMaxLevel(maxLevel);
563  return ct;
564  }
565 
572  IntVar[] times, int[] demands, long minLevel, long maxLevel) throws MismatchedArrayLengths {
573  return addReservoirConstraint(times, toLongArray(demands), minLevel, maxLevel);
574  }
575 
599  public Constraint addReservoirConstraintWithActive(IntVar[] times, long[] demands,
600  IntVar[] actives, long minLevel, long maxLevel) throws MismatchedArrayLengths {
601  if (times.length != demands.length) {
602  throw new MismatchedArrayLengths(
603  "CpModel.addReservoirConstraintWithActive", "times", "demands");
604  }
605  if (times.length != actives.length) {
606  throw new MismatchedArrayLengths(
607  "CpModel.addReservoirConstraintWithActive", "times", "actives");
608  }
609  if (minLevel > 0) {
610  throw new IllegalArgumentException(
611  "CpModel.addReservoirConstraintWithActive: minLevel must be <= 0");
612  }
613  if (maxLevel < 0) {
614  throw new IllegalArgumentException(
615  "CpModel.addReservoirConstraintWithActive: maxLevel must be >= 0");
616  }
617 
618  Constraint ct = new Constraint(modelBuilder);
619  ReservoirConstraintProto.Builder reservoir = ct.getBuilder().getReservoirBuilder();
620  for (IntVar var : times) {
621  reservoir.addTimes(var.getIndex());
622  }
623  for (long d : demands) {
624  reservoir.addDemands(d);
625  }
626  for (IntVar var : actives) {
627  reservoir.addActives(var.getIndex());
628  }
629  reservoir.setMinLevel(minLevel).setMaxLevel(maxLevel);
630  return ct;
631  }
632 
638  public Constraint addReservoirConstraintWithActive(IntVar[] times, int[] demands,
639  IntVar[] actives, long minLevel, long maxLevel) throws MismatchedArrayLengths {
641  times, toLongArray(demands), actives, minLevel, maxLevel);
642  }
643 
645  public void addMapDomain(IntVar var, Literal[] booleans, long offset) {
646  for (int i = 0; i < booleans.length; ++i) {
647  addEquality(var, offset + i).onlyEnforceIf(booleans[i]);
648  addDifferent(var, offset + i).onlyEnforceIf(booleans[i].not());
649  }
650  }
651 
653  public Constraint addMinEquality(IntVar target, IntVar[] vars) {
654  Constraint ct = new Constraint(modelBuilder);
656  ct.getBuilder().getIntMinBuilder().setTarget(target.getIndex());
657  for (IntVar var : vars) {
658  intMin.addVars(var.getIndex());
659  }
660  return ct;
661  }
662 
664  public Constraint addMaxEquality(IntVar target, IntVar[] vars) {
665  Constraint ct = new Constraint(modelBuilder);
667  ct.getBuilder().getIntMaxBuilder().setTarget(target.getIndex());
668  for (IntVar var : vars) {
669  intMax.addVars(var.getIndex());
670  }
671  return ct;
672  }
673 
675  public Constraint addDivisionEquality(IntVar target, IntVar num, IntVar denom) {
676  Constraint ct = new Constraint(modelBuilder);
677  ct.getBuilder()
678  .getIntDivBuilder()
679  .setTarget(target.getIndex())
680  .addVars(num.getIndex())
681  .addVars(denom.getIndex());
682  return ct;
683  }
684 
686  public Constraint addAbsEquality(IntVar target, IntVar var) {
687  Constraint ct = new Constraint(modelBuilder);
688  ct.getBuilder()
689  .getIntMaxBuilder()
690  .setTarget(target.getIndex())
691  .addVars(var.getIndex())
692  .addVars(-var.getIndex() - 1);
693  return ct;
694  }
695 
697  public Constraint addModuloEquality(IntVar target, IntVar var, IntVar mod) {
698  Constraint ct = new Constraint(modelBuilder);
699  ct.getBuilder()
700  .getIntModBuilder()
701  .setTarget(target.getIndex())
702  .addVars(var.getIndex())
703  .addVars(mod.getIndex());
704  return ct;
705  }
706 
708  public Constraint addModuloEquality(IntVar target, IntVar var, long mod) {
709  Constraint ct = new Constraint(modelBuilder);
710  ct.getBuilder()
711  .getIntModBuilder()
712  .setTarget(target.getIndex())
713  .addVars(var.getIndex())
714  .addVars(indexFromConstant(mod));
715  return ct;
716  }
717 
719  public Constraint addProductEquality(IntVar target, IntVar[] vars) {
720  Constraint ct = new Constraint(modelBuilder);
721  IntegerArgumentProto.Builder intProd =
722  ct.getBuilder().getIntProdBuilder().setTarget(target.getIndex());
723  for (IntVar var : vars) {
724  intProd.addVars(var.getIndex());
725  }
726  return ct;
727  }
728 
729  // Scheduling support.
730 
745  public IntervalVar newIntervalVar(IntVar start, IntVar size, IntVar end, String name) {
746  return new IntervalVar(modelBuilder, start.getIndex(), size.getIndex(), end.getIndex(), name);
747  }
748 
754  public IntervalVar newIntervalVar(IntVar start, IntVar size, long end, String name) {
755  return new IntervalVar(
756  modelBuilder, start.getIndex(), size.getIndex(), indexFromConstant(end), name);
757  }
758 
764  public IntervalVar newIntervalVar(IntVar start, long size, IntVar end, String name) {
765  return new IntervalVar(
766  modelBuilder, start.getIndex(), indexFromConstant(size), end.getIndex(), name);
767  }
768 
774  public IntervalVar newIntervalVar(long start, IntVar size, IntVar end, String name) {
775  return new IntervalVar(
776  modelBuilder, indexFromConstant(start), size.getIndex(), end.getIndex(), name);
777  }
778 
780  public IntervalVar newFixedInterval(long start, long size, String name) {
781  return new IntervalVar(modelBuilder, indexFromConstant(start), indexFromConstant(size),
782  indexFromConstant(start + size), name);
783  }
784 
803  IntVar start, IntVar size, IntVar end, Literal isPresent, String name) {
804  return new IntervalVar(modelBuilder, start.getIndex(), size.getIndex(), end.getIndex(),
805  isPresent.getIndex(), name);
806  }
807 
814  IntVar start, IntVar size, long end, Literal isPresent, String name) {
815  return new IntervalVar(modelBuilder, start.getIndex(), size.getIndex(), indexFromConstant(end),
816  isPresent.getIndex(), name);
817  }
818 
825  IntVar start, long size, IntVar end, Literal isPresent, String name) {
826  return new IntervalVar(modelBuilder, start.getIndex(), indexFromConstant(size), end.getIndex(),
827  isPresent.getIndex(), name);
828  }
829 
832  long start, IntVar size, IntVar end, Literal isPresent, String name) {
833  return new IntervalVar(modelBuilder, indexFromConstant(start), size.getIndex(), end.getIndex(),
834  isPresent.getIndex(), name);
835  }
836 
843  long start, long size, Literal isPresent, String name) {
844  return new IntervalVar(modelBuilder, indexFromConstant(start), indexFromConstant(size),
845  indexFromConstant(start + size), isPresent.getIndex(), name);
846  }
847 
856  public Constraint addNoOverlap(IntervalVar[] intervalVars) {
857  Constraint ct = new Constraint(modelBuilder);
858  NoOverlapConstraintProto.Builder noOverlap = ct.getBuilder().getNoOverlapBuilder();
859  for (IntervalVar var : intervalVars) {
860  noOverlap.addIntervals(var.getIndex());
861  }
862  return ct;
863  }
864 
876  public Constraint addNoOverlap2D(IntervalVar[] xIntervals, IntervalVar[] yIntervals) {
877  Constraint ct = new Constraint(modelBuilder);
878  NoOverlap2DConstraintProto.Builder noOverlap2d = ct.getBuilder().getNoOverlap2DBuilder();
879  for (IntervalVar x : xIntervals) {
880  noOverlap2d.addXIntervals(x.getIndex());
881  }
882  for (IntervalVar y : yIntervals) {
883  noOverlap2d.addYIntervals(y.getIndex());
884  }
885  return ct;
886  }
887 
903  public Constraint addCumulative(IntervalVar[] intervals, IntVar[] demands, IntVar capacity) {
904  Constraint ct = new Constraint(modelBuilder);
905  CumulativeConstraintProto.Builder cumul = ct.getBuilder().getCumulativeBuilder();
906  for (IntervalVar interval : intervals) {
907  cumul.addIntervals(interval.getIndex());
908  }
909  for (IntVar var : demands) {
910  cumul.addDemands(var.getIndex());
911  }
912  cumul.setCapacity(capacity.getIndex());
913  return ct;
914  }
915 
921  public Constraint addCumulative(IntervalVar[] intervals, long[] demands, IntVar capacity) {
922  Constraint ct = new Constraint(modelBuilder);
923  CumulativeConstraintProto.Builder cumul = ct.getBuilder().getCumulativeBuilder();
924  for (IntervalVar interval : intervals) {
925  cumul.addIntervals(interval.getIndex());
926  }
927  for (long d : demands) {
928  cumul.addDemands(indexFromConstant(d));
929  }
930  cumul.setCapacity(capacity.getIndex());
931  return ct;
932  }
933 
939  public Constraint addCumulative(IntervalVar[] intervals, int[] demands, IntVar capacity) {
940  return addCumulative(intervals, toLongArray(demands), capacity);
941  }
942 
948  public Constraint addCumulative(IntervalVar[] intervals, IntVar[] demands, long capacity) {
949  Constraint ct = new Constraint(modelBuilder);
950  CumulativeConstraintProto.Builder cumul = ct.getBuilder().getCumulativeBuilder();
951  for (IntervalVar interval : intervals) {
952  cumul.addIntervals(interval.getIndex());
953  }
954  for (IntVar var : demands) {
955  cumul.addDemands(var.getIndex());
956  }
957  cumul.setCapacity(indexFromConstant(capacity));
958  return ct;
959  }
960 
966  public Constraint addCumulative(IntervalVar[] intervals, long[] demands, long capacity) {
967  Constraint ct = new Constraint(modelBuilder);
968  CumulativeConstraintProto.Builder cumul = ct.getBuilder().getCumulativeBuilder();
969  for (IntervalVar interval : intervals) {
970  cumul.addIntervals(interval.getIndex());
971  }
972  for (long d : demands) {
973  cumul.addDemands(indexFromConstant(d));
974  }
975  cumul.setCapacity(indexFromConstant(capacity));
976  return ct;
977  }
978 
984  public Constraint addCumulative(IntervalVar[] intervals, int[] demands, long capacity) {
985  return addCumulative(intervals, toLongArray(demands), capacity);
986  }
987 
989  public void addHint(IntVar var, long value) {
990  modelBuilder.getSolutionHintBuilder().addVars(var.getIndex());
991  modelBuilder.getSolutionHintBuilder().addValues(value);
992  }
993 
995  public void clearHints() {
996  modelBuilder.clearSolutionHint();
997  }
998 
1000  public void addAssumption(Literal lit) {
1001  modelBuilder.addAssumptions(lit.getIndex());
1002  }
1003 
1005  public void addAssumptions(Literal[] literals) {
1006  for (Literal lit : literals) {
1007  addAssumption(lit);
1008  }
1009  }
1010 
1012  public void clearAssumptions() {
1013  modelBuilder.clearAssumptions();
1014  }
1015 
1016  // Objective.
1017 
1019  public void minimize(LinearExpr expr) {
1020  CpObjectiveProto.Builder obj = modelBuilder.getObjectiveBuilder();
1021  for (int i = 0; i < expr.numElements(); ++i) {
1022  obj.addVars(expr.getVariable(i).getIndex()).addCoeffs(expr.getCoefficient(i));
1023  }
1024  obj.setOffset(expr.getOffset());
1025  }
1026 
1028  public void maximize(LinearExpr expr) {
1029  CpObjectiveProto.Builder obj = modelBuilder.getObjectiveBuilder();
1030  for (int i = 0; i < expr.numElements(); ++i) {
1031  obj.addVars(expr.getVariable(i).getIndex()).addCoeffs(-expr.getCoefficient(i));
1032  }
1033  obj.setOffset(-expr.getOffset());
1034  obj.setScalingFactor(-1.0);
1035  }
1036 
1037  // DecisionStrategy
1038 
1040  public void addDecisionStrategy(IntVar[] variables,
1043  DecisionStrategyProto.Builder ds = modelBuilder.addSearchStrategyBuilder();
1044  for (IntVar var : variables) {
1045  ds.addVariables(var.getIndex());
1046  }
1047  ds.setVariableSelectionStrategy(varStr).setDomainReductionStrategy(domStr);
1048  }
1049 
1051  public String modelStats() {
1052  return SatHelper.modelStats(model());
1053  }
1054 
1056  public String validate() {
1057  return SatHelper.validateModel(model());
1058  }
1059 
1061  public Boolean exportToFile(String file) {
1062  return SatHelper.writeModelToFile(model(), file);
1063  }
1064 
1065  // Helpers
1066 
1067  long[] toLongArray(int[] values) {
1068  long[] result = new long[values.length];
1069  for (int i = 0; i < values.length; ++i) {
1070  result[i] = values[i];
1071  }
1072  return result;
1073  }
1074 
1075  int indexFromConstant(long constant) {
1076  int index = modelBuilder.getVariablesCount();
1077  modelBuilder.addVariablesBuilder().addDomain(constant).addDomain(constant);
1078  return index;
1079  }
1080 
1081  // Getters.
1082 
1083  public CpModelProto model() {
1084  return modelBuilder.build();
1085  }
1086 
1087  public int negated(int index) {
1088  return -index - 1;
1089  }
1090 
1093  return modelBuilder;
1094  }
1095 
1096  private final CpModelProto.Builder modelBuilder;
1097  private final Map<Long, IntVar> constantMap;
1098 }
ConstraintProto.Builder getBuilder()
Returns the constraint builder.
void onlyEnforceIf(Literal lit)
Adds a literal to the constraint.
.lang.Override int getVariablesCount()
Exception thrown when parallel arrays have mismatched lengths.
Definition: CpModel.java:50
MismatchedArrayLengths(String methodName, String array1Name, String array2Name)
Definition: CpModel.java:51
Exception thrown when an array has a wrong length.
Definition: CpModel.java:57
WrongLength(String methodName, String msg)
Definition: CpModel.java:58
Main modeling class.
Definition: CpModel.java:41
Constraint addDifferent(IntVar left, IntVar right)
Adds.
Definition: CpModel.java:246
Constraint addAllowedAssignments(IntVar[] variables, int[][] tuplesList)
Adds.
Definition: CpModel.java:389
IntVar newConstant(long value)
Creates a constant variable.
Definition: CpModel.java:91
Constraint addCumulative(IntervalVar[] intervals, long[] demands, long capacity)
Adds.
Definition: CpModel.java:966
IntVar newBoolVar(String name)
Creates a Boolean variable with the given name.
Definition: CpModel.java:86
Constraint addDifferentWithOffset(IntVar left, IntVar right, long offset)
Adds.
Definition: CpModel.java:252
Constraint addGreaterOrEqual(LinearExpr expr, long value)
Adds.
Definition: CpModel.java:213
Constraint addForbiddenAssignments(IntVar[] variables, int[][] tuplesList)
Adds.
Definition: CpModel.java:434
void clearAssumptions()
Remove all assumptions from the model.
Definition: CpModel.java:1012
IntervalVar newOptionalIntervalVar(IntVar start, IntVar size, long end, Literal isPresent, String name)
Creates an optional interval with a fixed end.
Definition: CpModel.java:813
Constraint addReservoirConstraintWithActive(IntVar[] times, long[] demands, IntVar[] actives, long minLevel, long maxLevel)
Adds.
Definition: CpModel.java:599
Constraint addGreaterOrEqual(LinearExpr left, LinearExpr right)
Adds.
Definition: CpModel.java:218
Constraint addAutomaton(IntVar[] transitionVariables, long startingState, long[] finalStates, long[][] transitions)
Adds an automaton constraint.
Definition: CpModel.java:473
Constraint addModuloEquality(IntVar target, IntVar var, long mod)
Adds.
Definition: CpModel.java:708
Boolean exportToFile(String file)
Write the model as a ascii protocol buffer to 'file'.
Definition: CpModel.java:1061
Constraint addLessOrEqual(LinearExpr expr, long value)
Adds.
Definition: CpModel.java:187
IntervalVar newOptionalFixedInterval(long start, long size, Literal isPresent, String name)
Creates an optional fixed interval from start and size.
Definition: CpModel.java:842
IntervalVar newIntervalVar(long start, IntVar size, IntVar end, String name)
Creates an interval variable with a fixed start.
Definition: CpModel.java:774
Constraint addLessThan(LinearExpr expr, long value)
Adds.
Definition: CpModel.java:197
Constraint addElement(IntVar index, long[] values, IntVar target)
Adds the element constraint:
Definition: CpModel.java:290
Literal falseLiteral()
Returns the false literal.
Definition: CpModel.java:106
Constraint addLessOrEqualWithOffset(LinearExpr left, LinearExpr right, long offset)
Adds.
Definition: CpModel.java:207
void addAssumptions(Literal[] literals)
Adds multiple literals to the model as assumptions.
Definition: CpModel.java:1005
Constraint addEquality(LinearExpr left, LinearExpr right)
Adds.
Definition: CpModel.java:177
IntervalVar newOptionalIntervalVar(long start, IntVar size, IntVar end, Literal isPresent, String name)
Creates an optional interval with a fixed start.
Definition: CpModel.java:831
IntervalVar newIntervalVar(IntVar start, long size, IntVar end, String name)
Creates an interval variable with a fixed size.
Definition: CpModel.java:764
void minimize(LinearExpr expr)
Adds a minimization objective of a linear expression.
Definition: CpModel.java:1019
Constraint addDivisionEquality(IntVar target, IntVar num, IntVar denom)
Adds.
Definition: CpModel.java:675
Constraint addReservoirConstraint(IntVar[] times, int[] demands, long minLevel, long maxLevel)
Adds.
Definition: CpModel.java:571
Constraint addGreaterThan(LinearExpr expr, long value)
Adds.
Definition: CpModel.java:223
void addAssumption(Literal lit)
Adds a literal to the model as assumption.
Definition: CpModel.java:1000
Constraint addProductEquality(IntVar target, IntVar[] vars)
Adds.
Definition: CpModel.java:719
Constraint addReservoirConstraint(IntVar[] times, long[] demands, long minLevel, long maxLevel)
Adds.
Definition: CpModel.java:543
void addHint(IntVar var, long value)
Adds hinting to a variable.
Definition: CpModel.java:989
Constraint addModuloEquality(IntVar target, IntVar var, IntVar mod)
Adds.
Definition: CpModel.java:697
IntervalVar newFixedInterval(long start, long size, String name)
Creates a fixed interval from its start and its size.
Definition: CpModel.java:780
Constraint addGreaterThan(LinearExpr left, LinearExpr right)
Adds.
Definition: CpModel.java:228
IntervalVar newOptionalIntervalVar(IntVar start, IntVar size, IntVar end, Literal isPresent, String name)
Creates an optional interval variable from start, size, end, and isPresent.
Definition: CpModel.java:802
Constraint addCircuit(int[] tails, int[] heads, Literal[] literals)
Adds.
Definition: CpModel.java:328
String modelStats()
Returns some statistics on model as a string.
Definition: CpModel.java:1051
Constraint addEqualityWithOffset(LinearExpr left, LinearExpr right, long offset)
Adds.
Definition: CpModel.java:182
Constraint addElement(IntVar index, IntVar[] variables, IntVar target)
Adds the element constraint:
Definition: CpModel.java:278
Constraint addAbsEquality(IntVar target, IntVar var)
Adds.
Definition: CpModel.java:686
IntervalVar newIntervalVar(IntVar start, IntVar size, IntVar end, String name)
Creates an interval variable from start, size, and end.
Definition: CpModel.java:745
Constraint addAllowedAssignments(IntVar[] variables, long[][] tuplesList)
Adds.
Definition: CpModel.java:364
IntervalVar newIntervalVar(IntVar start, IntVar size, long end, String name)
Creates an interval variable with a fixed end.
Definition: CpModel.java:754
Constraint addCumulative(IntervalVar[] intervals, int[] demands, IntVar capacity)
Adds.
Definition: CpModel.java:939
Constraint addReservoirConstraintWithActive(IntVar[] times, int[] demands, IntVar[] actives, long minLevel, long maxLevel)
Adds.
Definition: CpModel.java:638
void maximize(LinearExpr expr)
Adds a maximization objective of a linear expression.
Definition: CpModel.java:1028
Constraint addAllDifferent(IntVar[] variables)
Adds.
Definition: CpModel.java:268
Constraint addImplication(Literal a, Literal b)
Adds.
Definition: CpModel.java:143
Constraint addBoolXor(Literal[] literals)
Adds.
Definition: CpModel.java:133
Constraint addCumulative(IntervalVar[] intervals, IntVar[] demands, IntVar capacity)
Adds.
Definition: CpModel.java:903
Constraint addLessThan(LinearExpr left, LinearExpr right)
Adds.
Definition: CpModel.java:202
Constraint addMinEquality(IntVar target, IntVar[] vars)
Adds.
Definition: CpModel.java:653
Constraint addCumulative(IntervalVar[] intervals, IntVar[] demands, long capacity)
Adds.
Definition: CpModel.java:948
IntVar newIntVar(long lb, long ub, String name)
Creates an integer variable with domain [lb, ub].
Definition: CpModel.java:70
void addMapDomain(IntVar var, Literal[] booleans, long offset)
Adds.
Definition: CpModel.java:645
void addDecisionStrategy(IntVar[] variables, DecisionStrategyProto.VariableSelectionStrategy varStr, DecisionStrategyProto.DomainReductionStrategy domStr)
Adds.
Definition: CpModel.java:1040
Constraint addInverse(IntVar[] variables, IntVar[] inverseVariables)
Adds.
Definition: CpModel.java:504
Constraint addNoOverlap2D(IntervalVar[] xIntervals, IntervalVar[] yIntervals)
Adds.
Definition: CpModel.java:876
Constraint addLinearConstraint(LinearExpr expr, long lb, long ub)
Adds.
Definition: CpModel.java:167
Constraint addNoOverlap(IntervalVar[] intervalVars)
Adds.
Definition: CpModel.java:856
Literal trueLiteral()
Returns the true literal.
Definition: CpModel.java:101
Constraint addForbiddenAssignments(IntVar[] variables, long[][] tuplesList)
Adds.
Definition: CpModel.java:421
Constraint addDifferent(LinearExpr expr, long value)
Adds.
Definition: CpModel.java:239
Constraint addElement(IntVar index, int[] values, IntVar target)
Adds the element constraint:
Definition: CpModel.java:302
Constraint addEquality(LinearExpr expr, long value)
Adds.
Definition: CpModel.java:172
void clearHints()
Remove all solution hints.
Definition: CpModel.java:995
String validate()
Returns a non empty string explaining the issue if the model is invalid.
Definition: CpModel.java:1056
Constraint addGreaterOrEqualWithOffset(LinearExpr left, LinearExpr right, long offset)
Adds.
Definition: CpModel.java:233
Constraint addMaxEquality(IntVar target, IntVar[] vars)
Adds.
Definition: CpModel.java:664
Constraint addCumulative(IntervalVar[] intervals, int[] demands, long capacity)
Adds.
Definition: CpModel.java:984
Constraint addBoolOr(Literal[] literals)
Adds.
Definition: CpModel.java:113
IntVar newIntVarFromDomain(Domain domain, String name)
Creates an integer variable with given domain.
Definition: CpModel.java:81
Constraint addLinearExpressionInDomain(LinearExpr expr, Domain domain)
Adds.
Definition: CpModel.java:150
Constraint addBoolAnd(Literal[] literals)
Adds.
Definition: CpModel.java:123
IntervalVar newOptionalIntervalVar(IntVar start, long size, IntVar end, Literal isPresent, String name)
Creates an optional interval with a fixed size.
Definition: CpModel.java:824
Constraint addCumulative(IntervalVar[] intervals, long[] demands, IntVar capacity)
Adds.
Definition: CpModel.java:921
Constraint addLessOrEqual(LinearExpr left, LinearExpr right)
Adds.
Definition: CpModel.java:192
CpModelProto.Builder getBuilder()
Returns the model builder.
Definition: CpModel.java:1092
int getIndex()
Internal, returns the index of the variable in the underlying CpModelProto.
static String validateModel(com.google.ortools.sat.CpModelProto model_proto)
Definition: SatHelper.java:88
static String modelStats(com.google.ortools.sat.CpModelProto model_proto)
Definition: SatHelper.java:80
static boolean writeModelToFile(com.google.ortools.sat.CpModelProto model_proto, String filename)
Definition: SatHelper.java:96
We call domain any subset of Int64 = [kint64min, kint64max].
Definition: Domain.java:21
static Domain fromFlatIntervals(long[] flat_intervals)
This method is available in Python, Java and .NET.
Definition: Domain.java:100
long[] flattenedIntervals()
This method returns the flattened list of interval bounds of the domain.
Definition: Domain.java:111
A linear expression interface that can be parsed.
Definition: LinearExpr.java:17
long getCoefficient(int index)
Returns the ith coefficient.
int numElements()
Returns the number of elements in the interface.
long getOffset()
Returns the constant part of the expression.
IntVar getVariable(int index)
Returns the ith variable.
Interface to describe a boolean variable or its negation.
Definition: Literal.java:17
Literal not()
Returns the Boolean negation of the current literal.