14package com.google.ortools.sat;
16import com.google.ortools.sat.AllDifferentConstraintProto;
17import com.google.ortools.sat.AutomatonConstraintProto;
18import com.google.ortools.sat.BoolArgumentProto;
19import com.google.ortools.sat.CpModelProto;
20import com.google.ortools.sat.CpObjectiveProto;
21import com.google.ortools.sat.CumulativeConstraintProto;
22import com.google.ortools.sat.DecisionStrategyProto;
23import com.google.ortools.sat.ElementConstraintProto;
24import com.google.ortools.sat.FloatObjectiveProto;
25import com.google.ortools.sat.InverseConstraintProto;
26import com.google.ortools.sat.LinearArgumentProto;
27import com.google.ortools.sat.LinearConstraintProto;
28import com.google.ortools.sat.LinearExpressionProto;
29import com.google.ortools.sat.NoOverlapConstraintProto;
30import com.google.ortools.sat.ReservoirConstraintProto;
31import com.google.ortools.sat.TableConstraintProto;
32import com.google.ortools.util.Domain;
33import java.util.Arrays;
34import java.util.LinkedHashMap;
42public final class CpModel {
43 static class CpModelException
extends RuntimeException {
44 public CpModelException(String methodName, String msg) {
46 super(methodName +
": " + msg);
51 public static class MismatchedArrayLengths
extends CpModelException {
53 super(methodName, array1Name +
" and " + array2Name +
" have mismatched lengths");
58 public static class WrongLength
extends CpModelException {
60 super(methodName, msg);
66 constantMap =
new LinkedHashMap<>();
71 clone.modelBuilder.mergeFrom(modelBuilder.build());
72 clone.constantMap.clear();
73 clone.constantMap.putAll(constantMap);
81 return new IntVar(modelBuilder,
new Domain(lb, ub), name);
92 return new IntVar(modelBuilder, domain, name);
102 if (constantMap.containsKey(value)) {
103 return new IntVar(modelBuilder, constantMap.get(value));
106 constantMap.put(value, cste.
getIndex());
112 if (constantMap.containsKey(1L)) {
113 return new BoolVar(modelBuilder, constantMap.get(1L));
116 constantMap.put(1L, cste.
getIndex());
122 if (constantMap.containsKey(0L)) {
123 return new BoolVar(modelBuilder, constantMap.get(0L));
126 constantMap.put(0L, cste.
getIndex());
132 return new BoolVar(modelBuilder, index);
137 return new IntVar(modelBuilder, index);
144 return addBoolOr(Arrays.asList(literals));
150 BoolArgumentProto.Builder boolOr = ct.
getBuilder().getBoolOrBuilder();
152 boolOr.addLiterals(lit.getIndex());
159 return addBoolOr(Arrays.asList(literals));
175 BoolArgumentProto.Builder atMostOne = ct.
getBuilder().getAtMostOneBuilder();
177 atMostOne.addLiterals(lit.getIndex());
190 BoolArgumentProto.Builder exactlyOne = ct.
getBuilder().getExactlyOneBuilder();
192 exactlyOne.addLiterals(lit.getIndex());
205 BoolArgumentProto.Builder boolAnd = ct.
getBuilder().getBoolAndBuilder();
207 boolAnd.addLiterals(lit.getIndex());
220 BoolArgumentProto.Builder boolXOr = ct.
getBuilder().getBoolXorBuilder();
222 boolXOr.addLiterals(lit.getIndex());
237 LinearConstraintProto.Builder lin = ct.
getBuilder().getLinearBuilder();
244 if (b == Long.MIN_VALUE || b == Long.MAX_VALUE) {
247 lin.addDomain(b - offset);
327 new long[] {Long.MIN_VALUE, value - 1, value + 1, Long.MAX_VALUE}));
360 AllDifferentConstraintProto.Builder allDiff = ct.
getBuilder().getAllDiffBuilder();
362 allDiff.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr,
false));
370 ElementConstraintProto.Builder element =
372 for (
IntVar var : variables) {
373 element.addVars(var.getIndex());
375 element.setTarget(target.
getIndex());
382 ElementConstraintProto.Builder element =
384 for (
long v : values) {
387 element.setTarget(target.
getIndex());
394 ElementConstraintProto.Builder element =
396 for (
long v : values) {
399 element.setTarget(target.
getIndex());
452 TableConstraintProto.Builder table = ct.
getBuilder().getTableBuilder();
453 for (
IntVar var : variables) {
454 table.addVars(var.getIndex());
456 table.setNegated(
false);
481 TableConstraintProto.Builder table = ct.
getBuilder().getTableBuilder();
482 for (
IntVar var : variables) {
483 table.addVars(var.getIndex());
485 table.setNegated(
true);
519 IntVar[] transitionVariables,
long startingState,
long[] finalStates) {
521 AutomatonConstraintProto.Builder automaton = ct.
getBuilder().getAutomatonBuilder();
522 for (
IntVar var : transitionVariables) {
523 automaton.addVars(var.getIndex());
525 automaton.setStartingState(startingState);
526 for (
long c : finalStates) {
527 automaton.addFinalStates(c);
544 if (variables.length != inverseVariables.length) {
548 InverseConstraintProto.Builder inverse = ct.
getBuilder().getInverseBuilder();
549 for (
IntVar var : variables) {
550 inverse.addFDirect(var.getIndex());
552 for (
IntVar var : inverseVariables) {
553 inverse.addFInverse(var.getIndex());
583 throw new IllegalArgumentException(
"CpModel.addReservoirConstraint: minLevel must be <= 0");
586 throw new IllegalArgumentException(
"CpModel.addReservoirConstraint: maxLevel must be >= 0");
589 ReservoirConstraintProto.Builder reservoir = ct.
getBuilder().getReservoirBuilder();
590 reservoir.setMinLevel(minLevel).setMaxLevel(maxLevel);
596 for (
int i = 0; i < booleans.length; ++i) {
605 LinearArgumentProto.Builder linMax = ct.
getBuilder().getLinMaxBuilder();
606 linMax.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target,
true));
608 linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr,
true));
615 LinearArgument target, Iterable<? extends LinearArgument> exprs) {
617 LinearArgumentProto.Builder linMax = ct.
getBuilder().getLinMaxBuilder();
618 linMax.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target,
true));
620 linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr,
true));
628 LinearArgumentProto.Builder linMax = ct.
getBuilder().getLinMaxBuilder();
629 linMax.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target,
false));
631 linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr,
false));
638 LinearArgument target, Iterable<? extends LinearArgument> exprs) {
640 LinearArgumentProto.Builder linMax = ct.
getBuilder().getLinMaxBuilder();
641 linMax.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target,
false));
643 linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr,
false));
654 .setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target,
false))
655 .addExprs(getLinearExpressionProtoBuilderFromLinearArgument(num,
false))
656 .addExprs(getLinearExpressionProtoBuilderFromLinearArgument(denom,
false));
663 LinearArgumentProto.Builder linMax = ct.
getBuilder().getLinMaxBuilder();
664 linMax.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target,
false));
665 linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr,
false));
666 linMax.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr,
true));
676 .setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target,
false))
677 .addExprs(getLinearExpressionProtoBuilderFromLinearArgument(var,
false))
678 .addExprs(getLinearExpressionProtoBuilderFromLinearArgument(mod,
false));
687 .setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target,
false))
688 .addExprs(getLinearExpressionProtoBuilderFromLinearArgument(var,
false))
689 .addExprs(getLinearExpressionProtoBuilderFromLong(mod));
696 LinearArgumentProto.Builder intProd = ct.
getBuilder().getIntProdBuilder();
697 intProd.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target,
false));
699 intProd.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(expr,
false));
708 LinearArgumentProto.Builder intProd = ct.
getBuilder().getIntProdBuilder();
709 intProd.setTarget(getLinearExpressionProtoBuilderFromLinearArgument(target,
false));
710 intProd.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(left,
false));
711 intProd.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(right,
false));
734 getLinearExpressionProtoBuilderFromLinearArgument(start,
false),
735 getLinearExpressionProtoBuilderFromLinearArgument(size,
false),
736 getLinearExpressionProtoBuilderFromLinearArgument(end,
false), name);
752 getLinearExpressionProtoBuilderFromLinearArgument(start,
false),
753 getLinearExpressionProtoBuilderFromLong(size),
754 getLinearExpressionProtoBuilderFromLinearArgument(
761 return new IntervalVar(modelBuilder, getLinearExpressionProtoBuilderFromLong(start),
762 getLinearExpressionProtoBuilderFromLong(size),
763 getLinearExpressionProtoBuilderFromLong(start + size), name);
787 getLinearExpressionProtoBuilderFromLinearArgument(start,
false),
788 getLinearExpressionProtoBuilderFromLinearArgument(size,
false),
789 getLinearExpressionProtoBuilderFromLinearArgument(end,
false),
809 getLinearExpressionProtoBuilderFromLinearArgument(start,
false),
810 getLinearExpressionProtoBuilderFromLong(size),
811 getLinearExpressionProtoBuilderFromLinearArgument(
818 long start,
long size,
Literal isPresent, String name) {
819 return new IntervalVar(modelBuilder, getLinearExpressionProtoBuilderFromLong(start),
820 getLinearExpressionProtoBuilderFromLong(size),
821 getLinearExpressionProtoBuilderFromLong(start + size), isPresent.
getIndex(), name);
843 NoOverlapConstraintProto.Builder noOverlap = ct.
getBuilder().getNoOverlapBuilder();
845 noOverlap.addIntervals(var.getIndex());
881 CumulativeConstraintProto.Builder cumul = ct.
getBuilder().getCumulativeBuilder();
882 cumul.setCapacity(getLinearExpressionProtoBuilderFromLinearArgument(capacity,
false));
893 CumulativeConstraintProto.Builder cumul = ct.
getBuilder().getCumulativeBuilder();
894 cumul.setCapacity(getLinearExpressionProtoBuilderFromLong(capacity));
900 modelBuilder.getSolutionHintBuilder().addVars(var.
getIndex());
901 modelBuilder.getSolutionHintBuilder().addValues(value);
906 modelBuilder.clearSolutionHint();
911 modelBuilder.addAssumptions(lit.
getIndex());
923 modelBuilder.clearAssumptions();
931 CpObjectiveProto.Builder obj = modelBuilder.getObjectiveBuilder();
942 FloatObjectiveProto.Builder obj = modelBuilder.getFloatingPointObjectiveBuilder();
946 obj.setOffset(expr.
getOffset()).setMaximize(
false);
952 CpObjectiveProto.Builder obj = modelBuilder.getObjectiveBuilder();
958 obj.setScalingFactor(-1.0);
964 FloatObjectiveProto.Builder obj = modelBuilder.getFloatingPointObjectiveBuilder();
968 obj.setOffset(expr.
getOffset()).setMaximize(
true);
973 modelBuilder.clearObjective();
974 modelBuilder.clearFloatingPointObjective();
988 DecisionStrategyProto.Builder ds = modelBuilder.addSearchStrategyBuilder();
990 ds.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(arg,
false));
992 ds.setVariableSelectionStrategy(varStr).setDomainReductionStrategy(domStr);
999 DecisionStrategyProto.Builder ds = modelBuilder.addSearchStrategyBuilder();
1001 ds.addExprs(getLinearExpressionProtoBuilderFromLinearArgument(arg,
false));
1003 ds.setVariableSelectionStrategy(varStr).setDomainReductionStrategy(domStr);
1029 LinearExpressionProto.Builder getLinearExpressionProtoBuilderFromLinearArgument(
1034 final long mult = negate ? -1 : 1;
1035 for (
int i = 0; i < numVariables; ++i) {
1039 builder.setOffset(expr.
getOffset() * mult);
1043 LinearExpressionProto.Builder getLinearExpressionProtoBuilderFromLong(
long value) {
1044 LinearExpressionProto.Builder builder = LinearExpressionProto.newBuilder();
1045 builder.setOffset(value);
1052 return modelBuilder.build();
1061 return modelBuilder;
1064 private final CpModelProto.Builder modelBuilder;
1065 private final Map<Long, Integer> constantMap;
static Domain fromFlatIntervals(long[] flat_intervals)
long[] flattenedIntervals()