Originally posted by: SystemAdmin
Hello,
I'm reaching out to some concert c++ users out there. I can't figure out why this code fails when trying to add second variable. I basically mixed together differents parts of code I found on the net.
The main method basically maps cplex variable to indexes. Displaying the original data matrix works fine so the mapping is correct...
Thank you in advance!
// MwC.cpp : Defines the entry point for the console application.
//
#include <vector>
#include<map>
#include <ilcplex/ilocplex.h>
ILOSTLBEGIN
static void usage (const char *progname);
IloInt _row_num;
IloInt _var_num;
IloInt _res_row_num;
IloInt _res_var_num;
std::vector<IloNum> _res_cap; // residual capacity of variable
struct VARIABLE {
IloInt id;
std::vector<IloNum> column_data;
IloNum obj_coef;
VARIABLE(IloInt idvalue)
{
id = idvalue;
column_data.assign(_row_num + 1, 0); // assume empty
column_data[0] = 1;
//column_data.push_back(1); // convexity constraint
}
VARIABLE() {
id = -1;
column_data.assign(_row_num + 1, 0); // assume empty
column_data[0] = 1;
//column_data.push_back(1); // convexity constraint
//column_data.reserve(_row_num + 1);
//column_data.assign(_row_num, 0);
//column_data.push_back(1);
}
};
struct ROW {
IloInt id;
unsigned int order;
IloNum rhs;
ROW(IloInt idvalue, unsigned int orderval, IloNum rhsvalue) {
id = idvalue;
order = orderval;
rhs = rhsvalue;
}
ROW() {}
};
std::map<const char*, ROW> ROWIDX;
std::map<const char*, VARIABLE> VARIDX;
void displayobj(IloNumVarArray& v) {
IloEnv env = v.getEnv();
for(int i = 0 ; i < _var_num ; ++i) {
env.out() << VARIDX[ v
http://i].getName() .obj_coef << ", ";
}
env.out() << endl;
}
void displaymatrix(IloNumVarArray& v, IloRangeArray& c) {
IloEnv env = v.getEnv();
env.out() << "DATA MATRIX: " << endl;
for(int j = 0 ; j < _row_num ; ++j) {
for(int i = 0 ; i < _var_num ; ++i) {
env.out() << VARIDX[ v
http://i].getName() .column_data[ ROWIDX[ c
http://j].getName()].order << ", ";
}
env.out() << "||" << ROWIDX[c
http://j].getName().rhs << endl;
}
}
void displayLP(IloNumVarArray& v, IloRangeArray& c) {
displayobj(v);
displaymatrix(v, c);
}
void doubleUp(IloModel& model, IloNumVarArray& orig_var, IloRangeArray& orig_c, IloModel& c_model, IloObjective& c_obj, IloNumVarArray& c_vars, IloRangeArray& c_cons) {
// model :
// Ax = b
// l <= x <= u
// Exit with c_model :
// build Ay + Aw = 0
// 1y + 1w = 1
// 0 <= y <= 1
// 0 <= w <= 1
IloEnv env = model.getEnv();
IloEnv newenv = c_model.getEnv();
// add information to respective Ilo*
c_obj = IloMinimize(newenv);
env.out() << "c" << endl;
// Constraint
c_cons.add(IloRange(newenv, 1., 1., "convexity")); // add convexity
for(int i = 0 ; i < _row_num ; ++i ) {
c_cons.add ( IloRange( newenv, 0. , 0., orig_c[i].getName())); // same "set" of constraint as ORIG
env.out() << "order: " << ROWIDX[ orig_c
http://i].getName() .order << endl;
}
env.out() << "cons size: " << c_cons.getSize() << endl;
c_model.add(c_obj);
c_model.add(c_cons);
env.out() << "v" << endl;
for(int i = 0 ; i < _var_num ; ++i) {
IloNumColumn expr = c_obj (VARIDX[orig_var
http://i].getName().obj_coef) + c_cons[0](1);
env.out() << VARIDX[orig_var
http://i].getName().obj_coef << ", ";
for(int r = 0 ; r < _row_num ; ++r) {
env.out() << VARIDX[orig_var
http://i].getName().column_data[ ROWIDX[ orig_c
http://r].getName() ].order << ", ";
expr += c_cons[ ROWIDX[ orig_c
http://r].getName() ].order ( VARIDX[orig_var
http://i].getName().column_data[ ROWIDX[ orig_c
http://r].getName() ].order );
}
env.out() << endl;
env.out() << "try add" << endl;
IloNumVar x(expr, 0.0, 1.0); // program crashes here on second loop
env.out() << orig_var[i].getName() << endl;
x.setName(orig_var[i].getName());
c_vars.add(x);
//c_vars.add( IloNumVar( expr, 0.0, 1.0));
expr.end();
char* t;
strcpy(t, orig_var[i].getName());
strcat(t, "copy");
//env.out() << "conc"<<endl;
//IloNumColumn expr2(env);
/*expr2 = c_obj (VARIDX[orig_var
http://i].getName().obj_coef) + c_cons[0](1.);
for(int r = 0 ; r < _row_num ; ++r) {
expr2 += c_cons
r + 1 ( VARIDX[orig_var
http://i].getName().column_data[ ROWIDX[ orig_c
http://r].getName() ].order );
}*/
//env.out() << "exor:" << endl;
//IloNumVar x2(expr2, 0.0, 1.0);
//env.out() << "x2" <<endl;
//x2.setName( t);
//env.out() << "second" << endl;
}
env.out() << "m" << endl;
env.out() << "done" << endl;
IloCplex cp(newenv);
cp.extract(c_model);
env.out() << "ex" << endl;
//IloCplex cp(c_model);
cp.exportModel("testoutput.lp");
cp.end();
}
int _tmain(int argc, _TCHAR* argv[])
{
IloEnv env;
try {
IloModel model(env);
IloCplex cplex(env);
cplex.setParam(IloCplex::RootAlg, IloCplex::Primal);
IloObjective obj;
IloNumVarArray var(env);
IloRangeArray rng(env);
cplex.importModel(model, "mittel/test4.mps", obj, var, rng);
cplex.extract(model);
_var_num = var.getSize();
_row_num = rng.getSize();
env.out() << "nb var: " << _var_num << " nb row: " << _row_num << endl;
// map variable names and id
for(int i = 0 ; i < _var_num ; ++i) {
VARIABLE v( var[i].getId());
VARIDX.insert(pair<const char*, VARIABLE>(var[i].getName() , v));
}
// map row names and id
unsigned int o = 0;
for(int i = 0 ; i < _row_num ; ++i) {
ROW r(rng[i].getId(), ++o, rng[i].getUB());
ROWIDX.insert(pair<const char*, ROW> ( rng[i].getName() , r));
}
// ROWIDX.insert(pair<const char*, ROW> ("convexity", 0)); // convexity constraint will be id = 0
// fill internal data matrix
for(int i = 0 ; i < rng.getSize() ; ++i) {
//cout << "row:" << rng[i].getName() << " id: " << rng[i].getId() << endl;
for (IloExpr::LinearIterator it = IloExpr(rng[i].getExpr()).getLinearIterator() ; it.ok() ; ++it) {
//env.out() << "variable id: "<< it.getVar().getId() << " var name: " << it.getVar().getName() << " coef: "<< it.getCoef() << endl;
//env.out() << "matching id: " << VARIDX
http://it.getVar().getName().id << endl;
VARIDX
http://it.getVar().getName().column_data[ ROWIDX[ rng
http://i].getName()].order = it.getCoef();
}
}
// fill obj data
for(IloExpr::LinearIterator it = IloExpr(obj.getExpr()).getLinearIterator() ; it.ok() ; ++it) {
//env.out() << "variable id: "<< it.getVar().getId() << " var name: " << it.getVar().getName() << " coef: "<< it.getCoef() << endl;
//env.out() << "matching id: " << VARIDX
http://it.getVar().getName().id << endl;
VARIDX
http://it.getVar().getName().obj_coef = it.getCoef();
}
displayLP(var, rng);
// Create new model
//IloEnv env2 = env;
IloObjective obj2;
IloModel model2(env);
IloNumVarArray var2(env);
IloRangeArray rng2(env);
doubleUp(model, var, rng, model2, obj2, var2, rng2);
if ( !cplex.solve() ) {
env.error() << "Failed to optimize LP" << endl;
throw(-1);
}
IloNumArray vals(env);
cplex.getValues(vals, var);
env.out() << "Solution status = " << cplex.getStatus() << endl;
env.out() << "Solution value = " << cplex.getObjValue() << endl;
// env.out() << "Solution vector = " << vals << endl;
// try { // basis may not exist
// IloCplex::BasisStatusArray cstat(env);
//cplex.getBasisStatuses(cstat, var);
// //cplex.getStatuses(cstat, var);
// env.out() << "Basis statuses = " << cstat << endl;
// } catch (...) {
// }
env.out() << "Maximum bound violation = "
<< cplex.getQuality(IloCplex::MaxPrimalInfeas) << endl;
}
catch (IloException& e) {
cerr << "Concert exception caught: " << e << endl;
}
catch (...) {
cerr << "Unknown exception caught" << endl;
}
env.end();
return 0;
} // END main
static void usage (const char *progname)
{
cerr << "Usage: " << progname << " filename algorithm" << endl;
cerr << " where filename is a file with extension " << endl;
cerr << " MPS, SAV, or LP (lower case is allowed)" << endl;
cerr << " and algorithm is one of the letters" << endl;
cerr << " o default" << endl;
cerr << " p primal simplex" << endl;
cerr << " d dual simplex " << endl;
cerr << " b barrier " << endl;
cerr << " h barrier with crossover" << endl;
cerr << " n network simplex" << endl;
cerr << " Exiting..." << endl;
} // END usage
#CPLEXOptimizers#DecisionOptimization