incomplete ModelBuilder java implementation
This commit is contained in:
@@ -149,7 +149,7 @@ endif()
|
||||
set(JAVA_SRC_PATH src/main/java/${JAVA_DOMAIN_EXTENSION}/${JAVA_DOMAIN_NAME}/${JAVA_ARTIFACT})
|
||||
set(JAVA_TEST_PATH src/test/java/${JAVA_DOMAIN_EXTENSION}/${JAVA_DOMAIN_NAME}/${JAVA_ARTIFACT})
|
||||
set(JAVA_RESSOURCES_PATH src/main/resources)
|
||||
foreach(SUBPROJECT IN ITEMS algorithms graph init linear_solver constraint_solver sat util)
|
||||
foreach(SUBPROJECT IN ITEMS algorithms graph init linear_solver model_builder constraint_solver sat util)
|
||||
add_subdirectory(ortools/${SUBPROJECT}/java)
|
||||
target_link_libraries(jni${JAVA_ARTIFACT} PRIVATE jni${SUBPROJECT})
|
||||
endforeach()
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
// Copyright 2010-2021 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.modelbuilder;
|
||||
|
||||
/** A specialized linear expression: a * x + b */
|
||||
public final class AffineExpression implements LinearExpr {
|
||||
private final int varIndex;
|
||||
private final double coefficient;
|
||||
private final double offset;
|
||||
|
||||
public AffineExpression(int varIndex, double coefficient, double offset) {
|
||||
this.varIndex = varIndex;
|
||||
this.coefficient = coefficient;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
// LinearArgument interface.
|
||||
@Override
|
||||
public LinearExpr build() {
|
||||
return this;
|
||||
}
|
||||
|
||||
// LinearExpr interface.
|
||||
@Override
|
||||
public int numElements() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVariableIndex(int index) {
|
||||
if (index != 0) {
|
||||
throw new IllegalArgumentException("wrong index in LinearExpr.getIndex(): " + index);
|
||||
}
|
||||
return varIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCoefficient(int index) {
|
||||
if (index != 0) {
|
||||
throw new IllegalArgumentException("wrong index in LinearExpr.getCoefficient(): " + index);
|
||||
}
|
||||
return coefficient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getOffset() {
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright 2010-2021 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.modelbuilder;
|
||||
|
||||
/** A specialized constant linear expression. */
|
||||
public final class ConstantExpression implements LinearExpr {
|
||||
private final double offset;
|
||||
|
||||
public ConstantExpression(double offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
// LinearArgument interface.
|
||||
@Override
|
||||
public LinearExpr build() {
|
||||
return this;
|
||||
}
|
||||
|
||||
// LinearExpr interface.
|
||||
@Override
|
||||
public int numElements() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVariableIndex(int index) {
|
||||
throw new IllegalArgumentException("wrong index in LinearExpr.getVariable(): " + index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCoefficient(int index) {
|
||||
throw new IllegalArgumentException("wrong index in LinearExpr.getCoefficient(): " + index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%f", offset);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// Copyright 2010-2021 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.modelbuilder;
|
||||
|
||||
/**
|
||||
* A object that can build a LinearExpr object.
|
||||
*
|
||||
* <p>This class is used in all modeling methods of the CpModel class.
|
||||
*/
|
||||
public interface LinearArgument {
|
||||
/** Builds a linear expression. */
|
||||
LinearExpr build();
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
// Copyright 2010-2021 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.modelbuilder;
|
||||
|
||||
/** Wrapper around a linear constraint stored in the ModelBuilderHelper instance. */
|
||||
public class LinearConstraint {
|
||||
public LinearConstraint(ModelBuilderHelper helper) {
|
||||
this.helper = helper;
|
||||
this.index = helper.addLinearConstraint();
|
||||
}
|
||||
|
||||
/** Returns the index of the constraint in the model. */
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
/** Returns the constraint builder. */
|
||||
public ModelBuilderHelper getHelper() {
|
||||
return helper;
|
||||
}
|
||||
|
||||
/** Returns the lower bound of the variable. */
|
||||
public double getLowerBound() {
|
||||
return helper.getConstraintLowerBound(index);
|
||||
}
|
||||
|
||||
/** Returns the upper bound of the variable. */
|
||||
public double getUpperBound() {
|
||||
return helper.getConstraintUpperBound(index);
|
||||
}
|
||||
|
||||
/** Returns the name of the variable given upon creation. */
|
||||
public String getName() {
|
||||
return helper.getConstraintName(index);
|
||||
}
|
||||
|
||||
/** Returns the lower bound of the variable. */
|
||||
public void setLowerBound(double lb) {
|
||||
helper.setConstraintLowerBound(index, lb);
|
||||
}
|
||||
|
||||
/** Returns the upper bound of the variable. */
|
||||
public void setUpperBound(double ub) {
|
||||
helper.setConstraintUpperBound(index, ub);
|
||||
}
|
||||
|
||||
// Adds var * coeff to the constraint.
|
||||
public void addTerm(Variable var, double coeff) {
|
||||
helper.addConstraintTerm(index, var.getIndex(), coeff);
|
||||
}
|
||||
|
||||
/** Returns the name of the variable given upon creation. */
|
||||
public void setName(String name) {
|
||||
helper.setConstraintName(index, name);
|
||||
}
|
||||
|
||||
/** Inline setter */
|
||||
public LinearConstraint withName(String name) {
|
||||
setName(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
private final ModelBuilderHelper helper;
|
||||
private final int index;
|
||||
}
|
||||
59
ortools/java/com/google/ortools/modelbuilder/LinearExpr.java
Normal file
59
ortools/java/com/google/ortools/modelbuilder/LinearExpr.java
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright 2010-2021 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.modelbuilder;
|
||||
|
||||
/** A linear expression (sum (ai * xi) + b). It specifies methods to help parsing the expression. */
|
||||
public interface LinearExpr extends LinearArgument {
|
||||
/** Returns the number of terms (excluding the constant one) in this expression. */
|
||||
int numElements();
|
||||
|
||||
/** Returns the index of the ith variable. */
|
||||
int getVariableIndex(int index);
|
||||
|
||||
/** Returns the ith coefficient. */
|
||||
double getCoefficient(int index);
|
||||
|
||||
/** Returns the constant part of the expression. */
|
||||
double getOffset();
|
||||
|
||||
/** Returns a builder */
|
||||
static LinearExprBuilder newBuilder() {
|
||||
return new LinearExprBuilder();
|
||||
}
|
||||
|
||||
/** Shortcut for newBuilder().add(value).build() */
|
||||
static LinearExpr constant(double value) {
|
||||
return newBuilder().add(value).build();
|
||||
}
|
||||
|
||||
/** Shortcut for newBuilder().addTerm(expr, coeff).build() */
|
||||
static LinearExpr term(LinearArgument expr, double coeff) {
|
||||
return newBuilder().addTerm(expr, coeff).build();
|
||||
}
|
||||
|
||||
/** Shortcut for newBuilder().addTerm(expr, coeff).add(offset).build() */
|
||||
static LinearExpr affine(LinearArgument expr, double coeff, double offset) {
|
||||
return newBuilder().addTerm(expr, coeff).add(offset).build();
|
||||
}
|
||||
|
||||
/** Shortcut for newBuilder().addSum(exprs).build() */
|
||||
static LinearExpr sum(LinearExpr[] exprs) {
|
||||
return newBuilder().addSum(exprs).build();
|
||||
}
|
||||
|
||||
/** Shortcut for newBuilder().addWeightedSum(exprs, coeffs).build() */
|
||||
static LinearExpr weightedSum(LinearArgument[] exprs, double[] coeffs) {
|
||||
return newBuilder().addWeightedSum(exprs, coeffs).build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
// Copyright 2010-2021 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.modelbuilder;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/** Builder class for the LinearExpr container. */
|
||||
public final class LinearExprBuilder implements LinearArgument {
|
||||
private final TreeMap<Integer, Double> coefficients;
|
||||
private double offset;
|
||||
|
||||
LinearExprBuilder() {
|
||||
this.coefficients = new TreeMap<>();
|
||||
this.offset = 0;
|
||||
}
|
||||
|
||||
public LinearExprBuilder add(LinearArgument expr) {
|
||||
addTerm(expr, 1);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LinearExprBuilder add(double constant) {
|
||||
offset = offset + constant;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LinearExprBuilder addTerm(LinearArgument expr, double coeff) {
|
||||
final LinearExpr e = expr.build();
|
||||
final int numElements = e.numElements();
|
||||
for (int i = 0; i < numElements; ++i) {
|
||||
coefficients.merge(e.getVariableIndex(i), e.getCoefficient(i) * coeff, Double::sum);
|
||||
}
|
||||
offset = offset + e.getOffset() * coeff;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LinearExprBuilder addSum(LinearArgument[] exprs) {
|
||||
for (final LinearArgument expr : exprs) {
|
||||
addTerm(expr, 1);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public LinearExprBuilder addWeightedSum(LinearArgument[] exprs, double[] coeffs) {
|
||||
for (int i = 0; i < exprs.length; ++i) {
|
||||
addTerm(exprs[i], coeffs[i]);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public LinearExprBuilder addWeightedSum(LinearArgument[] exprs, int[] coeffs) {
|
||||
for (int i = 0; i < exprs.length; ++i) {
|
||||
addTerm(exprs[i], coeffs[i]);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public LinearExprBuilder addWeightedSum(LinearArgument[] exprs, long[] coeffs) {
|
||||
for (int i = 0; i < exprs.length; ++i) {
|
||||
addTerm(exprs[i], coeffs[i]);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinearExpr build() {
|
||||
int numElements = 0;
|
||||
int lastVarIndex = -1;
|
||||
double lastCoeff = 0;
|
||||
for (Map.Entry<Integer, Double> entry : coefficients.entrySet()) {
|
||||
if (entry.getValue() != 0) {
|
||||
numElements++;
|
||||
lastVarIndex = entry.getKey();
|
||||
lastCoeff = entry.getValue();
|
||||
}
|
||||
}
|
||||
if (numElements == 0) {
|
||||
return new ConstantExpression(offset);
|
||||
} else if (numElements == 1) {
|
||||
return new AffineExpression(lastVarIndex, lastCoeff, offset);
|
||||
} else {
|
||||
int[] varIndices = new int[numElements];
|
||||
double[] coeffs = new double[numElements];
|
||||
int index = 0;
|
||||
for (Map.Entry<Integer, Double> entry : coefficients.entrySet()) {
|
||||
if (entry.getValue() != 0) {
|
||||
varIndices[index] = entry.getKey();
|
||||
coeffs[index] = entry.getValue();
|
||||
index++;
|
||||
}
|
||||
}
|
||||
return new WeightedSumExpression(varIndices, coeffs, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
206
ortools/java/com/google/ortools/modelbuilder/ModelBuilder.java
Normal file
206
ortools/java/com/google/ortools/modelbuilder/ModelBuilder.java
Normal file
@@ -0,0 +1,206 @@
|
||||
// Copyright 2010-2021 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.modelbuilder;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Main modeling class.
|
||||
*
|
||||
* <p>Proposes a factory to create all modeling objects understood by the SAT solver.
|
||||
*/
|
||||
public final class ModelBuilder {
|
||||
static class ModelBuilderException extends RuntimeException {
|
||||
public ModelBuilderException(String methodName, String msg) {
|
||||
// Call constructor of parent Exception
|
||||
super(methodName + ": " + msg);
|
||||
}
|
||||
}
|
||||
|
||||
/** Exception thrown when parallel arrays have mismatched lengths. */
|
||||
public static class MismatchedArrayLengths extends ModelBuilderException {
|
||||
public MismatchedArrayLengths(String methodName, String array1Name, String array2Name) {
|
||||
super(methodName, array1Name + " and " + array2Name + " have mismatched lengths");
|
||||
}
|
||||
}
|
||||
|
||||
/** Exception thrown when an array has a wrong length. */
|
||||
public static class WrongLength extends ModelBuilderException {
|
||||
public WrongLength(String methodName, String msg) {
|
||||
super(methodName, msg);
|
||||
}
|
||||
}
|
||||
|
||||
public ModelBuilder() {
|
||||
helper = new ModelBuilderHelper();
|
||||
constantMap = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
// Integer variables.
|
||||
|
||||
/** Creates a variable with domain [lb, ub]. */
|
||||
public Variable newVar(double lb, double ub, boolean isIntegral, String name) {
|
||||
return new Variable(helper, lb, ub, isIntegral, name);
|
||||
}
|
||||
|
||||
/** Creates an continuous variable with domain [lb, ub]. */
|
||||
public Variable newNumVar(double lb, double ub, String name) {
|
||||
return new Variable(helper, lb, ub, false, name);
|
||||
}
|
||||
|
||||
/** Creates an integer variable with domain [lb, ub]. */
|
||||
public Variable newIntVar(double lb, double ub, String name) {
|
||||
return new Variable(helper, lb, ub, true, name);
|
||||
}
|
||||
|
||||
/** Creates a Boolean variable with the given name. */
|
||||
public Variable newBoolVar(String name) {
|
||||
return new Variable(helper, 0, 1, true, name);
|
||||
}
|
||||
|
||||
/** Creates a constant variable. */
|
||||
public Variable newConstant(double value) {
|
||||
if (constantMap.containsKey(value)) {
|
||||
return new Variable(helper, constantMap.get(value));
|
||||
}
|
||||
Variable cste = new Variable(helper, value, value, false, ""); // bounds and name.
|
||||
constantMap.put(value, cste.getIndex());
|
||||
return cste;
|
||||
}
|
||||
|
||||
/** Rebuilds a variable from its index. */
|
||||
public Variable varFromIndex(int index) {
|
||||
return new Variable(helper, index);
|
||||
}
|
||||
|
||||
// Linear constraints.
|
||||
|
||||
/** Adds {@code lb <= expr <= ub}. */
|
||||
public LinearConstraint addLinearConstraint(LinearArgument expr, double lb, double ub) {
|
||||
LinearConstraint lin = new LinearConstraint(helper);
|
||||
final LinearExpr e = expr.build();
|
||||
for (int i = 0; i < e.numElements(); ++i) {
|
||||
helper.addConstraintTerm(lin.getIndex(), e.getVariableIndex(i), e.getCoefficient(i));
|
||||
}
|
||||
double offset = e.getOffset();
|
||||
if (lb == Double.NEGATIVE_INFINITY || lb == Double.POSITIVE_INFINITY) {
|
||||
lin.setLowerBound(lb);
|
||||
} else {
|
||||
lin.setLowerBound(lb - offset);
|
||||
}
|
||||
if (ub == Double.NEGATIVE_INFINITY || ub == Double.POSITIVE_INFINITY) {
|
||||
lin.setUpperBound(ub);
|
||||
} else {
|
||||
lin.setUpperBound(ub - offset);
|
||||
}
|
||||
return lin;
|
||||
}
|
||||
|
||||
/** Returns the number of variables in the model. */
|
||||
public int numVariables() {
|
||||
return helper.numVariables();
|
||||
}
|
||||
|
||||
/** Adds {@code expr == value}. */
|
||||
public LinearConstraint addEquality(LinearArgument expr, double value) {
|
||||
return addLinearConstraint(expr, value, value);
|
||||
}
|
||||
|
||||
/** Adds {@code left == right}. */
|
||||
public LinearConstraint addEquality(LinearArgument left, LinearArgument right) {
|
||||
LinearExprBuilder difference = LinearExpr.newBuilder();
|
||||
difference.addTerm(left, 1);
|
||||
difference.addTerm(right, -1);
|
||||
return addLinearConstraint(difference, 0.0, 0.0);
|
||||
}
|
||||
|
||||
/** Adds {@code expr <= value}. */
|
||||
public LinearConstraint addLessOrEqual(LinearArgument expr, double value) {
|
||||
return addLinearConstraint(expr, Double.NEGATIVE_INFINITY, value);
|
||||
}
|
||||
|
||||
/** Adds {@code left <= right}. */
|
||||
public LinearConstraint addLessOrEqual(LinearArgument left, LinearArgument right) {
|
||||
LinearExprBuilder difference = LinearExpr.newBuilder();
|
||||
difference.addTerm(left, 1);
|
||||
difference.addTerm(right, -1);
|
||||
return addLinearConstraint(difference, Double.NEGATIVE_INFINITY, 0.0);
|
||||
}
|
||||
|
||||
/** Adds {@code expr >= value}. */
|
||||
public LinearConstraint addGreaterOrEqual(LinearArgument expr, double value) {
|
||||
return addLinearConstraint(expr, value, Double.POSITIVE_INFINITY);
|
||||
}
|
||||
|
||||
/** Adds {@code left >= right}. */
|
||||
public LinearConstraint addGreaterOrEqual(LinearArgument left, LinearArgument right) {
|
||||
LinearExprBuilder difference = LinearExpr.newBuilder();
|
||||
difference.addTerm(left, 1);
|
||||
difference.addTerm(right, -1);
|
||||
return addLinearConstraint(difference, 0.0, Double.POSITIVE_INFINITY);
|
||||
}
|
||||
|
||||
/** Returns the number of constraints in the model. */
|
||||
public int numConstraints() {
|
||||
return helper.numConstraints();
|
||||
}
|
||||
|
||||
/** Minimize expression */
|
||||
public void minimize(LinearArgument obj) {
|
||||
optimize(obj, false);
|
||||
}
|
||||
|
||||
/** Minimize expression */
|
||||
public void maximize(LinearArgument obj) {
|
||||
optimize(obj, true);
|
||||
}
|
||||
|
||||
/** Sets the objective expression. */
|
||||
public void optimize(LinearArgument obj, boolean maximize) {
|
||||
helper.clearObjective();
|
||||
LinearExpr e = obj.build();
|
||||
LinkedHashMap<Integer, Double> coeffMap = new LinkedHashMap<>();
|
||||
for (int i = 0; i < e.numElements(); ++i) {
|
||||
coeffMap.merge(e.getVariableIndex(i), e.getCoefficient(i), Double::sum);
|
||||
}
|
||||
for (Map.Entry<Integer, Double> entry : coeffMap.entrySet()) {
|
||||
if (entry.getValue() != 0) {
|
||||
helper.setVarObjectiveCoefficient(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
helper.setObjectiveOffset(e.getOffset());
|
||||
helper.setMaximize(maximize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the model as a protocol buffer to 'file'.
|
||||
*
|
||||
* @param file file to write the model to. If the filename ends with 'txt', the model will be
|
||||
* written as a text file, otherwise, the binary format will be used.
|
||||
* @return true if the model was correctly written.
|
||||
*/
|
||||
public Boolean exportToFile(String file) {
|
||||
return helper.writeModelToFile(file);
|
||||
}
|
||||
|
||||
// Getters.
|
||||
/** Returns the model builder helper. */
|
||||
public ModelBuilderHelper getHelper() {
|
||||
return helper;
|
||||
}
|
||||
|
||||
private final ModelBuilderHelper helper;
|
||||
private final Map<Double, Integer> constantMap;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// Copyright 2010-2021 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.modelbuilder;
|
||||
|
||||
/** Model solver class */
|
||||
public final class ModelSolver {
|
||||
static class ModelSolverException extends RuntimeException {
|
||||
public ModelSolverException(String methodName, String msg) {
|
||||
// Call constructor of parent Exception
|
||||
super(methodName + ": " + msg);
|
||||
}
|
||||
}
|
||||
|
||||
public ModelSolver(String solverName) {
|
||||
this.helper = new ModelSolverHelper(solverName);
|
||||
}
|
||||
|
||||
public SolveStatus solve(ModelBuilder model) {
|
||||
helper.solve(model.getHelper());
|
||||
if (!helper.hasResponse()) {
|
||||
return SolveStatus.UNKNOWN_STATUS;
|
||||
}
|
||||
return helper.getStatus();
|
||||
}
|
||||
|
||||
public double objectiveValue() {
|
||||
if (!helper.hasSolution()) {
|
||||
throw new ModelSolverException(
|
||||
"ModelSolver.objectiveValue()", "solve() was not called or no solution was found");
|
||||
}
|
||||
return helper.getObjectiveValue();
|
||||
}
|
||||
|
||||
public double value(Variable var) {
|
||||
if (!helper.hasSolution()) {
|
||||
throw new ModelSolverException(
|
||||
"ModelSolver.value())", "solve() was not called or no solution was found");
|
||||
}
|
||||
return helper.getVariableValue(var.getIndex());
|
||||
}
|
||||
|
||||
public double wallTime() {
|
||||
return helper.getWallTime();
|
||||
}
|
||||
|
||||
ModelSolverHelper helper;
|
||||
}
|
||||
83
ortools/java/com/google/ortools/modelbuilder/Variable.java
Normal file
83
ortools/java/com/google/ortools/modelbuilder/Variable.java
Normal file
@@ -0,0 +1,83 @@
|
||||
// Copyright 2010-2021 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.modelbuilder;
|
||||
|
||||
/** An integer variable. */
|
||||
public class Variable implements LinearArgument {
|
||||
Variable(ModelBuilderHelper helper, double lb, double ub, boolean isIntegral, String name) {
|
||||
this.helper = helper;
|
||||
this.index = helper.addVar();
|
||||
this.helper.setVarName(index, name);
|
||||
this.helper.setVarIntegrality(index, isIntegral);
|
||||
this.helper.setVarLowerBound(index, lb);
|
||||
this.helper.setVarUpperBound(index, ub);
|
||||
}
|
||||
|
||||
Variable(ModelBuilderHelper helper, int index) {
|
||||
this.helper = helper;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
/** Returns the index of the variable in the underlying ModelBuilderHelper. */
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
// LinearArgument interface
|
||||
@Override
|
||||
public LinearExpr build() {
|
||||
return new AffineExpression(index, 1.0, 0.0);
|
||||
}
|
||||
|
||||
/** Returns the lower bound of the variable. */
|
||||
public double getLowerBound() {
|
||||
return helper.getVarLowerBound(index);
|
||||
}
|
||||
|
||||
/** Returns the upper bound of the variable. */
|
||||
public double getUpperBound() {
|
||||
return helper.getVarUpperBound(index);
|
||||
}
|
||||
|
||||
/** Returns whether the variable is integral. */
|
||||
public boolean isIntegral() {
|
||||
return helper.getVarIsIntegral(index);
|
||||
}
|
||||
|
||||
/** Returns the name of the variable given upon creation. */
|
||||
public String getName() {
|
||||
return helper.getVarName(index);
|
||||
}
|
||||
|
||||
/** Returns the objective coefficient of the variable. */
|
||||
public double getObjectiveCoefficient() {
|
||||
return helper.getVarObjectiveCoefficient(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (getName().isEmpty()) {
|
||||
if (getLowerBound() == getUpperBound()) {
|
||||
return String.format("%f", getLowerBound());
|
||||
} else {
|
||||
return String.format("var_%d(%f, %f)", getIndex(), getLowerBound(), getUpperBound());
|
||||
}
|
||||
} else {
|
||||
return String.format("%s(%f, %f)", getName(), getLowerBound(), getUpperBound());
|
||||
}
|
||||
}
|
||||
|
||||
protected final ModelBuilderHelper helper;
|
||||
protected final int index;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// Copyright 2010-2021 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.modelbuilder;
|
||||
|
||||
/** A specialized linear expression: sum(ai * xi) + b. */
|
||||
public final class WeightedSumExpression implements LinearExpr {
|
||||
private final int[] variablesIndices;
|
||||
private final double[] coefficients;
|
||||
private final double offset;
|
||||
|
||||
public WeightedSumExpression(int[] variablesIndices, double[] coefficients, double offset) {
|
||||
this.variablesIndices = variablesIndices;
|
||||
this.coefficients = coefficients;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinearExpr build() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int numElements() {
|
||||
return variablesIndices.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVariableIndex(int index) {
|
||||
if (index < 0 || index >= variablesIndices.length) {
|
||||
throw new IllegalArgumentException("wrong index in LinearExpr.getVariable(): " + index);
|
||||
}
|
||||
return variablesIndices[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCoefficient(int index) {
|
||||
if (index < 0 || index >= variablesIndices.length) {
|
||||
throw new IllegalArgumentException("wrong index in LinearExpr.getCoefficient(): " + index);
|
||||
}
|
||||
return coefficients[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getOffset() {
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
17
ortools/model_builder/java/CMakeLists.txt
Normal file
17
ortools/model_builder/java/CMakeLists.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
set_property(SOURCE modelbuilder.i PROPERTY CPLUSPLUS ON)
|
||||
set_property(SOURCE modelbuilder.i PROPERTY SWIG_MODULE_NAME main)
|
||||
set_property(SOURCE modelbuilder.i PROPERTY COMPILE_DEFINITIONS
|
||||
${OR_TOOLS_COMPILE_DEFINITIONS} ABSL_MUST_USE_RESULT)
|
||||
set_property(SOURCE modelbuilder.i PROPERTY COMPILE_OPTIONS
|
||||
-package ${JAVA_PACKAGE}.modelbuilder)
|
||||
swig_add_library(jnimodel_builder
|
||||
TYPE OBJECT
|
||||
LANGUAGE java
|
||||
OUTPUT_DIR ${JAVA_PROJECT_DIR}/${JAVA_SRC_PATH}/modelbuilder
|
||||
SOURCES modelbuilder.i)
|
||||
|
||||
target_include_directories(jnimodel_builder PRIVATE ${JNI_INCLUDE_DIRS})
|
||||
set_target_properties(jnimodel_builder PROPERTIES
|
||||
SWIG_USE_TARGET_INCLUDE_DIRECTORIES ON
|
||||
POSITION_INDEPENDENT_CODE ON)
|
||||
target_link_libraries(jnimodel_builder PRIVATE ortools::ortools)
|
||||
157
ortools/model_builder/java/modelbuilder.i
Normal file
157
ortools/model_builder/java/modelbuilder.i
Normal file
@@ -0,0 +1,157 @@
|
||||
// Copyright 2010-2021 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.
|
||||
|
||||
%include "stdint.i"
|
||||
|
||||
%include "ortools/base/base.i"
|
||||
%include "enums.swg"
|
||||
|
||||
%{
|
||||
#include "ortools/model_builder/wrappers/model_builder_helper.h"
|
||||
%}
|
||||
|
||||
%module operations_research_modelbuilder
|
||||
|
||||
// This typemap is inspired by the constraints_solver java typemaps.
|
||||
// The only difference is that the argument is not a basic type, and needs
|
||||
// processing to be passed to the std::function.
|
||||
//
|
||||
// TODO(user): cleanup java/functions.i and move the code there.
|
||||
%{
|
||||
#include <memory> // std::make_shared<GlobalRefGuard>
|
||||
%}
|
||||
|
||||
%typemap(in) std::function<void(const std::string&)> %{
|
||||
// $input will be deleted once this function return.
|
||||
// So we create a JNI global reference to keep it alive.
|
||||
jobject $input_object = jenv->NewGlobalRef($input);
|
||||
// and we wrap it in a GlobalRefGuard object which will call the
|
||||
// JNI global reference deleter to avoid leak at destruction.
|
||||
JavaVM* jvm;
|
||||
jenv->GetJavaVM(&jvm);
|
||||
auto $input_guard = std::make_shared<GlobalRefGuard>(jvm, $input_object);
|
||||
|
||||
jclass $input_object_class = jenv->GetObjectClass($input);
|
||||
if (nullptr == $input_object_class) return $null;
|
||||
jmethodID $input_method_id = jenv->GetMethodID(
|
||||
$input_object_class, "accept", "(Ljava/lang/Object;)V");
|
||||
assert($input_method_id != nullptr);
|
||||
|
||||
// When the lambda will be destroyed, input_guard's destructor will be called.
|
||||
$1 = [jvm, $input_object, $input_method_id, $input_guard](
|
||||
const std::string& message) -> void {
|
||||
JNIEnv *jenv = NULL;
|
||||
JavaVMAttachArgs args;
|
||||
args.version = JNI_VERSION_1_2;
|
||||
args.name = NULL;
|
||||
args.group = NULL;
|
||||
jvm->AttachCurrentThread((void**)&jenv, &args);
|
||||
jenv->CallVoidMethod($input_object, $input_method_id, (jenv)->NewStringUTF(message.c_str()));
|
||||
jvm->DetachCurrentThread();
|
||||
};
|
||||
%}
|
||||
%typemap(jni) std::function<void(const std::string&)> "jobject" // Type used in the JNI C.
|
||||
%typemap(jtype) std::function<void(const std::string&)> "java.util.function.Consumer<String>" // Type used in the JNI.java.
|
||||
%typemap(jstype) std::function<void(const std::string&)> "java.util.function.Consumer<String>" // Type used in the Proxy class.
|
||||
%typemap(javain) std::function<void(const std::string&)> "$javainput" // passing the Callback to JNI java class.
|
||||
|
||||
%ignoreall
|
||||
|
||||
%unignore operations_research;
|
||||
|
||||
// Wrap the ModelBuilderHelper class.
|
||||
%unignore operations_research::ModelBuilderHelper;
|
||||
%unignore operations_research::ModelBuilderHelper::ModelBuilderHelper;
|
||||
%unignore operations_research::ModelBuilderHelper::~ModelBuilderHelper;
|
||||
|
||||
// Var API.
|
||||
%rename (addVar) operations_research::ModelBuilderHelper::AddVar;
|
||||
%rename (getVarIsIntegral) operations_research::ModelBuilderHelper::VarIsIntegral;
|
||||
%rename (getVarLowerBound) operations_research::ModelBuilderHelper::VarLowerBound;
|
||||
%rename (getVarName) operations_research::ModelBuilderHelper::VarName;
|
||||
%rename (getVarObjectiveCoefficient) operations_research::ModelBuilderHelper::VarObjectiveCoefficient;
|
||||
%rename (getVarUpperBound) operations_research::ModelBuilderHelper::VarUpperBound;
|
||||
%rename (numVariables) operations_research::ModelBuilderHelper::num_variables;
|
||||
%rename (setVarIntegrality) operations_research::ModelBuilderHelper::SetVarIntegrality;
|
||||
%rename (setVarLowerBound) operations_research::ModelBuilderHelper::SetVarLowerBound;
|
||||
%rename (setVarName) operations_research::ModelBuilderHelper::SetVarName;
|
||||
%rename (setVarObjectiveCoefficient) operations_research::ModelBuilderHelper::SetVarObjectiveCoefficient;
|
||||
%rename (setVarUpperBound) operations_research::ModelBuilderHelper::SetVarUpperBound;
|
||||
|
||||
// Constraint API.
|
||||
%rename (addConstraintTerm) operations_research::ModelBuilderHelper::AddConstraintTerm;
|
||||
%rename (addLinearConstraint) operations_research::ModelBuilderHelper::AddLinearConstraint;
|
||||
%rename (getConstraintCoefficients) operations_research::ModelBuilderHelper::ConstraintCoefficients;
|
||||
%rename (getConstraintLowerBound) operations_research::ModelBuilderHelper::ConstraintLowerBound;
|
||||
%rename (getConstraintName) operations_research::ModelBuilderHelper::ConstraintName;
|
||||
%rename (getConstraintUpperBound) operations_research::ModelBuilderHelper::ConstraintUpperBound;
|
||||
%rename (getConstraintVarIndices) operations_research::ModelBuilderHelper::ConstraintVarIndices;
|
||||
%rename (numConstraints) operations_research::ModelBuilderHelper::num_constraints;
|
||||
%rename (setConstraintLowerBound) operations_research::ModelBuilderHelper::SetConstraintLowerBound;
|
||||
%rename (setConstraintName) operations_research::ModelBuilderHelper::SetConstraintName;
|
||||
%rename (setConstraintUpperBound) operations_research::ModelBuilderHelper::SetConstraintUpperBound;
|
||||
|
||||
// Objective API.
|
||||
%rename (clearObjective) operations_research::ModelBuilderHelper::ClearObjective;
|
||||
%rename (getMaximize) operations_research::ModelBuilderHelper::maximize;
|
||||
%rename (setMaximize) operations_research::ModelBuilderHelper::SetMaximize;
|
||||
%rename (getObjectiveOffset) operations_research::ModelBuilderHelper::ObjectiveOffset;
|
||||
%rename (setObjectiveOffset) operations_research::ModelBuilderHelper::SetObjectiveOffset;
|
||||
|
||||
// Model API.
|
||||
%rename (getName) operations_research::ModelBuilderHelper::name;
|
||||
%rename (setName) operations_research::ModelBuilderHelper::SetName;
|
||||
%rename (writeModelToFile) operations_research::ModelBuilderHelper::WriteModelToFile;
|
||||
%rename (importFromMpsString) operations_research::ModelBuilderHelper::ImportFromMpsString;
|
||||
%rename (importFromMpsFile) operations_research::ModelBuilderHelper::ImportFromMpsFile;
|
||||
%rename (importFromLpString) operations_research::ModelBuilderHelper::ImportFromLpString;
|
||||
%rename (importFromLpFile) operations_research::ModelBuilderHelper::ImportFromLpFile;
|
||||
|
||||
%unignore operations_research::ModelSolverHelper;
|
||||
%unignore operations_research::ModelSolverHelper::ModelSolverHelper(const std::string&);
|
||||
%rename (solverIsSupported) operations_research::ModelSolverHelper::solverIsSupported;
|
||||
%rename (solve) operations_research::ModelSolverHelper::Solve;
|
||||
%rename (hasResponse) operations_research::ModelSolverHelper::has_response;
|
||||
%rename (hasSolution) operations_research::ModelSolverHelper::has_solution;
|
||||
%rename (getStatus) operations_research::ModelSolverHelper::status;
|
||||
%rename (getObjectiveValue) operations_research::ModelSolverHelper::objective_value;
|
||||
%rename (getBestObjectiveBound) operations_research::ModelSolverHelper::best_objective_bound;
|
||||
%rename (getVariableValue) operations_research::ModelSolverHelper::variable_value;
|
||||
%rename (getReducedCost) operations_research::ModelSolverHelper::reduced_cost;
|
||||
%rename (getDualValue) operations_research::ModelSolverHelper::dual_value;
|
||||
%rename (getStatusString) operations_research::ModelSolverHelper::status_string;
|
||||
%rename (getWallTime) operations_research::ModelSolverHelper::wall_time;
|
||||
%rename (enableOutput) operations_research::ModelSolverHelper::EnableOutput;
|
||||
|
||||
%unignore operations_research::SolveStatus;
|
||||
%unignore operations_research::OPTIMAL;
|
||||
%unignore operations_research::FEASIBLE;
|
||||
%unignore operations_research::INFEASIBLE;
|
||||
%unignore operations_research::UNBOUNDED;
|
||||
%unignore operations_research::ABNORMAL;
|
||||
%unignore operations_research::NOT_SOLVED;
|
||||
%unignore operations_research::MODEL_IS_VALID;
|
||||
%unignore operations_research::CANCELLED_BY_USER;
|
||||
%unignore operations_research::UNKNOWN_STATUS;
|
||||
%unignore operations_research::MODEL_INVALID;
|
||||
%unignore operations_research::INVALID_SOLVER_PARAMETERS;
|
||||
%unignore operations_research::SOLVER_TYPE_UNAVAILABLE;
|
||||
%unignore operations_research::INCOMPATIBLE_OPTIONS;
|
||||
|
||||
// For enums
|
||||
%javaconst(1);
|
||||
|
||||
%include "ortools/model_builder/wrappers/model_builder_helper.h"
|
||||
|
||||
%unignoreall
|
||||
|
||||
85
ortools/model_builder/samples/SimpleLpProgramMb.java
Normal file
85
ortools/model_builder/samples/SimpleLpProgramMb.java
Normal file
@@ -0,0 +1,85 @@
|
||||
// Copyright 2010-2021 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.
|
||||
|
||||
// Minimal example to call the GLOP solver.
|
||||
// [START program]
|
||||
package com.google.ortools.modelbuilder.samples;
|
||||
|
||||
// [START import]
|
||||
import com.google.ortools.Loader;
|
||||
import com.google.ortools.modelbuilder.LinearExpr;
|
||||
import com.google.ortools.modelbuilder.ModelBuilder;
|
||||
import com.google.ortools.modelbuilder.ModelSolver;
|
||||
import com.google.ortools.modelbuilder.SolveStatus;
|
||||
import com.google.ortools.modelbuilder.Variable;
|
||||
// [END import]
|
||||
|
||||
/** Minimal Linear Programming example to showcase calling the solver. */
|
||||
public final class SimpleLpProgramMb {
|
||||
public static void main(String[] args) {
|
||||
Loader.loadNativeLibraries();
|
||||
// [START model]
|
||||
// Create the linear model.
|
||||
ModelBuilder model = new ModelBuilder();
|
||||
// [END model]
|
||||
|
||||
// [START variables]
|
||||
double infinity = java.lang.Double.POSITIVE_INFINITY;
|
||||
// Create the variables x and y.
|
||||
Variable x = model.newNumVar(0.0, infinity, "x");
|
||||
Variable y = model.newNumVar(0.0, infinity, "y");
|
||||
|
||||
System.out.println("Number of variables = " + model.numVariables());
|
||||
// [END variables]
|
||||
|
||||
// [START constraints]
|
||||
// x + 7 * y <= 17.5.
|
||||
model.addLessOrEqual(LinearExpr.newBuilder().add(x).addTerm(y, 7), 17.5).withName("c0");
|
||||
|
||||
// x <= 3.5.
|
||||
model.addLessOrEqual(x, 3.5).withName("c1");
|
||||
|
||||
System.out.println("Number of constraints = " + model.numConstraints());
|
||||
// [END constraints]
|
||||
|
||||
// [START objective]
|
||||
// Maximize x + 10 * y.
|
||||
model.maximize(LinearExpr.newBuilder().add(x).addTerm(y, 10.0));
|
||||
// [END objective]
|
||||
|
||||
// [START solve]
|
||||
// Solve with the GLOP LP solver.
|
||||
ModelSolver solver = new ModelSolver("glop");
|
||||
final SolveStatus status = solver.solve(model);
|
||||
// [END solve]
|
||||
|
||||
// [START print_solution]
|
||||
if (status == SolveStatus.OPTIMAL) {
|
||||
System.out.println("Solution:");
|
||||
System.out.println("Objective value = " + solver.objectiveValue());
|
||||
System.out.println("x = " + solver.value(x));
|
||||
System.out.println("y = " + solver.value(y));
|
||||
} else {
|
||||
System.err.println("The problem does not have an optimal solution!");
|
||||
}
|
||||
// [END print_solution]
|
||||
|
||||
// [START advanced]
|
||||
System.out.println("\nAdvanced usage:");
|
||||
System.out.println("Problem solved in " + solver.wallTime() + " milliseconds");
|
||||
// [END advanced]
|
||||
}
|
||||
|
||||
private SimpleLpProgramMb() {}
|
||||
}
|
||||
// [END program]
|
||||
83
ortools/model_builder/samples/SimpleMipProgramMb.java
Normal file
83
ortools/model_builder/samples/SimpleMipProgramMb.java
Normal file
@@ -0,0 +1,83 @@
|
||||
// Copyright 2010-2021 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.
|
||||
|
||||
// Minimal example to call the MIP solver.
|
||||
// [START program]
|
||||
package com.google.ortools.modelbuilder.samples;
|
||||
// [START import]
|
||||
import com.google.ortools.Loader;
|
||||
import com.google.ortools.modelbuilder.LinearExpr;
|
||||
import com.google.ortools.modelbuilder.ModelBuilder;
|
||||
import com.google.ortools.modelbuilder.ModelSolver;
|
||||
import com.google.ortools.modelbuilder.SolveStatus;
|
||||
import com.google.ortools.modelbuilder.Variable;
|
||||
// [END import]
|
||||
|
||||
/** Minimal Mixed Integer Programming example to showcase calling the solver. */
|
||||
public final class SimpleMipProgramMb {
|
||||
public static void main(String[] args) {
|
||||
Loader.loadNativeLibraries();
|
||||
// [START model]
|
||||
// Create the linear model.
|
||||
ModelBuilder model = new ModelBuilder();
|
||||
// [END model]
|
||||
|
||||
// [START variables]
|
||||
double infinity = java.lang.Double.POSITIVE_INFINITY;
|
||||
// x and y are integer non-negative variables.
|
||||
Variable x = model.newIntVar(0.0, infinity, "x");
|
||||
Variable y = model.newIntVar(0.0, infinity, "y");
|
||||
|
||||
System.out.println("Number of variables = " + model.numVariables());
|
||||
// [END variables]
|
||||
|
||||
// [START constraints]
|
||||
// x + 7 * y <= 17.5.
|
||||
model.addLessOrEqual(LinearExpr.newBuilder().add(x).addTerm(y, 7), 17.5).withName("c0");
|
||||
|
||||
// x <= 3.5.
|
||||
model.addLessOrEqual(x, 3.5).withName("c1");
|
||||
|
||||
System.out.println("Number of constraints = " + model.numConstraints());
|
||||
// [END constraints]
|
||||
|
||||
// [START objective]
|
||||
// Maximize x + 10 * y.
|
||||
model.maximize(LinearExpr.newBuilder().add(x).addTerm(y, 10.0));
|
||||
// [END objective]
|
||||
|
||||
// [START solve]
|
||||
// Solve with the SCIP MIP solver.
|
||||
ModelSolver solver = new ModelSolver("scip");
|
||||
final SolveStatus status = solver.solve(model);
|
||||
// [END solve]
|
||||
|
||||
// [START print_solution]
|
||||
if (status == SolveStatus.OPTIMAL) {
|
||||
System.out.println("Solution:");
|
||||
System.out.println("Objective value = " + solver.objectiveValue());
|
||||
System.out.println("x = " + solver.value(x));
|
||||
System.out.println("y = " + solver.value(y));
|
||||
} else {
|
||||
System.err.println("The problem does not have an optimal solution!");
|
||||
}
|
||||
// [END print_solution]
|
||||
|
||||
// [START advanced]
|
||||
System.out.println("\nAdvanced usage:");
|
||||
System.out.println("Problem solved in " + solver.wallTime() + " milliseconds");
|
||||
}
|
||||
|
||||
private SimpleMipProgramMb() {}
|
||||
}
|
||||
// [END program]
|
||||
Reference in New Issue
Block a user