fix model exporter in java/c#
This commit is contained in:
@@ -664,10 +664,10 @@ MPSolver::BasisStatus GLPKInterface::TransformGLPKBasisStatus(
|
||||
// ------ Query statistics on the solution and the solve ------
|
||||
|
||||
int64 GLPKInterface::iterations() const {
|
||||
#if GLP_MINOR_VERSION < 49
|
||||
#if GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION < 49
|
||||
if (!mip_ && CheckSolutionIsSynchronized())
|
||||
return lpx_get_int_parm(lp_, LPX_K_ITCNT);
|
||||
#elif GLP_MINOR_VERSION >= 53
|
||||
#elif GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION >= 53
|
||||
if (!mip_ && CheckSolutionIsSynchronized()) {
|
||||
return glp_get_it_cnt(lp_);
|
||||
}
|
||||
|
||||
@@ -729,7 +729,7 @@ std::string GurobiInterface::ValidFileExtensionForParameterFile() const {
|
||||
return ".prm";
|
||||
}
|
||||
|
||||
MPSolverInterface* BuildGurobiInterface(MPSolver* const solver, bool mip) {
|
||||
MPSolverInterface* BuildGurobiInterface(bool mip, MPSolver* const solver) {
|
||||
return new GurobiInterface(solver, mip);
|
||||
}
|
||||
|
||||
|
||||
@@ -335,8 +335,8 @@ extern MPSolverInterface* BuildSCIPInterface(MPSolver* const solver);
|
||||
extern MPSolverInterface* BuildSLMInterface(MPSolver* const solver, bool mip);
|
||||
#endif
|
||||
#if defined(USE_GUROBI)
|
||||
extern MPSolverInterface* BuildGurobiInterface(MPSolver* const solver,
|
||||
bool mip);
|
||||
extern MPSolverInterface* BuildGurobiInterface(bool mip,
|
||||
MPSolver* const solver);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -370,9 +370,9 @@ MPSolverInterface* BuildSolverInterface(MPSolver* const solver) {
|
||||
#endif
|
||||
#if defined(USE_GUROBI)
|
||||
case MPSolver::GUROBI_LINEAR_PROGRAMMING:
|
||||
return BuildGurobiInterface(solver, false);
|
||||
return BuildGurobiInterface(false, solver);
|
||||
case MPSolver::GUROBI_MIXED_INTEGER_PROGRAMMING:
|
||||
return BuildGurobiInterface(solver, true);
|
||||
return BuildGurobiInterface(true, solver);
|
||||
#endif
|
||||
default:
|
||||
// TODO(user): Revert to the best *available* interface.
|
||||
|
||||
@@ -63,6 +63,11 @@
|
||||
%rename (Objective) MutableObjective;
|
||||
// Access to the underlying solver is available only in C++.
|
||||
%ignore underlying_solver;
|
||||
// The ExportModelAs*Format methods return the string directly in the python
|
||||
// API, using an empty string to indicate failures (which can also indicate an
|
||||
// empty model).
|
||||
%ignore ExportModelAsLpFormat(bool, string*);
|
||||
%ignore ExportModelAsMpsFormat(bool, bool, string*);
|
||||
|
||||
namespace operations_research {
|
||||
%pythoncode {
|
||||
@@ -535,7 +540,7 @@ namespace operations_research {
|
||||
%rename (clear) MPObjective::Clear;
|
||||
%rename (clear) MPSolver::Clear;
|
||||
%rename (computeExactConditionNumber) MPSolver::ComputeExactConditionNumber;
|
||||
%rename (loadModel) MPSolver::LoadModel;
|
||||
%rename (loadModelFromProto) MPSolver::LoadModelFromProto;
|
||||
%rename (lookupVariableOrNull) MPSolver::LookupVariableOrNull;
|
||||
%rename (lookupConstraintOrNull) MPSolver::LookupConstraintOrNull;
|
||||
%rename (makeBoolVar) MPSolver::MakeBoolVar;
|
||||
@@ -577,6 +582,9 @@ namespace operations_research {
|
||||
%ignore MPSolver::ExportModel;
|
||||
%ignore MPSolver::FillSolutionResponse;
|
||||
%ignore MPSolver::SolveWithProtocolBuffers;
|
||||
// Ignore export to string methods.
|
||||
%ignore operations_research::MPSolver::ExportModelAsLpFormat;
|
||||
%ignore operations_research::MPSolver::ExportModelAsMpsFormat;
|
||||
// Access to the underlying solver is available only in C++.
|
||||
%ignore MPSolver::underlying_solver;
|
||||
|
||||
@@ -646,6 +654,21 @@ Class c = Class.forName("com.google.ortools.linearsolver.MPSolver");
|
||||
}
|
||||
%}
|
||||
|
||||
%extend MPSolver {
|
||||
std::string exportModelAsLpFormat(bool obfuscated) {
|
||||
std::string output;
|
||||
if (!self->ExportModelAsLpFormat(obfuscated, &output)) return "";
|
||||
return output;
|
||||
}
|
||||
|
||||
std::string exportModelAsMpsFormat(bool fixed_format, bool obfuscated) {
|
||||
std::string output;
|
||||
if (!self->ExportModelAsMpsFormat(fixed_format, obfuscated, &output)) {
|
||||
return "";
|
||||
}
|
||||
return output;
|
||||
}
|
||||
}
|
||||
} // namespace operations_research
|
||||
|
||||
#endif // SWIGJAVA
|
||||
@@ -689,6 +712,9 @@ namespace operations_research {
|
||||
// Ignore Objective(), use MutableObjective() instead.
|
||||
%ignore MPSolver::Objective;
|
||||
%rename (Objective) MPSolver::MutableObjective;
|
||||
// Ignore export to string methods.
|
||||
%ignore operations_research::MPSolver::ExportModelAsLpFormat;
|
||||
%ignore operations_research::MPSolver::ExportModelAsMpsFormat;
|
||||
|
||||
%typemap(cscode) MPVariable %{
|
||||
public static LinearExpr operator+(Variable a, double v)
|
||||
@@ -1089,6 +1115,20 @@ namespace operations_research {
|
||||
Objective().SetMaximization();
|
||||
Objective().SetCoefficient(var, 1.0);
|
||||
}
|
||||
|
||||
std::string ExportModelAsLpFormat(bool obfuscated) {
|
||||
std::string output;
|
||||
if (!self->ExportModelAsLpFormat(obfuscated, &output)) return "";
|
||||
return output;
|
||||
}
|
||||
|
||||
std::string ExportModelAsMpsFormat(bool fixed_format, bool obfuscated) {
|
||||
std::string output;
|
||||
if (!self->ExportModelAsMpsFormat(fixed_format, obfuscated, &output)) {
|
||||
return "";
|
||||
}
|
||||
return output;
|
||||
}
|
||||
%}
|
||||
|
||||
} // namespace operations_research
|
||||
|
||||
@@ -436,6 +436,28 @@ bool MPModelProtoExporter::CanUseFixedMpsFormat() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void MPModelProtoExporter::AppendMpsColumns(bool integrality,
|
||||
const std::vector<std::vector<std::pair<int, double>>>& transpose, std::string* output) {
|
||||
current_mps_column_ = 0;
|
||||
for (int var_index = 0; var_index < proto_.variable_size(); ++var_index) {
|
||||
const MPVariableProto& var_proto = proto_.variable(var_index);
|
||||
if (var_proto.is_integer() != integrality) continue;
|
||||
const std::string var_name = GetVariableName(var_index);
|
||||
current_mps_column_ = 0;
|
||||
if (var_proto.objective_coefficient() != 0.0) {
|
||||
AppendMpsTermWithContext(var_name, "COST",
|
||||
var_proto.objective_coefficient(),
|
||||
output);
|
||||
}
|
||||
for (const std::pair<int, double> cst_index_and_coeff : transpose[var_index]) {
|
||||
const std::string cst_name = GetConstraintName(cst_index_and_coeff.first);
|
||||
AppendMpsTermWithContext(var_name, cst_name, cst_index_and_coeff.second,
|
||||
output);
|
||||
}
|
||||
AppendNewLineIfTwoColumns(output);
|
||||
}
|
||||
}
|
||||
|
||||
bool MPModelProtoExporter::ExportModelAsMpsFormat(bool fixed_format,
|
||||
bool obfuscated,
|
||||
std::string* output) {
|
||||
@@ -486,9 +508,9 @@ bool MPModelProtoExporter::ExportModelAsMpsFormat(bool fixed_format,
|
||||
}
|
||||
|
||||
// As the information regarding a column needs to be contiguous, we create
|
||||
// a map associating a variable to a the vector containing the indices of the
|
||||
// a map associating a variable to a vector containing the indices of the
|
||||
// constraints where this variable appears.
|
||||
std::vector<std::vector<std::pair<int, double> > > transpose(proto_.variable_size());
|
||||
std::vector<std::vector<std::pair<int, double>>> transpose(proto_.variable_size());
|
||||
for (int cst_index = 0; cst_index < proto_.constraint_size(); ++cst_index) {
|
||||
const MPConstraintProto& ct_proto = proto_.constraint(cst_index);
|
||||
for (int k = 0; k < ct_proto.var_index_size(); ++k) {
|
||||
@@ -506,35 +528,16 @@ bool MPModelProtoExporter::ExportModelAsMpsFormat(bool fixed_format,
|
||||
}
|
||||
|
||||
// COLUMNS section.
|
||||
current_mps_column_ = 0;
|
||||
std::string columns_section;
|
||||
const char* const kIntMarkerFormat = " %-10s%-36s%-10s\n";
|
||||
for (int var_index = 0; var_index < proto_.variable_size(); ++var_index) {
|
||||
const MPVariableProto& var_proto = proto_.variable(var_index);
|
||||
const std::string var_name = GetVariableName(var_index);
|
||||
current_mps_column_ = 0;
|
||||
if (var_proto.is_integer()) {
|
||||
StringAppendF(&columns_section, kIntMarkerFormat, "INTSTART", "'MARKER'",
|
||||
"'INTORG'");
|
||||
}
|
||||
if (var_proto.objective_coefficient() != 0.0) {
|
||||
AppendMpsTermWithContext(var_name, "COST",
|
||||
var_proto.objective_coefficient(),
|
||||
&columns_section);
|
||||
}
|
||||
for (const std::pair<int, double> cst_index_and_coeff : transpose[var_index]) {
|
||||
const std::string cst_name = GetConstraintName(cst_index_and_coeff.first);
|
||||
AppendMpsTermWithContext(var_name, cst_name, cst_index_and_coeff.second,
|
||||
&columns_section);
|
||||
}
|
||||
if (var_proto.is_integer()) {
|
||||
columns_section += "\n";
|
||||
current_mps_column_ = 0;
|
||||
StringAppendF(&columns_section, kIntMarkerFormat, "INTEND", "'MARKER'",
|
||||
"'INTEND'");
|
||||
}
|
||||
AppendNewLineIfTwoColumns(&columns_section);
|
||||
AppendMpsColumns(/*integrality=*/true, transpose, &columns_section);
|
||||
if (!columns_section.empty()) {
|
||||
const char* const kIntMarkerFormat = " %-10s%-36s%-10s\n";
|
||||
columns_section = StringPrintf(kIntMarkerFormat, "INTSTART",
|
||||
"'MARKER'", "'INTORG'") + columns_section;
|
||||
StringAppendF(&columns_section, kIntMarkerFormat,
|
||||
"INTEND", "'MARKER'", "'INTEND'");
|
||||
}
|
||||
AppendMpsColumns(/*integrality=*/false, transpose, &columns_section);
|
||||
if (!columns_section.empty()) {
|
||||
*output += "COLUMNS\n" + columns_section;
|
||||
}
|
||||
|
||||
@@ -151,6 +151,13 @@ class MPModelProtoExporter {
|
||||
// Used by and in complement to AppendMpsTermWithContext.
|
||||
void AppendNewLineIfTwoColumns(std::string* output);
|
||||
|
||||
// When 'integrality' is true, appends columns corresponding to integer
|
||||
// variables. Appends the columns for non-integer variables otherwise.
|
||||
// The sparse matrix must be passed as a vector of columns ('transpose').
|
||||
void AppendMpsColumns(bool integrality,
|
||||
const std::vector<std::vector<std::pair<int, double>>>& transpose,
|
||||
std::string* output);
|
||||
|
||||
// Appends a line describing the bound of a variablenew-line if two columns
|
||||
// are already present on the MPS line.
|
||||
// Used by and in complement to AppendMpsTermWithContext.
|
||||
|
||||
Reference in New Issue
Block a user