polish new linear_solver non C++ API

This commit is contained in:
Laurent Perron
2019-07-01 14:13:15 +02:00
parent d4c088a367
commit e6ff7153aa
4 changed files with 92 additions and 11 deletions

View File

@@ -263,6 +263,11 @@ $(GEN_DIR)/com/google/ortools/constraintsolver/RoutingEnums.java: \
| $(GEN_DIR)/com/google/ortools/constraintsolver
$(PROTOC) --proto_path=$(SRC_DIR) --java_out=$(GEN_PATH) $(SRC_DIR)$Sortools$Sconstraint_solver$Srouting_enums.proto
$(GEN_DIR)/com/google/ortools/linearsolver/MPModelProto.java: \
$(SRC_DIR)/ortools/linear_solver/linear_solver.proto \
| $(GEN_DIR)/com/google/ortools/linearsolver
$(PROTOC) --proto_path=$(SRC_DIR) --java_out=$(GEN_PATH) $(SRC_DIR)$Sortools$Slinear_solver$Slinear_solver.proto
$(GEN_DIR)/com/google/ortools/sat/CpModel.java: \
$(SRC_DIR)/ortools/sat/cp_model.proto \
| $(GEN_DIR)/com/google/ortools/sat
@@ -285,6 +290,7 @@ $(JAVA_OR_TOOLS_LIBS): \
$(GEN_DIR)/com/google/ortools/constraintsolver/SearchLimitProtobuf.java \
$(GEN_DIR)/com/google/ortools/constraintsolver/RoutingParameters.java \
$(GEN_DIR)/com/google/ortools/constraintsolver/RoutingEnums.java \
$(GEN_DIR)/com/google/ortools/linearsolver/MPModelProto.java \
$(GEN_DIR)/com/google/ortools/sat/SatParameters.java \
$(GEN_DIR)/com/google/ortools/util/OptionalBoolean.java \
$(GEN_DIR)/com/google/ortools/sat/CpModel.java | \

View File

