14 package com.google.ortools.sat;
41 static class CpModelException
extends Exception {
42 public CpModelException(String methodName, String msg) {
44 super(
"CpModel." + methodName +
": " + msg);
51 super(methodName, array1Name +
" and " + array2Name +
" have mismatched lengths");
58 super(methodName, msg);
70 return new IntVar(modelBuilder,
new Domain(lb, ub), name);
81 return new IntVar(modelBuilder, domain, name);
99 BoolArgumentProto.Builder boolOr = ct.
getBuilder().getBoolOrBuilder();
101 boolOr.addLiterals(lit.getIndex());
109 BoolArgumentProto.Builder boolOr = ct.
getBuilder().getBoolAndBuilder();
111 boolOr.addLiterals(lit.getIndex());
119 BoolArgumentProto.Builder boolOr = ct.
getBuilder().getBoolXorBuilder();
121 boolOr.addLiterals(lit.getIndex());
136 LinearConstraintProto.Builder lin = ct.
getBuilder().getLinearBuilder();
190 new Difference(left, right),
new Domain(Long.MIN_VALUE, -offset));
216 new Difference(left, right),
new Domain(-offset, Long.MAX_VALUE));
223 new long[] {Long.MIN_VALUE, value - 1, value + 1, Long.MAX_VALUE}));
236 new long[] {Long.MIN_VALUE, -offset - 1, -offset + 1, Long.MAX_VALUE}));
251 AllDifferentConstraintProto.Builder allDiff = ct.
getBuilder().getAllDiffBuilder();
252 for (
IntVar var : variables) {
253 allDiff.addVars(var.getIndex());
261 ElementConstraintProto.Builder element = ct.
getBuilder().getElementBuilder();
263 for (
IntVar var : variables) {
264 element.addVars(var.getIndex());
266 element.setTarget(target.
getIndex());
273 ElementConstraintProto.Builder element = ct.
getBuilder().getElementBuilder();
275 for (
long v : values) {
276 element.addVars(indexFromConstant(v));
278 element.setTarget(target.
getIndex());
285 ElementConstraintProto.Builder element = ct.
getBuilder().getElementBuilder();
287 for (
long v : values) {
288 element.addVars(indexFromConstant(v));
290 element.setTarget(target.
getIndex());
311 if (tails.length != heads.length) {
314 if (tails.length != literals.length) {
319 CircuitConstraintProto.Builder circuit = ct.
getBuilder().getCircuitBuilder();
320 for (
int t : tails) {
323 for (
int h : heads) {
327 circuit.addLiterals(lit.getIndex());
348 TableConstraintProto.Builder table = ct.
getBuilder().getTableBuilder();
349 for (
IntVar var : variables) {
350 table.addVars(var.getIndex());
352 int numVars = variables.length;
353 for (
int t = 0; t < tuplesList.length; ++t) {
354 if (tuplesList[t].length != numVars) {
356 "tuple " + t +
" does not have the same length as the variables");
358 for (
int i = 0; i < tuplesList[t].length; ++i) {
359 table.addValues(tuplesList[t][i]);
373 TableConstraintProto.Builder table = ct.
getBuilder().getTableBuilder();
374 for (
IntVar var : variables) {
375 table.addVars(var.getIndex());
377 int numVars = variables.length;
378 for (
int t = 0; t < tuplesList.length; ++t) {
379 if (tuplesList[t].length != numVars) {
381 "tuple " + t +
" does not have the same length as the variables");
383 for (
int i = 0; i < tuplesList[t].length; ++i) {
384 table.addValues(tuplesList[t][i]);
406 ct.
getBuilder().getTableBuilder().setNegated(
true);
419 ct.
getBuilder().getTableBuilder().setNegated(
true);
455 long[] finalStates,
long[][] transitions)
throws WrongLength {
457 AutomatonConstraintProto.Builder automaton = ct.
getBuilder().getAutomatonBuilder();
458 for (
IntVar var : transitionVariables) {
459 automaton.addVars(var.getIndex());
461 automaton.setStartingState(startingState);
462 for (
long c : finalStates) {
463 automaton.addFinalStates(c);
465 for (
long[] t : transitions) {
467 throw new WrongLength(
"addAutomaton",
"transition does not have length 3");
469 automaton.addTransitionTail(t[0]);
470 automaton.addTransitionLabel(t[1]);
471 automaton.addTransitionHead(t[2]);
489 if (variables.length != inverseVariables.length) {
493 InverseConstraintProto.Builder inverse = ct.
getBuilder().getInverseBuilder();
494 for (
IntVar var : variables) {
495 inverse.addFDirect(var.getIndex());
497 for (
IntVar var : inverseVariables) {
498 inverse.addFInverse(var.getIndex());
528 if (times.length != demands.length) {
532 ReservoirConstraintProto.Builder reservoir = ct.
getBuilder().getReservoirBuilder();
533 for (
IntVar var : times) {
534 reservoir.addTimes(var.getIndex());
536 for (
long d : demands) {
537 reservoir.addDemands(d);
539 reservoir.setMinLevel(minLevel);
540 reservoir.setMaxLevel(maxLevel);
581 if (times.length != demands.length) {
584 if (times.length != actives.length) {
589 ReservoirConstraintProto.Builder reservoir = ct.
getBuilder().getReservoirBuilder();
590 for (
IntVar var : times) {
591 reservoir.addTimes(var.getIndex());
593 for (
long d : demands) {
594 reservoir.addDemands(d);
596 for (
IntVar var : actives) {
597 reservoir.addActives(var.getIndex());
599 reservoir.setMinLevel(minLevel);
600 reservoir.setMaxLevel(maxLevel);
612 times, toLongArray(demands), actives, minLevel, maxLevel);
617 for (
int i = 0; i < booleans.length; ++i) {
626 IntegerArgumentProto.Builder intMin = ct.
getBuilder().getIntMinBuilder();
627 intMin.setTarget(target.
getIndex());
629 intMin.addVars(var.getIndex());
637 IntegerArgumentProto.Builder intMax = ct.
getBuilder().getIntMaxBuilder();
638 intMax.setTarget(target.
getIndex());
640 intMax.addVars(var.getIndex());
648 IntegerArgumentProto.Builder intDiv = ct.
getBuilder().getIntDivBuilder();
649 intDiv.setTarget(target.
getIndex());
658 IntegerArgumentProto.Builder intMax = ct.
getBuilder().getIntMaxBuilder();
659 intMax.setTarget(target.
getIndex());
661 intMax.addVars(-var.
getIndex() - 1);
668 IntegerArgumentProto.Builder intMod = ct.
getBuilder().getIntModBuilder();
669 intMod.setTarget(target.
getIndex());
678 IntegerArgumentProto.Builder intMod = ct.
getBuilder().getIntModBuilder();
679 intMod.setTarget(target.
getIndex());
681 intMod.addVars(indexFromConstant(mod));
688 IntegerArgumentProto.Builder intProd = ct.
getBuilder().getIntProdBuilder();
689 intProd.setTarget(target.
getIndex());
691 intProd.addVars(var.getIndex());
723 modelBuilder, start.
getIndex(), size.
getIndex(), indexFromConstant(end), name);
733 modelBuilder, start.
getIndex(), indexFromConstant(size), end.
getIndex(), name);
743 modelBuilder, indexFromConstant(start), size.
getIndex(), end.
getIndex(), name);
748 return new IntervalVar(modelBuilder, indexFromConstant(start), indexFromConstant(size),
749 indexFromConstant(start + size), name);
810 long start,
long size,
Literal isPresent, String name) {
811 return new IntervalVar(modelBuilder, indexFromConstant(start), indexFromConstant(size),
812 indexFromConstant(start + size), isPresent.
getIndex(), name);
825 NoOverlapConstraintProto.Builder noOverlap = ct.
getBuilder().getNoOverlapBuilder();
827 noOverlap.addIntervals(var.getIndex());
845 NoOverlap2DConstraintProto.Builder noOverlap2d = ct.
getBuilder().getNoOverlap2DBuilder();
847 noOverlap2d.addXIntervals(x.getIndex());
850 noOverlap2d.addYIntervals(y.getIndex());
872 CumulativeConstraintProto.Builder cumul = ct.
getBuilder().getCumulativeBuilder();
874 cumul.addIntervals(interval.getIndex());
876 for (
IntVar var : demands) {
877 cumul.addDemands(var.getIndex());
879 cumul.setCapacity(capacity.
getIndex());
890 CumulativeConstraintProto.Builder cumul = ct.
getBuilder().getCumulativeBuilder();
892 cumul.addIntervals(interval.getIndex());
894 for (
long d : demands) {
895 cumul.addDemands(indexFromConstant(d));
897 cumul.setCapacity(capacity.
getIndex());
907 return addCumulative(intervals, toLongArray(demands), capacity);
917 CumulativeConstraintProto.Builder cumul = ct.
getBuilder().getCumulativeBuilder();
919 cumul.addIntervals(interval.getIndex());
921 for (
IntVar var : demands) {
922 cumul.addDemands(var.getIndex());
924 cumul.setCapacity(indexFromConstant(capacity));
935 CumulativeConstraintProto.Builder cumul = ct.
getBuilder().getCumulativeBuilder();
937 cumul.addIntervals(interval.getIndex());
939 for (
long d : demands) {
940 cumul.addDemands(indexFromConstant(d));
942 cumul.setCapacity(indexFromConstant(capacity));
952 return addCumulative(intervals, toLongArray(demands), capacity);
959 CpObjectiveProto.Builder obj = modelBuilder.getObjectiveBuilder();
968 CpObjectiveProto.Builder obj = modelBuilder.getObjectiveBuilder();
973 obj.setScalingFactor(-1.0);
980 DecisionStrategyProto.VariableSelectionStrategy varStr,
981 DecisionStrategyProto.DomainReductionStrategy domStr) {
982 DecisionStrategyProto.Builder ds = modelBuilder.addSearchStrategyBuilder();
983 for (
IntVar var : variables) {
984 ds.addVariables(var.getIndex());
986 ds.setVariableSelectionStrategy(varStr);
987 ds.setDomainReductionStrategy(domStr);
992 return SatHelper.modelStats(
model());
997 return SatHelper.validateModel(
model());
1002 long[] toLongArray(
int[] values) {
1003 long[] result =
new long[values.length];
1004 for (
int i = 0; i < values.length; ++i) {
1005 result[i] = values[i];
1010 int indexFromConstant(
long constant) {
1012 IntegerVariableProto.Builder cst = modelBuilder.addVariablesBuilder();
1013 cst.addDomain(constant);
1014 cst.addDomain(constant);
1021 return modelBuilder.build();
1030 return modelBuilder;
long [] flattenedIntervals()
This method returns the flattened list of interval bounds of the domain.
static Domain fromFlatIntervals(long[] flat_intervals)
This method is available in Python, Java and .NET.
We call "domain" any subset of Int64 = [kint64min, kint64max].