mimic C++ linear API in java for CP-SAT
This commit is contained in:
@@ -129,29 +129,15 @@ public class CpModel {
|
||||
|
||||
// Linear constraints.
|
||||
|
||||
/** Add {@code lb <= sum(vars) <= ub}. */
|
||||
public Constraint addSumConstraint(IntVar[] vars, long lb, long ub) {
|
||||
Constraint ct = new Constraint(modelBuilder);
|
||||
LinearConstraintProto.Builder lin = ct.getBuilder().getLinearBuilder();
|
||||
for (IntVar var : vars) {
|
||||
lin.addVars(var.getIndex());
|
||||
lin.addCoeffs(1);
|
||||
}
|
||||
lin.addDomain(lb);
|
||||
lin.addDomain(ub);
|
||||
return ct;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@code sum(vars) in domain}, where domain is a flattened list of intervals similar to the
|
||||
* one for enumerated integer variables.
|
||||
* Adds {@code expr in domain}.
|
||||
*/
|
||||
public Constraint addSumInDomain(IntVar[] vars, Domain domain) {
|
||||
public Constraint addLinearExpressionInDomain(LinearExpr expr, Domain domain) {
|
||||
Constraint ct = new Constraint(modelBuilder);
|
||||
LinearConstraintProto.Builder lin = ct.getBuilder().getLinearBuilder();
|
||||
for (IntVar var : vars) {
|
||||
lin.addVars(var.getIndex());
|
||||
lin.addCoeffs(1);
|
||||
for (int i = 0; i < expr.numElements(); ++i) {
|
||||
lin.addVars(expr.getVariable(i).getIndex());
|
||||
lin.addCoeffs(expr.getCoefficient(i));
|
||||
}
|
||||
for (long b : domain.flattenedIntervals()) {
|
||||
lin.addDomain(b);
|
||||
@@ -159,201 +145,75 @@ public class CpModel {
|
||||
return ct;
|
||||
}
|
||||
|
||||
/** Add {@code sum(vars) == value}. */
|
||||
public Constraint addSumEqual(IntVar[] vars, long value) {
|
||||
return addSumConstraint(vars, value, value);
|
||||
/** Adds {@code lb <= expr <= ub}. */
|
||||
public Constraint addLinearConstraint(LinearExpr expr, long lb, long ub) {
|
||||
return addLinearExpressionInDomain(expr, new Domain(lb, ub));
|
||||
}
|
||||
|
||||
/** Add {@code sum(vars) == target}. */
|
||||
public Constraint addSumEqual(IntVar[] vars, IntVar target) {
|
||||
int size = vars.length;
|
||||
IntVar[] newVars = new IntVar[size + 1];
|
||||
long[] coeffs = new long[size + 1];
|
||||
for (int i = 0; i < size; ++i) {
|
||||
newVars[i] = vars[i];
|
||||
coeffs[i] = 1;
|
||||
}
|
||||
newVars[size] = target;
|
||||
coeffs[size] = -1;
|
||||
return addLinearConstraint(newVars, coeffs, 0, 0);
|
||||
/** Adds {@code expr == value}. */
|
||||
public Constraint addEquality(LinearExpr expr, long value) {
|
||||
return addLinearExpressionInDomain(expr, new Domain(value));
|
||||
}
|
||||
|
||||
/** Add {@code lb <= sum(vars[i] * coeffs[i]) <= ub}. */
|
||||
public Constraint addLinearConstraint(IntVar[] vars, long[] coeffs, long lb, long ub) {
|
||||
Constraint ct = new Constraint(modelBuilder);
|
||||
LinearConstraintProto.Builder lin = ct.getBuilder().getLinearBuilder();
|
||||
for (IntVar var : vars) {
|
||||
lin.addVars(var.getIndex());
|
||||
}
|
||||
for (long c : coeffs) {
|
||||
lin.addCoeffs(c);
|
||||
}
|
||||
lin.addDomain(lb);
|
||||
lin.addDomain(ub);
|
||||
return ct;
|
||||
/** Adds {@code left == right}. */
|
||||
public Constraint addEquality(LinearExpr left, LinearExpr right) {
|
||||
return addLinearExpressionInDomain(new Difference(left, right), new Domain(0));
|
||||
}
|
||||
|
||||
/** Add {@code lb <= sum(vars[i] * coeffs[i]) <= ub}. */
|
||||
public Constraint addLinearConstraint(IntVar[] vars, int[] coeffs, long lb, long ub) {
|
||||
return addLinearConstraint(vars, toLongArray(coeffs), lb, ub);
|
||||
/** Adds {@code left + offset == right}. */
|
||||
public Constraint addEqualityWithOffset(LinearExpr left, LinearExpr right, long offset) {
|
||||
return addLinearExpressionInDomain(new Difference(left, right), new Domain(-offset));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@code sum(vars[i] * coeffs[i]) in domain}, where domain is a flattened list of intervals
|
||||
* similar to the one for enumerated integer variables.
|
||||
*/
|
||||
public Constraint addLinearExpressionInDomain(IntVar[] vars, long[] coeffs, Domain domain) {
|
||||
Constraint ct = new Constraint(modelBuilder);
|
||||
LinearConstraintProto.Builder lin = ct.getBuilder().getLinearBuilder();
|
||||
for (IntVar var : vars) {
|
||||
lin.addVars(var.getIndex());
|
||||
}
|
||||
for (long c : coeffs) {
|
||||
lin.addCoeffs(c);
|
||||
}
|
||||
for (long b : domain.flattenedIntervals()) {
|
||||
lin.addDomain(b);
|
||||
}
|
||||
return ct;
|
||||
/** Adds {@code expr <= value}. */
|
||||
public Constraint addLessOrEqual(LinearExpr expr, long value) {
|
||||
return addLinearExpressionInDomain(expr, new Domain(Long.MIN_VALUE, value));
|
||||
}
|
||||
|
||||
/** Add {@code sum(vars[i] * coeffs[i]) == value}. */
|
||||
public Constraint addLinearExpressionEqual(IntVar[] vars, long[] coeffs, long value) {
|
||||
return addLinearConstraint(vars, coeffs, value, value);
|
||||
/** Adds {@code left <= right}. */
|
||||
public Constraint addLessOrEqual(LinearExpr left, LinearExpr right) {
|
||||
return addLinearExpressionInDomain(new Difference(left, right),
|
||||
new Domain(Long.MIN_VALUE, 0));
|
||||
}
|
||||
|
||||
/** Add {@code sum(vars[i] * coeffs[i]) == value}. */
|
||||
public Constraint addLinearExpressionEqual(IntVar[] vars, int[] coeffs, long value) {
|
||||
return addLinearConstraint(vars, toLongArray(coeffs), value, value);
|
||||
/** Adds {@code left + offset <= right}. */
|
||||
public Constraint addLessOrEqualWithOffset(LinearExpr left, LinearExpr right, long offset) {
|
||||
return addLinearExpressionInDomain(new Difference(left, right),
|
||||
new Domain(Long.MIN_VALUE, -offset));
|
||||
}
|
||||
|
||||
/** Add {@code sum(vars[i] * coeffs[i]) == target}. */
|
||||
public Constraint addLinearExpressionEqual(IntVar[] vars, long[] coeffs, IntVar target) {
|
||||
int size = vars.length;
|
||||
IntVar[] newVars = new IntVar[size + 1];
|
||||
long[] newCoeffs = new long[size + 1];
|
||||
for (int i = 0; i < size; ++i) {
|
||||
newVars[i] = vars[i];
|
||||
newCoeffs[i] = coeffs[i];
|
||||
}
|
||||
newVars[size] = target;
|
||||
newCoeffs[size] = -1;
|
||||
return addLinearConstraint(newVars, newCoeffs, 0, 0);
|
||||
/** Adds {@code expr >= value}. */
|
||||
public Constraint addGreaterOrEqual(LinearExpr expr, long value) {
|
||||
return addLinearExpressionInDomain(expr, new Domain(value, Long.MAX_VALUE));
|
||||
}
|
||||
|
||||
/** Add {@code sum(vars[i] * coeffs[i]) == target}. */
|
||||
public Constraint addLinearExpressionEqual(IntVar[] vars, int[] coeffs, IntVar target) {
|
||||
return addLinearExpressionEqual(vars, toLongArray(coeffs), target);
|
||||
/** Adds {@code left >= right}. */
|
||||
public Constraint addGreaterOrEqual(LinearExpr left, LinearExpr right) {
|
||||
return addLinearExpressionInDomain(new Difference(left, right), new Domain(0, Long.MAX_VALUE));
|
||||
}
|
||||
|
||||
/** Adds {@code left + offset >= right}. */
|
||||
public Constraint addGreaterOrEqualWithOffset(LinearExpr left, LinearExpr right, long offset) {
|
||||
return addLinearExpressionInDomain(new Difference(left, right),
|
||||
new Domain(-offset, Long.MAX_VALUE));
|
||||
}
|
||||
|
||||
/** Adds {@code expr != value}. */
|
||||
public Constraint addDifferent(LinearExpr expr, long value) {
|
||||
return addLinearExpressionInDomain(expr, Domain.fromFlatIntervals(
|
||||
new long[] {Long.MIN_VALUE, value - 1, value + 1, Long.MAX_VALUE}));
|
||||
}
|
||||
|
||||
/** Adds {@code var <= value}. */
|
||||
public Constraint addLessOrEqual(IntVar var, long value) {
|
||||
Constraint ct = new Constraint(modelBuilder);
|
||||
LinearConstraintProto.Builder lin = ct.getBuilder().getLinearBuilder();
|
||||
lin.addVars(var.getIndex());
|
||||
lin.addCoeffs(1);
|
||||
lin.addDomain(java.lang.Long.MIN_VALUE);
|
||||
lin.addDomain(value);
|
||||
return ct;
|
||||
/** Adds {@code left != right}. */
|
||||
public Constraint addDifferent(IntVar left, IntVar right) {
|
||||
return addLinearExpressionInDomain(new Difference(left, right), Domain.fromFlatIntervals(
|
||||
new long[] {Long.MIN_VALUE, -1, 1, Long.MAX_VALUE}));
|
||||
}
|
||||
|
||||
/** Adds {@code before <= after}. */
|
||||
public Constraint addLessOrEqual(IntVar before, IntVar after) {
|
||||
return addLessOrEqualWithOffset(before, after, 0);
|
||||
}
|
||||
|
||||
/** Adds {@code var >= value}. */
|
||||
public Constraint addGreaterOrEqual(IntVar var, long value) {
|
||||
Constraint ct = new Constraint(modelBuilder);
|
||||
LinearConstraintProto.Builder lin = ct.getBuilder().getLinearBuilder();
|
||||
lin.addVars(var.getIndex());
|
||||
lin.addCoeffs(1);
|
||||
lin.addDomain(value);
|
||||
lin.addDomain(java.lang.Long.MAX_VALUE);
|
||||
return ct;
|
||||
}
|
||||
|
||||
/** Adds {@code var == value}. */
|
||||
public Constraint addEquality(IntVar var, long value) {
|
||||
Constraint ct = new Constraint(modelBuilder);
|
||||
LinearConstraintProto.Builder lin = ct.getBuilder().getLinearBuilder();
|
||||
lin.addVars(var.getIndex());
|
||||
lin.addCoeffs(1);
|
||||
lin.addDomain(value);
|
||||
lin.addDomain(value);
|
||||
return ct;
|
||||
}
|
||||
|
||||
/** Adds {@code a == b}. */
|
||||
public Constraint addEquality(IntVar a, IntVar b) {
|
||||
return addEqualityWithOffset(a, b, 0);
|
||||
}
|
||||
|
||||
/** Adds {@code a + offset == b}. */
|
||||
public Constraint addEqualityWithOffset(IntVar a, IntVar b, long offset) {
|
||||
Constraint ct = new Constraint(modelBuilder);
|
||||
LinearConstraintProto.Builder lin = ct.getBuilder().getLinearBuilder();
|
||||
lin.addVars(a.getIndex());
|
||||
lin.addCoeffs(-1);
|
||||
lin.addVars(b.getIndex());
|
||||
lin.addCoeffs(1);
|
||||
lin.addDomain(offset);
|
||||
lin.addDomain(offset);
|
||||
return ct;
|
||||
}
|
||||
|
||||
/** Adds {@code var != value}. */
|
||||
public Constraint addDifferent(IntVar var, long value) {
|
||||
Constraint ct = new Constraint(modelBuilder);
|
||||
LinearConstraintProto.Builder lin = ct.getBuilder().getLinearBuilder();
|
||||
lin.addVars(var.getIndex());
|
||||
lin.addCoeffs(1);
|
||||
if (value > java.lang.Long.MIN_VALUE) {
|
||||
lin.addDomain(java.lang.Long.MIN_VALUE);
|
||||
lin.addDomain(value - 1);
|
||||
}
|
||||
if (value < java.lang.Long.MAX_VALUE) {
|
||||
lin.addDomain(value + 1);
|
||||
lin.addDomain(java.lang.Long.MAX_VALUE);
|
||||
}
|
||||
return ct;
|
||||
}
|
||||
|
||||
/** Adds {@code a != b}. */
|
||||
public Constraint addDifferent(IntVar a, IntVar b) {
|
||||
return addDifferentWithOffset(a, b, 0);
|
||||
}
|
||||
|
||||
/** Adds {@code a + offset != b} */
|
||||
public Constraint addDifferentWithOffset(IntVar a, IntVar b, long offset) {
|
||||
Constraint ct = new Constraint(modelBuilder);
|
||||
LinearConstraintProto.Builder lin = ct.getBuilder().getLinearBuilder();
|
||||
lin.addVars(a.getIndex());
|
||||
lin.addCoeffs(-1);
|
||||
lin.addVars(b.getIndex());
|
||||
lin.addCoeffs(1);
|
||||
if (offset > java.lang.Long.MIN_VALUE) {
|
||||
lin.addDomain(java.lang.Long.MIN_VALUE);
|
||||
lin.addDomain(offset - 1);
|
||||
}
|
||||
if (offset < java.lang.Long.MAX_VALUE) {
|
||||
lin.addDomain(offset + 1);
|
||||
lin.addDomain(java.lang.Long.MAX_VALUE);
|
||||
}
|
||||
return ct;
|
||||
}
|
||||
|
||||
/** Adds {@code before + offset <= after}. */
|
||||
public Constraint addLessOrEqualWithOffset(IntVar before, IntVar after, long offset) {
|
||||
Constraint ct = new Constraint(modelBuilder);
|
||||
LinearConstraintProto.Builder lin = ct.getBuilder().getLinearBuilder();
|
||||
lin.addVars(before.getIndex());
|
||||
lin.addCoeffs(-1);
|
||||
lin.addVars(after.getIndex());
|
||||
lin.addCoeffs(1);
|
||||
lin.addDomain(offset);
|
||||
lin.addDomain(java.lang.Long.MAX_VALUE);
|
||||
return ct;
|
||||
/** Adds {@code left + offset != right}. */
|
||||
public Constraint addDifferentWithOffset(IntVar left, IntVar right, long offset) {
|
||||
return addLinearExpressionInDomain(new Difference(left, right), Domain.fromFlatIntervals(
|
||||
new long[] {Long.MIN_VALUE, -offset - 1, -offset + 1, Long.MAX_VALUE}));
|
||||
}
|
||||
|
||||
// Integer constraints.
|
||||
@@ -1074,73 +934,25 @@ public class CpModel {
|
||||
|
||||
// Objective.
|
||||
|
||||
/** Adds a minimization objective of a single variable. */
|
||||
public void minimize(IntVar var) {
|
||||
/** Adds a minimization objective of a linear expression. */
|
||||
public void minimize(LinearExpr expr) {
|
||||
CpObjectiveProto.Builder obj = modelBuilder.getObjectiveBuilder();
|
||||
obj.addVars(var.getIndex());
|
||||
obj.addCoeffs(1);
|
||||
}
|
||||
|
||||
/** Adds a minimization objective of a sum of variables. */
|
||||
public void minimizeSum(IntVar[] vars) {
|
||||
CpObjectiveProto.Builder obj = modelBuilder.getObjectiveBuilder();
|
||||
for (IntVar var : vars) {
|
||||
obj.addVars(var.getIndex());
|
||||
obj.addCoeffs(1);
|
||||
for (int i = 0; i < expr.numElements(); ++i) {
|
||||
obj.addVars(expr.getVariable(i).getIndex());
|
||||
obj.addCoeffs(expr.getCoefficient(i));
|
||||
}
|
||||
}
|
||||
|
||||
/** Adds a minimization objective of a scalar product of variables. */
|
||||
public void minimizeLinearExpression(IntVar[] vars, long[] coeffs) {
|
||||
/** Adds a maximization objective of a linear expression. */
|
||||
public void maximize(LinearExpr expr) {
|
||||
CpObjectiveProto.Builder obj = modelBuilder.getObjectiveBuilder();
|
||||
for (IntVar var : vars) {
|
||||
obj.addVars(var.getIndex());
|
||||
}
|
||||
for (long c : coeffs) {
|
||||
obj.addCoeffs(c);
|
||||
}
|
||||
}
|
||||
|
||||
/** Adds a minimization objective of a scalar product of variables. */
|
||||
public void minimizeLinearExpression(IntVar[] vars, int[] coeffs) {
|
||||
minimizeLinearExpression(vars, toLongArray(coeffs));
|
||||
}
|
||||
|
||||
/** Adds a maximization objective of a single variable. */
|
||||
public void maximize(IntVar var) {
|
||||
CpObjectiveProto.Builder obj = modelBuilder.getObjectiveBuilder();
|
||||
obj.addVars(negated(var.getIndex()));
|
||||
obj.addCoeffs(1);
|
||||
obj.setScalingFactor(-1.0);
|
||||
}
|
||||
|
||||
/** Adds a maximization objective of a sum of variables. */
|
||||
public void maximizeSum(IntVar[] vars) {
|
||||
CpObjectiveProto.Builder obj = modelBuilder.getObjectiveBuilder();
|
||||
for (IntVar var : vars) {
|
||||
obj.addVars(negated(var.getIndex()));
|
||||
obj.addCoeffs(1);
|
||||
for (int i = 0; i < expr.numElements(); ++i) {
|
||||
obj.addVars(expr.getVariable(i).getIndex());
|
||||
obj.addCoeffs(-expr.getCoefficient(i));
|
||||
}
|
||||
obj.setScalingFactor(-1.0);
|
||||
}
|
||||
|
||||
/** Adds a maximization objective of a scalar product of variables. */
|
||||
public void maximizeLinearExpression(IntVar[] vars, long[] coeffs) {
|
||||
CpObjectiveProto.Builder obj = modelBuilder.getObjectiveBuilder();
|
||||
for (IntVar var : vars) {
|
||||
obj.addVars(negated(var.getIndex()));
|
||||
}
|
||||
for (long c : coeffs) {
|
||||
obj.addCoeffs(c);
|
||||
}
|
||||
obj.setScalingFactor(-1.0);
|
||||
}
|
||||
|
||||
/** Adds a maximization objective of a scalar product of variables. */
|
||||
public void maximizeLinearExpression(IntVar[] vars, int[] coeffs) {
|
||||
maximizeLinearExpression(vars, toLongArray(coeffs));
|
||||
}
|
||||
|
||||
// DecisionStrategy
|
||||
|
||||
/** Adds {@code DecisionStrategy(variables, varStr, domStr)}. */
|
||||
|
||||
45
ortools/com/google/ortools/sat/Difference.java
Normal file
45
ortools/com/google/ortools/sat/Difference.java
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2010-2018 Google LLC
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.ortools.sat;
|
||||
|
||||
/** the substraction of two linear expressions. Used internally. */
|
||||
class Difference implements LinearExpr {
|
||||
private LinearExpr left;
|
||||
private LinearExpr right;
|
||||
|
||||
public Difference(LinearExpr left, LinearExpr right) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
public int numElements() {
|
||||
return left.numElements() + right.numElements();
|
||||
}
|
||||
|
||||
public IntVar getVariable(int index) {
|
||||
if (index < left.numElements()) {
|
||||
return left.getVariable(index);
|
||||
} else {
|
||||
return right.getVariable(index - left.numElements());
|
||||
}
|
||||
}
|
||||
|
||||
public long getCoefficient(int index) {
|
||||
if (index < left.numElements()) {
|
||||
return left.getCoefficient(index);
|
||||
} else {
|
||||
return -right.getCoefficient(index - left.numElements());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ import com.google.ortools.sat.CpModelProto;
|
||||
import com.google.ortools.sat.IntegerVariableProto;
|
||||
|
||||
/** An integer variable. */
|
||||
public class IntVar implements Literal {
|
||||
public class IntVar implements Literal, LinearExpr {
|
||||
IntVar(CpModelProto.Builder builder, Domain domain, String name) {
|
||||
this.modelBuilder = builder;
|
||||
this.variableIndex = modelBuilder.getVariablesCount();
|
||||
@@ -50,6 +50,21 @@ public class IntVar implements Literal {
|
||||
return varBuilder;
|
||||
}
|
||||
|
||||
// LinearExpr interface.
|
||||
public int numElements() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public IntVar getVariable(int index) {
|
||||
assert(index == 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getCoefficient(int index) {
|
||||
assert(index == 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Returns a short string describing the variable. */
|
||||
@Override
|
||||
public String getShortString() {
|
||||
|
||||
46
ortools/com/google/ortools/sat/LinearExpr.java
Normal file
46
ortools/com/google/ortools/sat/LinearExpr.java
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright 2010-2018 Google LLC
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.ortools.sat;
|
||||
|
||||
/** A linear expression interface that can be parsed. */
|
||||
public interface LinearExpr {
|
||||
/** Returns the number of elements in the interface. */
|
||||
int numElements();
|
||||
|
||||
/** Returns the ith variable. */
|
||||
IntVar getVariable(int index);
|
||||
|
||||
/** Returns the ith coefficient. */
|
||||
long getCoefficient(int index);
|
||||
|
||||
/** Creates a sum expression. */
|
||||
static LinearExpr Sum(IntVar[] variables) {
|
||||
return new SumOfVariables(variables);
|
||||
}
|
||||
|
||||
/** Creates a scalar product. */
|
||||
static LinearExpr ScalProd(IntVar[] variables, long[] coefficients) {
|
||||
return new ScalProd(variables, coefficients);
|
||||
}
|
||||
|
||||
/** Creates a scalar product. */
|
||||
static LinearExpr ScalProd(IntVar[] variables, int[] coefficients) {
|
||||
long[] tmp = new long[coefficients.length];
|
||||
for (int i = 0; i < coefficients.length; ++i) {
|
||||
tmp[i] = coefficients[i];
|
||||
}
|
||||
return new ScalProd(variables, tmp);
|
||||
}
|
||||
|
||||
}
|
||||
37
ortools/com/google/ortools/sat/ScalProd.java
Normal file
37
ortools/com/google/ortools/sat/ScalProd.java
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright 2010-2018 Google LLC
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.ortools.sat;
|
||||
|
||||
/** A linear expression interface that can be parsed. */
|
||||
public class ScalProd implements LinearExpr {
|
||||
private IntVar[] variables;
|
||||
private long[] coefficients;
|
||||
|
||||
public ScalProd(IntVar[] variables, long[] coefficients) {
|
||||
this.variables = variables;
|
||||
this.coefficients = coefficients;
|
||||
}
|
||||
|
||||
public int numElements() {
|
||||
return variables.length;
|
||||
}
|
||||
|
||||
public IntVar getVariable(int index) {
|
||||
return variables[index];
|
||||
}
|
||||
|
||||
public long getCoefficient(int index) {
|
||||
return coefficients[index];
|
||||
}
|
||||
}
|
||||
35
ortools/com/google/ortools/sat/SumOfVariables.java
Normal file
35
ortools/com/google/ortools/sat/SumOfVariables.java
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright 2010-2018 Google LLC
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.ortools.sat;
|
||||
|
||||
/** A linear expression interface that can be parsed. */
|
||||
public class SumOfVariables implements LinearExpr {
|
||||
private IntVar[] variables;
|
||||
|
||||
public SumOfVariables(IntVar[] variables) {
|
||||
this.variables = variables;
|
||||
}
|
||||
|
||||
public int numElements() {
|
||||
return variables.length;
|
||||
}
|
||||
|
||||
public IntVar getVariable(int index) {
|
||||
return variables[index];
|
||||
}
|
||||
|
||||
public long getCoefficient(int index) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import com.google.ortools.sat.CpModel;
|
||||
import com.google.ortools.sat.CpSolver;
|
||||
import com.google.ortools.sat.CpSolverStatus;
|
||||
import com.google.ortools.sat.IntVar;
|
||||
import com.google.ortools.sat.LinearExpr;
|
||||
|
||||
/** Solves a bin packing problem with the CP-SAT solver. */
|
||||
public class BinPackingProblemSat {
|
||||
@@ -65,7 +66,7 @@ public class BinPackingProblemSat {
|
||||
for (int i = 0; i < numItems; ++i) {
|
||||
vars[i] = x[i][b];
|
||||
}
|
||||
model.addLinearExpressionEqual(vars, sizes, load[b]);
|
||||
model.addEquality(LinearExpr.ScalProd(vars, sizes), load[b]);
|
||||
}
|
||||
|
||||
// Place all items.
|
||||
@@ -74,7 +75,7 @@ public class BinPackingProblemSat {
|
||||
for (int b = 0; b < numBins; ++b) {
|
||||
vars[b] = x[i][b];
|
||||
}
|
||||
model.addSumEqual(vars, items[i][1]);
|
||||
model.addEquality(LinearExpr.Sum(vars), items[i][1]);
|
||||
}
|
||||
|
||||
// Links load and slack.
|
||||
@@ -87,7 +88,7 @@ public class BinPackingProblemSat {
|
||||
}
|
||||
|
||||
// Maximize sum of slacks.
|
||||
model.maximizeSum(slacks);
|
||||
model.maximize(LinearExpr.Sum(slacks));
|
||||
|
||||
// Solves and prints out the solution.
|
||||
CpSolver solver = new CpSolver();
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.google.ortools.sat.CpSolver;
|
||||
import com.google.ortools.sat.CpSolverSolutionCallback;
|
||||
import com.google.ortools.sat.DecisionStrategyProto;
|
||||
import com.google.ortools.sat.IntVar;
|
||||
import com.google.ortools.sat.LinearExpr;
|
||||
import com.google.ortools.sat.SatParameters;
|
||||
|
||||
/** Link integer constraints together. */
|
||||
@@ -41,7 +42,7 @@ public class ChannelingSampleSat {
|
||||
|
||||
// Create our two half-reified constraints.
|
||||
// First, b implies (y == 10 - x).
|
||||
model.addSumEqual(new IntVar[] {x, y}, 10).onlyEnforceIf(b);
|
||||
model.addEquality(LinearExpr.Sum(new IntVar[] {x, y}), 10).onlyEnforceIf(b);
|
||||
// Second, not(b) implies y == 0.
|
||||
model.addEquality(y, 0).onlyEnforceIf(b.not());
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.google.ortools.sat.CpModel;
|
||||
import com.google.ortools.sat.CpSolver;
|
||||
import com.google.ortools.sat.CpSolverSolutionCallback;
|
||||
import com.google.ortools.sat.IntVar;
|
||||
import com.google.ortools.sat.LinearExpr;
|
||||
|
||||
/** Cryptarithmetic puzzle. */
|
||||
public class CpIsFunSat {
|
||||
@@ -73,9 +74,9 @@ public class CpIsFunSat {
|
||||
model.addAllDifferent(letters);
|
||||
|
||||
// CP + IS + FUN = TRUE
|
||||
model.addLinearExpressionEqual(new IntVar[] {c, p, i, s, f, u, n, t, r, u, e},
|
||||
model.addEquality(LinearExpr.ScalProd(new IntVar[] {c, p, i, s, f, u, n, t, r, u, e},
|
||||
new long[] {
|
||||
base, 1, base, 1, base * base, base, 1, -base * base * base, -base * base, -base, -1},
|
||||
base, 1, base, 1, base * base, base, 1, -base * base * base, -base * base, -base, -1}),
|
||||
0);
|
||||
// [END constraints]
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.google.ortools.sat.CpSolver;
|
||||
import com.google.ortools.sat.CpSolverSolutionCallback;
|
||||
import com.google.ortools.sat.DecisionStrategyProto;
|
||||
import com.google.ortools.sat.IntVar;
|
||||
import com.google.ortools.sat.LinearExpr;
|
||||
import com.google.ortools.sat.SatParameters;
|
||||
|
||||
/** Encode the piecewise linear expression. */
|
||||
@@ -47,16 +48,18 @@ public class EarlinessTardinessCostSampleSat {
|
||||
|
||||
// First segment: s1 == earlinessCost * (earlinessDate - x).
|
||||
IntVar s1 = model.newIntVar(-largeConstant, largeConstant, "s1");
|
||||
model.addLinearExpressionEqual(
|
||||
new IntVar[] {s1, x}, new long[] {1, earlinessCost}, earlinessCost* earlinessDate);
|
||||
model.addEquality(
|
||||
LinearExpr.ScalProd(new IntVar[] {s1, x}, new long[] {1, earlinessCost}),
|
||||
earlinessCost* earlinessDate);
|
||||
|
||||
// Second segment.
|
||||
IntVar s2 = model.newConstant(0);
|
||||
|
||||
// Third segment: s3 == latenessCost * (x - latenessDate).
|
||||
IntVar s3 = model.newIntVar(-largeConstant, largeConstant, "s3");
|
||||
model.addLinearExpressionEqual(
|
||||
new IntVar[] {s3, x}, new long[] {1, -latenessCost}, -latenessCost* latenessDate);
|
||||
model.addEquality(
|
||||
LinearExpr.ScalProd(new IntVar[] {s3, x}, new long[] {1, -latenessCost}),
|
||||
-latenessCost* latenessDate);
|
||||
|
||||
// Link together expr and x through s1, s2, and s3.
|
||||
model.addMaxEquality(expr, new IntVar[] {s1, s2, s3});
|
||||
|
||||
@@ -15,6 +15,7 @@ import com.google.ortools.sat.CpModel;
|
||||
import com.google.ortools.sat.CpSolver;
|
||||
import com.google.ortools.sat.CpSolverStatus;
|
||||
import com.google.ortools.sat.IntVar;
|
||||
import com.google.ortools.sat.LinearExpr;
|
||||
|
||||
/**
|
||||
* In a field of rabbits and pheasants, there are 20 heads and 56 legs. How many rabbits and
|
||||
@@ -32,9 +33,9 @@ public class RabbitsAndPheasantsSat {
|
||||
IntVar r = model.newIntVar(0, 100, "r");
|
||||
IntVar p = model.newIntVar(0, 100, "p");
|
||||
// 20 heads.
|
||||
model.addSumEqual(new IntVar[] {r, p}, 20);
|
||||
model.addEquality(LinearExpr.Sum(new IntVar[] {r, p}), 20);
|
||||
// 56 legs.
|
||||
model.addLinearExpressionEqual(new IntVar[] {r, p}, new long[] {4, 2}, 56);
|
||||
model.addEquality(LinearExpr.ScalProd(new IntVar[] {r, p}, new long[] {4, 2}), 56);
|
||||
|
||||
// Creates a solver and solves the model.
|
||||
CpSolver solver = new CpSolver();
|
||||
|
||||
@@ -15,6 +15,7 @@ import com.google.ortools.sat.CpModel;
|
||||
import com.google.ortools.sat.CpSolver;
|
||||
import com.google.ortools.sat.CpSolverStatus;
|
||||
import com.google.ortools.sat.IntVar;
|
||||
import com.google.ortools.sat.LinearExpr;
|
||||
import com.google.ortools.sat.IntervalVar;
|
||||
import com.google.ortools.sat.Literal;
|
||||
import java.util.ArrayList;
|
||||
@@ -89,7 +90,7 @@ public class RankingSampleSat {
|
||||
vars[numTasks] = ranks[i];
|
||||
coefs[numTasks] = -1;
|
||||
// ranks == sum(precedences) - 1;
|
||||
model.addLinearExpressionEqual(vars, coefs, 1);
|
||||
model.addEquality(LinearExpr.ScalProd(vars, coefs), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +154,7 @@ public class RankingSampleSat {
|
||||
}
|
||||
objectiveVars[numTasks] = makespan;
|
||||
objectiveCoefs[numTasks] = 2;
|
||||
model.minimizeLinearExpression(objectiveVars, objectiveCoefs);
|
||||
model.minimize(LinearExpr.ScalProd(objectiveVars, objectiveCoefs));
|
||||
|
||||
// Creates a solver and solves the model.
|
||||
CpSolver solver = new CpSolver();
|
||||
|
||||
@@ -70,7 +70,7 @@ public class SolveAndPrintIntermediateSolutionsSampleSat {
|
||||
|
||||
// Maximize a linear combination of variables.
|
||||
// [START objective]
|
||||
model.maximizeLinearExpression(new IntVar[] {x, y, z}, new int[] {1, 2, 3});
|
||||
model.maximize(LinearExpr.ScalProd(new IntVar[] {x, y, z}, new int[] {1, 2, 3}));
|
||||
// [END objective]
|
||||
|
||||
// Create a solver and solve the model.
|
||||
|
||||
@@ -46,16 +46,14 @@ public class StepFunctionSampleSat {
|
||||
|
||||
// expr == 0 on [5, 6] U [8, 10]
|
||||
Literal b0 = model.newBoolVar("b0");
|
||||
model.addSumInDomain(new IntVar[] {x}, Domain.fromValues(new long[] {5, 6, 8, 9, 10}))
|
||||
.onlyEnforceIf(b0);
|
||||
model.addLinearExpressionInDomain(
|
||||
x, Domain.fromValues(new long[] {5, 6, 8, 9, 10})).onlyEnforceIf(b0);
|
||||
model.addEquality(expr, 0).onlyEnforceIf(b0);
|
||||
|
||||
// expr == 2 on [0, 1] U [3, 4] U [11, 20]
|
||||
Literal b2 = model.newBoolVar("b2");
|
||||
model
|
||||
.addSumInDomain(
|
||||
new IntVar[] {x}, Domain.fromIntervals(new long[][] {{0, 1}, {3, 4}, {11, 20}}))
|
||||
.onlyEnforceIf(b2);
|
||||
model.addLinearExpressionInDomain(
|
||||
x, Domain.fromIntervals(new long[][] {{0, 1}, {3, 4}, {11, 20}})).onlyEnforceIf(b2);
|
||||
model.addEquality(expr, 2).onlyEnforceIf(b2);
|
||||
|
||||
// expr == 3 when x = 7
|
||||
|
||||
Reference in New Issue
Block a user