@@ -30,12 +30,12 @@
%include "ortools/base/base.i"
%include "ortools/util/java/proto.i"
// We prefer our in-house vector wrapper to std_vector.i, because it
// converts to and from native java arrays.
%import "ortools/util/java/vector.i"
%include "ortools/util/java/proto.i"
// We need to forward-declare the proto here, so that the PROTO_* macros
// involving them work correctly. The order matters very much: this declaration
// needs to be before the %{ #include ".../linear_solver.h" %}.
@@ -50,17 +50,79 @@ class MPSolutionResponse;
#include "ortools/linear_solver/model_exporter.h"
%}
%typemap(javaimports) SWIGTYPE %{
import java.lang.reflect.*;
%}
// Conversion of array of MPVariable or MPConstraint from/to C++ vectors.
CONVERT_VECTOR_WITH_CAST(operations_research::MPVariable, MPVariable, REINTERPRET_CAST,
com/google/ortools/linearsolver);
CONVERT_VECTOR_WITH_CAST(operations_research::MPConstraint, MPConstraint, REINTERPRET_CAST,
com/google/ortools/linearsolver);
%typemap(javaimports) SWIGTYPE %{
import java.lang.reflect.*;
%}
// Support the proto-based APIs.
// TODO(user): expose these in the open-source export as well.
PROTO_INPUT(
operations_research::MPModelProto,
com.google.ortools.linearsolver.MPModelProto,
input_model);
PROTO2_RETURN(
operations_research::MPModelProto,
com.google.ortools.linearsolver.MPModelProto);
PROTO_INPUT(
operations_research::MPModelRequest,
com.google.ortools.linearsolver.MPModelRequest,
model_request);
PROTO2_RETURN(
operations_research::MPSolutionResponse,
com.google.ortools.linearsolver.MPSolutionResponse);
%extend operations_research::MPSolver {
// Replaces MPSolver::LoadModelFromProto. We simply return the error message,
// which will be empty iff the model is valid.
std::string loadModelFromProto(const operations_research::MPModelProto& input_model) {
std::string error_message;
$self->LoadModelFromProto(input_model, &error_message);
return error_message;
}
// Replaces MPSolver::LoadModelFromProtoWithUniqueNamesOrDie
std::string loadModelFromProtoWithUniqueNamesOrDie(
const operations_research::MPModelProto& input_model) {
std::unordered_set<std::string> names;
for (const auto var : input_model.variable()) {
if (!var.name().empty() && !names.insert(var.name()).second) {
LOG(FATAL) << "found duplicated variable names " + var.name();
}
}
std::string error_message;
$self->LoadModelFromProtoWithUniqueNamesOrDie(input_model, &error_message);
return error_message;
}
// Replaces MPSolver::ExportModelToProto
operations_research::MPModelProto exportModelToProto() {
operations_research::MPModelProto model;
$self->ExportModelToProto(&model);
return model;
}
// Replaces MPSolver::FillSolutionResponseProto
operations_research::MPSolutionResponse createSolutionResponseProto() {
operations_research::MPSolutionResponse response;
$self->FillSolutionResponseProto(&response);
return response;
}
// Replaces MPSolver::SolveWithProto
static operations_research::MPSolutionResponse solveWithProto(
const operations_research::MPModelRequest& model_request) {
operations_research::MPSolutionResponse response;
operations_research::MPSolver::SolveWithProto(model_request, &response);
return response;
}
std::string exportModelAsLpFormat(
const operations_research::MPModelExportOptions& options =
operations_research::MPModelExportOptions()) {
@@ -77,7 +139,7 @@ import java.lang.reflect.*;
return ExportModelAsMpsFormat(model, options).value_or("");
}
/// Set a hint for solution.
/// Sets a hint for solution.
///
/// If a feasible or almost-feasible solution to the problem is already known,
/// it may be helpful to pass it to the solver so that it can be used. A
@@ -106,7 +168,7 @@ import java.lang.reflect.*;
bool setNumThreads(int num_theads) {
return $self->SetNumThreads(num_theads).ok();
}
}
} // Extend operations_research::MPSolver
// Add java code on MPSolver.
%typemap(javacode) operations_research::MPSolver %{
@@ -150,7 +212,7 @@ import java.lang.reflect.*;
public MPVariable[] makeBoolVarArray(int count, String var_name) {
return makeVarArray(count, 0.0, 1.0, true, var_name);
}
%}
%} // %typemap(javacode) operations_research::MPSolver
%ignoreall
@@ -212,6 +274,17 @@ import java.lang.reflect.*;
%rename (infinity) operations_research::MPSolver::infinity;
%rename (setTimeLimit) operations_research::MPSolver::set_time_limit; // no test
// Proto-based API of the MPSolver. Use is encouraged.
// Note: the following proto-based methods aren't listed here, but are
// supported (that's because we re-implement them in java below):
// - loadModelFromProto
// - exportModelToProto
// - createSolutionResponseProto
// - solveWithProto
%unignore operations_research::MPSolver::LoadStatus;
%unignore operations_research::MPSolver::NO_ERROR; // no test
%unignore operations_research::MPSolver::UNKNOWN_VARIABLE_ID; // no test
%rename (loadSolutionFromProto) operations_research::MPSolver::LoadSolutionFromProto; // no test
// Expose some of the more advanced MPSolver API.
%rename (supportsProblemType) operations_research::MPSolver::SupportsProblemType; // no test

View File

@@ -28,6 +28,7 @@
//
// TODO(user): test all the APIs that are currently marked as 'untested'.
%include "std_string.i"
%include "stdint.i"
%include "ortools/base/base.i"
@@ -184,6 +185,7 @@ from ortools.linear_solver.linear_solver_natural_api import VariableExpr
}
}
static double Infinity() { return operations_research::MPSolver::infinity(); }
void SetTimeLimit(int64 x) { $self->set_time_limit(x); }
int64 WallTime() const { return $self->wall_time(); }
@@ -223,6 +225,7 @@ PY_PROTO_TYPEMAP(ortools.linear_solver.linear_solver_pb2,
// Actual conversions. This also includes the conversion to std::vector<Class>.
%define PY_CONVERT(Class)
%{
// Forcing SWIGTYPE_p_.... $descriptor( ) does not work outside of typemaps.
template<>
bool PyObjAs(PyObject *py_obj, operations_research::Class** b) {
return SWIG_ConvertPtr(py_obj, reinterpret_cast<void**>(b),
@@ -231,8 +234,8 @@ bool PyObjAs(PyObject *py_obj, operations_research::Class** b) {
}
PyObject* FromObject ## Class(operations_research::Class* obj) {
return SWIG_NewPointerObj(obj,
SWIGTYPE_p_operations_research__ ## Class,
return SWIG_NewPointerObj(obj,
SWIGTYPE_p_operations_research__ ## Class,
SWIG_POINTER_NOSHADOW);
}

View File

@@ -11,7 +11,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// Linear optimization example.
// [START program]
using System;
using Google.OrTools.LinearSolver;