more work on ModelBuilder java
This commit is contained in:
@@ -275,6 +275,11 @@ test_java_linear_solver_samples: \
|
||||
rjava_SimpleMipProgram \
|
||||
rjava_StiglerDiet
|
||||
|
||||
.PHONY: test_java_model_builder_samples # Build and Run all Java MB Samples (located in ortools/model_builder/samples)
|
||||
test_java_model_builder_samples: \
|
||||
rjava_SimpleLpProgramMb \
|
||||
rjava_SimpleMipProgramMb
|
||||
|
||||
.PHONY: test_java_sat_samples # Build and Run all Java SAT Samples (located in ortools/sat/samples)
|
||||
test_java_sat_samples: \
|
||||
rjava_AssignmentSat \
|
||||
@@ -305,6 +310,7 @@ check_java: \
|
||||
test_java_constraint_solver_samples \
|
||||
test_java_graph_samples \
|
||||
test_java_linear_solver_samples \
|
||||
test_java_model_builder_samples \
|
||||
test_java_sat_samples \
|
||||
\
|
||||
rjava_LinearProgramming \
|
||||
|
||||
@@ -35,36 +35,36 @@ public class LinearConstraint {
|
||||
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 double getUpperBound() {
|
||||
return helper.getConstraintUpperBound(index);
|
||||
}
|
||||
|
||||
/** Returns the upper bound of the variable. */
|
||||
public void setUpperBound(double ub) {
|
||||
helper.setConstraintUpperBound(index, ub);
|
||||
}
|
||||
|
||||
/** Returns the name of the variable given upon creation. */
|
||||
public String getName() {
|
||||
return helper.getConstraintName(index);
|
||||
}
|
||||
|
||||
// Sets the name of the variable. */
|
||||
public void setName(String name) {
|
||||
helper.setConstraintName(index, name);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
@@ -184,6 +184,18 @@ public final class ModelBuilder {
|
||||
helper.setMaximize(maximize);
|
||||
}
|
||||
|
||||
// Model getters, import, export.
|
||||
|
||||
/** Returns the name of the model. */
|
||||
public String getName() {
|
||||
return helper.getName();
|
||||
}
|
||||
|
||||
/** Sets the name of the model. */
|
||||
public void setName(String name) {
|
||||
helper.setName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the model as a protocol buffer to 'file'.
|
||||
*
|
||||
@@ -191,10 +203,34 @@ public final class ModelBuilder {
|
||||
* 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) {
|
||||
public boolean exportToFile(String file) {
|
||||
return helper.writeModelToFile(file);
|
||||
}
|
||||
|
||||
public String exportToMpsString(boolean obfuscate) {
|
||||
return helper.exportToMpsString(obfuscate);
|
||||
}
|
||||
|
||||
public String exportToLpString(boolean obfuscate) {
|
||||
return helper.exportToLpString(obfuscate);
|
||||
}
|
||||
|
||||
public boolean importFromMpsString(String mpsString) {
|
||||
return helper.importFromMpsString(mpsString);
|
||||
}
|
||||
|
||||
public boolean importFromMpsFile(String mpsFile) {
|
||||
return helper.importFromMpsString(mpsFile);
|
||||
}
|
||||
|
||||
public boolean importFromLpString(String lpString) {
|
||||
return helper.importFromLpString(lpString);
|
||||
}
|
||||
|
||||
public boolean importFromLpFile(String lpFile) {
|
||||
return helper.importFromMpsString(lpFile);
|
||||
}
|
||||
|
||||
// Getters.
|
||||
/** Returns the model builder helper. */
|
||||
public ModelBuilderHelper getHelper() {
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
package com.google.ortools.modelbuilder;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/** Model solver class */
|
||||
public final class ModelSolver {
|
||||
static class ModelSolverException extends RuntimeException {
|
||||
@@ -22,11 +24,15 @@ public final class ModelSolver {
|
||||
}
|
||||
}
|
||||
|
||||
/** Creates the solver with the supplied solver backend. */
|
||||
public ModelSolver(String solverName) {
|
||||
this.helper = new ModelSolverHelper(solverName);
|
||||
this.logCallback = null;
|
||||
}
|
||||
|
||||
/** Solves given model, and returns the status of the response. */
|
||||
public SolveStatus solve(ModelBuilder model) {
|
||||
helper.setLogCallback(logCallback);
|
||||
helper.solve(model.getHelper());
|
||||
if (!helper.hasResponse()) {
|
||||
return SolveStatus.UNKNOWN_STATUS;
|
||||
@@ -34,25 +40,100 @@ public final class ModelSolver {
|
||||
return helper.getStatus();
|
||||
}
|
||||
|
||||
public double objectiveValue() {
|
||||
/** Enables or disables the underlying solver output. */
|
||||
public void enableOutput(boolean enable) {
|
||||
helper.enableOutput(enable);
|
||||
}
|
||||
|
||||
/** Sets the time limit for the solve in seconds. */
|
||||
public void setTimeLimitInSeconds(double limit) {
|
||||
helper.setTimeLimitInSeconds(limit);
|
||||
}
|
||||
|
||||
/** Sets solver specific parameters as string. */
|
||||
public void setSolverSpecificParameters(String parameters) {
|
||||
helper.setSolverSpecificParameters(parameters);
|
||||
}
|
||||
|
||||
/** Returns whether solver specified during the ctor was found and correctly installed. */
|
||||
public boolean solverIsSupported() {
|
||||
return helper.solverIsSupported();
|
||||
}
|
||||
|
||||
/** Tries to interrupt the solve. Returns true if the feature is supported. */
|
||||
public boolean interruptSolve() {
|
||||
return helper.interruptSolve();
|
||||
}
|
||||
|
||||
/** Returns true if solve() was called, and a response was returned. */
|
||||
public boolean hasResponse() {
|
||||
return helper.hasResponse();
|
||||
}
|
||||
|
||||
/** Returns true if solve() was called, and a solution was returned. */
|
||||
public boolean hasSolution() {
|
||||
return helper.hasSolution();
|
||||
}
|
||||
|
||||
/** Checks that the solver has found a solution, and returns the objective value. */
|
||||
public double getObjectiveValue() {
|
||||
if (!helper.hasSolution()) {
|
||||
throw new ModelSolverException(
|
||||
"ModelSolver.objectiveValue()", "solve() was not called or no solution was found");
|
||||
"ModelSolver.getObjectiveValue()", "solve() was not called or no solution was found");
|
||||
}
|
||||
return helper.getObjectiveValue();
|
||||
}
|
||||
|
||||
public double value(Variable var) {
|
||||
/** Checks that the solver has found a solution, and returns the objective value. */
|
||||
public double getBestObjectiveBound() {
|
||||
if (!helper.hasSolution()) {
|
||||
throw new ModelSolverException(
|
||||
"ModelSolver.value())", "solve() was not called or no solution was found");
|
||||
"ModelSolver.getBestObjectiveBound()", "solve() was not called or no solution was found");
|
||||
}
|
||||
return helper.getBestObjectiveBound();
|
||||
}
|
||||
|
||||
/** Checks that the solver has found a solution, and value of the given variable. */
|
||||
public double getValue(Variable var) {
|
||||
if (!helper.hasSolution()) {
|
||||
throw new ModelSolverException(
|
||||
"ModelSolver.getValue())", "solve() was not called or no solution was found");
|
||||
}
|
||||
return helper.getVariableValue(var.getIndex());
|
||||
}
|
||||
/** Checks that the solver has found a solution, and reduced cost of the given variable. */
|
||||
public double getReducedCost(Variable var) {
|
||||
if (!helper.hasSolution()) {
|
||||
throw new ModelSolverException(
|
||||
"ModelSolver.getReducedCost())", "solve() was not called or no solution was found");
|
||||
}
|
||||
return helper.getReducedCost(var.getIndex());
|
||||
}
|
||||
|
||||
public double wallTime() {
|
||||
/** Checks that the solver has found a solution, and dual value of the given constraint. */
|
||||
public double getDualValue(LinearConstraint ct) {
|
||||
if (!helper.hasSolution()) {
|
||||
throw new ModelSolverException(
|
||||
"ModelSolver.getDualValue())", "solve() was not called or no solution was found");
|
||||
}
|
||||
return helper.getDualValue(ct.getIndex());
|
||||
}
|
||||
|
||||
/** Sets the log callback for the solver. */
|
||||
public void setLogCallback(Consumer<String> cb) {
|
||||
this.logCallback = cb;
|
||||
}
|
||||
|
||||
/** Returns the elapsed time since the creation of the solver. */
|
||||
public double getWallTime() {
|
||||
return helper.getWallTime();
|
||||
}
|
||||
|
||||
ModelSolverHelper helper;
|
||||
/** Returns the user time since the creation of the solver. */
|
||||
public double getUserTime() {
|
||||
return helper.getUserTime();
|
||||
}
|
||||
|
||||
private final ModelSolverHelper helper;
|
||||
private Consumer<String> logCallback;
|
||||
}
|
||||
|
||||
@@ -45,14 +45,39 @@ public class Variable implements LinearArgument {
|
||||
return helper.getVarLowerBound(index);
|
||||
}
|
||||
|
||||
/** Sets the lower bound of the variable. */
|
||||
public void setLowerBound(double lowerBound) {
|
||||
helper.setVarLowerBound(index, lowerBound);
|
||||
}
|
||||
|
||||
/** Returns the upper bound of the variable. */
|
||||
public double getUpperBound() {
|
||||
return helper.getVarUpperBound(index);
|
||||
}
|
||||
|
||||
/** Sets the upper bound of the variable. */
|
||||
public void setUpperBound(double upperBound) {
|
||||
helper.setVarUpperBound(index, upperBound);
|
||||
}
|
||||
|
||||
/** Returns whether the variable is integral. */
|
||||
public boolean isIntegral() {
|
||||
return helper.getVarIsIntegral(index);
|
||||
public boolean getVarIntegrality() {
|
||||
return helper.getVarIntegrality(index);
|
||||
}
|
||||
|
||||
/** Sets the integrality of the variable. */
|
||||
public void setVarIntegrality(boolean isIntegral) {
|
||||
helper.setVarIntegrality(index, isIntegral);
|
||||
}
|
||||
|
||||
/** Returns the objective coefficient of the variable. */
|
||||
public double getObjectiveCoefficient() {
|
||||
return helper.getVarObjectiveCoefficient(index);
|
||||
}
|
||||
|
||||
/** Sets the objective coefficient of the variable in the objective. */
|
||||
public void setObjectiveCoefficient(double objectiveCoefficient) {
|
||||
helper.setVarObjectiveCoefficient(index, objectiveCoefficient);
|
||||
}
|
||||
|
||||
/** Returns the name of the variable given upon creation. */
|
||||
@@ -60,9 +85,8 @@ public class Variable implements LinearArgument {
|
||||
return helper.getVarName(index);
|
||||
}
|
||||
|
||||
/** Returns the objective coefficient of the variable. */
|
||||
public double getObjectiveCoefficient() {
|
||||
return helper.getVarObjectiveCoefficient(index);
|
||||
public void setName(String name) {
|
||||
helper.setVarName(index, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -29,6 +29,27 @@
|
||||
// TODO(user): cleanup java/functions.i and move the code there.
|
||||
%{
|
||||
#include <memory> // std::make_shared<GlobalRefGuard>
|
||||
|
||||
/* Global JNI reference deleter. Instantiate it via std::make_shared<> */
|
||||
class GlobalRefGuard {
|
||||
JavaVM *jvm_;
|
||||
jobject jref_;
|
||||
// non-copyable
|
||||
GlobalRefGuard(const GlobalRefGuard &) = delete;
|
||||
GlobalRefGuard &operator=(const GlobalRefGuard &) = delete;
|
||||
public:
|
||||
GlobalRefGuard(JavaVM *jvm, jobject jref): jvm_(jvm), jref_(jref) {}
|
||||
~GlobalRefGuard() {
|
||||
JNIEnv *jenv = NULL;
|
||||
JavaVMAttachArgs args;
|
||||
args.version = JNI_VERSION_1_2;
|
||||
args.name = NULL;
|
||||
args.group = NULL;
|
||||
jvm_->AttachCurrentThread((void**)&jenv, &args);
|
||||
jenv->DeleteGlobalRef(jref_);
|
||||
jvm_->DetachCurrentThread();
|
||||
}
|
||||
};
|
||||
%}
|
||||
|
||||
%typemap(in) std::function<void(const std::string&)> %{
|
||||
@@ -65,6 +86,20 @@
|
||||
%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.
|
||||
|
||||
%extend operations_research::ModelBuilderHelper {
|
||||
std::string exportToMpsString(bool obfuscate) {
|
||||
operations_research::MPModelExportOptions options;
|
||||
options.obfuscate = obfuscate;
|
||||
return $self->ExportToMpsString(options);
|
||||
}
|
||||
|
||||
std::string exportToLpString(bool obfuscate) {
|
||||
operations_research::MPModelExportOptions options;
|
||||
options.obfuscate = obfuscate;
|
||||
return $self->ExportToLpString(options);
|
||||
}
|
||||
} // Extend operations_research::ModelBuilderHelper
|
||||
|
||||
%ignoreall
|
||||
|
||||
%unignore operations_research;
|
||||
@@ -76,7 +111,7 @@
|
||||
|
||||
// Var API.
|
||||
%rename (addVar) operations_research::ModelBuilderHelper::AddVar;
|
||||
%rename (getVarIsIntegral) operations_research::ModelBuilderHelper::VarIsIntegral;
|
||||
%rename (getVarIntegrality) operations_research::ModelBuilderHelper::VarIsIntegral;
|
||||
%rename (getVarLowerBound) operations_research::ModelBuilderHelper::VarLowerBound;
|
||||
%rename (getVarName) operations_research::ModelBuilderHelper::VarName;
|
||||
%rename (getVarObjectiveCoefficient) operations_research::ModelBuilderHelper::VarObjectiveCoefficient;
|
||||
@@ -116,11 +151,14 @@
|
||||
%rename (importFromMpsFile) operations_research::ModelBuilderHelper::ImportFromMpsFile;
|
||||
%rename (importFromLpString) operations_research::ModelBuilderHelper::ImportFromLpString;
|
||||
%rename (importFromLpFile) operations_research::ModelBuilderHelper::ImportFromLpFile;
|
||||
%unignore operations_research::ModelBuilderHelper::exportToMpsString;
|
||||
%unignore operations_research::ModelBuilderHelper::exportToLpString;
|
||||
|
||||
%unignore operations_research::ModelSolverHelper;
|
||||
%unignore operations_research::ModelSolverHelper::ModelSolverHelper(const std::string&);
|
||||
%rename (solverIsSupported) operations_research::ModelSolverHelper::solverIsSupported;
|
||||
%rename (solverIsSupported) operations_research::ModelSolverHelper::SolverIsSupported;
|
||||
%rename (solve) operations_research::ModelSolverHelper::Solve;
|
||||
%rename (interruptSolve) operations_research::ModelSolverHelper::InterruptSolve;
|
||||
%rename (hasResponse) operations_research::ModelSolverHelper::has_response;
|
||||
%rename (hasSolution) operations_research::ModelSolverHelper::has_solution;
|
||||
%rename (getStatus) operations_research::ModelSolverHelper::status;
|
||||
@@ -131,7 +169,11 @@
|
||||
%rename (getDualValue) operations_research::ModelSolverHelper::dual_value;
|
||||
%rename (getStatusString) operations_research::ModelSolverHelper::status_string;
|
||||
%rename (getWallTime) operations_research::ModelSolverHelper::wall_time;
|
||||
%rename (getUserTime) operations_research::ModelSolverHelper::user_time;
|
||||
%rename (enableOutput) operations_research::ModelSolverHelper::EnableOutput;
|
||||
%rename (setLogCallback) operations_research::ModelSolverHelper::SetLogCallback;
|
||||
%rename (setTimeLimitInSeconds) operations_research::ModelSolverHelper::SetTimeLimitInSeconds;
|
||||
%rename (setSolverSpecificParameters) operations_research::ModelSolverHelper::SetSolverSpecificParameters;
|
||||
|
||||
%unignore operations_research::SolveStatus;
|
||||
%unignore operations_research::OPTIMAL;
|
||||
|
||||
@@ -66,9 +66,9 @@ public final class SimpleLpProgramMb {
|
||||
// [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));
|
||||
System.out.println("Objective value = " + solver.getObjectiveValue());
|
||||
System.out.println("x = " + solver.getValue(x));
|
||||
System.out.println("y = " + solver.getValue(y));
|
||||
} else {
|
||||
System.err.println("The problem does not have an optimal solution!");
|
||||
}
|
||||
@@ -76,7 +76,7 @@ public final class SimpleLpProgramMb {
|
||||
|
||||
// [START advanced]
|
||||
System.out.println("\nAdvanced usage:");
|
||||
System.out.println("Problem solved in " + solver.wallTime() + " milliseconds");
|
||||
System.out.println("Problem solved in " + solver.getWallTime() + " seconds");
|
||||
// [END advanced]
|
||||
}
|
||||
|
||||
|
||||
@@ -65,9 +65,9 @@ public final class SimpleMipProgramMb {
|
||||
// [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));
|
||||
System.out.println("Objective value = " + solver.getObjectiveValue());
|
||||
System.out.println("x = " + solver.getValue(x));
|
||||
System.out.println("y = " + solver.getValue(y));
|
||||
} else {
|
||||
System.err.println("The problem does not have an optimal solution!");
|
||||
}
|
||||
@@ -75,7 +75,8 @@ public final class SimpleMipProgramMb {
|
||||
|
||||
// [START advanced]
|
||||
System.out.println("\nAdvanced usage:");
|
||||
System.out.println("Problem solved in " + solver.wallTime() + " milliseconds");
|
||||
System.out.println("Problem solved in " + solver.getWallTime() + " seconds");
|
||||
// [END advanced]
|
||||
}
|
||||
|
||||
private SimpleMipProgramMb() {}
|
||||
|
||||
Reference in New Issue
Block a user