Skip to content

Commit

Permalink
Export NL model: write var defs #232
Browse files Browse the repository at this point in the history
  • Loading branch information
glebbelov committed Mar 14, 2024
1 parent b8514e6 commit a0e92ee
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 26 deletions.
6 changes: 6 additions & 0 deletions include/mp/flat/constr_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "mp/format.h"
#include "mp/error.h"
#include "mp/common.h"

#include "mp/flat/context.h"
#include "mp/arrayref.h"
Expand Down Expand Up @@ -346,6 +347,11 @@ class ConditionalConstraint :
}
};

/// Write a readable variable definition
template <class Writer>
void WriteVar(Writer& pr, const char* name,
double lb, double ub, var::Type ty);

/// Write a CondCon
template <class JW, class Con>
inline void WriteJSON(JW jw,
Expand Down
4 changes: 2 additions & 2 deletions include/mp/flat/converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,8 +503,8 @@ class FlatConverter :
MPD( CloseGraphExporter() );
if (value_presolver_.GetExport())
assert( value_presolver_.AllEntriesExported() );
// if (GetEnv().verbose_mode())
GetEnv().PrintWarnings();
// Printing always. if (GetEnv().verbose_mode())
GetEnv().PrintWarnings();
}

/// Check linear constraints.
Expand Down
7 changes: 6 additions & 1 deletion include/mp/flat/converter_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,13 @@ class FlatModel
MiniJSONWriter jw(wrt);
int i_actual = i+i_start;
jw["VAR_index"] = i_actual;
if (var_names_storage_.size() > i)
if (var_names_storage_.size() > i_actual) {
int i = i_actual;
jw["name"] = var_names_[i];
fmt::MemoryWriter pr;
WriteVar(pr, var_names_[i], lbs[i], ubs[i], types[i]);
jw["printed"] = pr.c_str();
}
jw["bounds"]
<< (lbs[i] < -DBL_MAX ? -DBL_MAX : lbs[i])
<< (ubs[i] > DBL_MAX ? DBL_MAX : ubs[i]);
Expand Down
44 changes: 22 additions & 22 deletions include/mp/problem.h
Original file line number Diff line number Diff line change
Expand Up @@ -478,43 +478,43 @@ class BasicProblem : public ExprFactory, public SuffixManager {
/// Normal variable name
const std::string& var_name(int i) {
assert(0<=i && i<num_vars());
if ((int)var_names().size()<=i)
var_names_.resize(num_vars());
if (var_names_[i].empty())
var_names_[i] = "_x[" + std::to_string(i+1) + "]";
return var_names_[i];
return item_name(i, var_names_, num_vars(), "_x[");
}
/// Defined variable name
const std::string& dvar_name(int i) {
assert(0<=i && i<num_common_exprs());
i += num_vars();
if ((int)var_names().size()<=i)
var_names_.resize(num_vars()+num_common_exprs());
if (var_names_[i].empty())
var_names_[i] = "_sdvar[" + std::to_string(i+1) + "]";
return var_names_[i];
return item_name(i, var_names_,
num_vars()+num_common_exprs(), "_x[",
num_vars(), "_sdvar[");
}
/// Constraint name
const std::string& con_name(int i) {
assert(0<=i && i<num_cons());
if ((int)con_names().size()<=i)
con_names_.resize(num_cons());
if (con_names_[i].empty())
con_names_[i]
= (i<num_algebraic_cons() ? "_CON" : "_LCON")
+ std::to_string(i+1);
return con_names_[i];
return item_name(i, con_names_,
num_cons(), "_CON",
num_algebraic_cons(), "_LCON");
}
/// Objective name
const std::string& obj_name(int i) {
assert(0<=i && i<num_objs());
if ((int)obj_names().size()<=i)
obj_names_.resize(num_objs());
if (obj_names_[i].empty())
obj_names_[i] = "_OBJ" + std::to_string(i+1);
return obj_names_[i];
return item_name(i, obj_names_, num_objs(), "_OBJ");
}

protected:
/// Return names[i].
/// Generate names[old_size...n-1] if needed,
/// so that the whole vector is valid,
/// even if only some variables/cons/objs were queried.
/// From [n2], name 'stub2'[i-n2] is given.
/// If stub/stub2 ends with a '[', ']' is added after the index.
static const std::string& item_name(
int i, std::vector<std::string>& names,
int n, const char* stub,
int n2=std::numeric_limits<int>::max(),
const char* stub2=nullptr);

public:
/** Returns the variable names (if present).
* After normal variables follow defined variables.
*/
Expand Down
38 changes: 37 additions & 1 deletion src/problem.cc
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,43 @@ void BasicProblem<Alloc>::SetInfo(const NLProblemInfo &info) {
nonlinear_exprs_.reserve(num_common_exprs);
}

/// Instantiate
template <typename Params>
const std::string& BasicProblem<Params>::item_name(
int i, std::vector<std::string>& names,
int n, const char* stub, int n2, const char* stub2) {
assert(0<=i && i<n);
if ((int)names.size()<n) {
int sz0 = (int)names.size();
names.resize(n);
int k=sz0;
auto gen_names = [&names](
int k, int n, const char* stub, int k_sub=0) {
for ( ; k<n; k++) {
assert(stub);
int l = std::strlen(stub);
assert(l);
bool fbr = '['==stub[l-1];
names[k] = stub;
names[k] += std::to_string(k-k_sub+1);
if (fbr)
names[k] += ']';
}
};
if (n2>=0 && n2<n) {
if (k<n2) {
gen_names(k, n2, stub);
gen_names(n2, n, stub2, n2);
} else
gen_names(k, n, stub2, n2);
} else
gen_names(k, n, stub);
}
assert(names[i].size());
return names[i];
}

// Instantiations

template class BasicProblem< >;

template void ReadNLFile(fmt::CStringRef filename, Problem &p, int flags);
Expand Down
27 changes: 27 additions & 0 deletions src/std_constr.cc
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#include <map>
#include <cfloat>
#include <cassert>

#include "mp/format.h"
#include "mp/util-json-write.hpp"
#include "mp/common.h"

#include "mp/flat/expr_quadratic.h"
#include "mp/flat/model_info.hpp"
Expand Down Expand Up @@ -70,6 +72,31 @@ void QuadTerms::sort_terms() {
}
}

template <class Writer>
void WriteVar(Writer& pr, const char* name,
double lb, double ub, var::Type ty) {
assert(*name);
pr << "var " << name;
if (!lb && 1.0==ub && var::INTEGER==ty)
pr << " binary";
else if (lb==ub)
pr << " = " << lb;
else {
if (lb >= -DBL_MAX)
pr << " >=" << lb;
if (ub <= DBL_MAX)
pr << " <=" << ub;
if (var::INTEGER == ty)
pr << " integer";
}
pr << ';';
}

// Generate
template
void WriteVar(fmt::MemoryWriter& pr, const char* name,
double lb, double ub, var::Type ty);

template <>
void WriteJSON(JSONW jw, const QuadTerms& qt) {
jw["coefs"] = qt.coefs();
Expand Down
8 changes: 8 additions & 0 deletions test/end2end/cases/categorized/fast/suf_common/modellist.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@
"solve_result_num": 0
}
},
{
"name": "mipbound_01 objno=0 writegraph",
"tags": [ "linear", "return_mipgap"],
"options": { "ANYSOLVER_options": "objno=0 writegraph=mipb_01.jsonl" },
"values": {
"solve_result_num": 0
}
},
{
"name" : "dietu_stt sensitivity=1",
"objective" : 74.273820,
Expand Down

0 comments on commit a0e92ee

Please sign in to comment.