int main() { IloEnv env; try { IloModel model(env); setData(env); IloNumVarArray inside(env, nbProds); IloNumVarArray outside(env, nbProds); IloObjective obj = IloAdd(model, IloMinimize(env)); // Must meet demand for each product for(IloInt p = 0; p < nbProds; p++) { IloRange demRange = IloAdd(model, IloRange (env, demand[p], demand[p])); inside[p] = IloNumVar(obj(insideCost[p]) + demRange(1)); outside[p] = IloNumVar(obj(outsideCost[p]) + demRange(1)); } // Must respect capacity constraint for each resource for(IloInt r = 0; r < nbResources; r++) model.add(IloScalProd(consumption[r], inside) <= capacity[r]); IloCplex cplex(env); cplex.extract(model); cplex.solve(); if (cplex.getStatus() != IloAlgorithm::Optimal) cout << "No optimal solution" << endl; cout << "Solution status: " << cplex.getStatus() << endl; displayResults(cplex, inside, outside); cout << "----------------------------------------" << endl; } catch (IloException& ex) { cerr << "Error: " << ex << endl; } catch (...) { cerr << "Error" << endl; } env.end(); return 0; }
void MILPSolverCPX::addRow(const vector<pair<int,double> > & entries, const double & lb, const double & ub) { static const bool debug = false; if (debug) cout << "Adding row to LP: "; IloRange & newRange = modelcon->data[rowCount] = IloAdd(*model, IloRange(*env, lb,ub)); map<int,double> & dest = coeffs[rowCount]; const int entCount = entries.size(); for (int i = 0; i < entCount; ++i) { newRange.setLinearCoef((*modelvar)[entries[i].first], entries[i].second); dest[entries[i].first] = entries[i].second; if (debug) { if (i) cout << " + "; cout << entries[i].second << "*" << entries[i].first; } } if (debug) { if (lb == -IloInfinity) { cout << " <= " << ub << "\n"; } else if (ub == IloInfinity) { cout << " >= " << lb << "\n"; } else if (ub == lb) { cout << " == " << ub << "\n"; } else { cout << " in [" << lb << "," << ub << "]\n"; } } ++rowCount; }
MILPSolverCPX::MILPSolverCPX(MILPSolverCPX & c) { static const bool debug = false; if (debug) { cout << "Copying...\n"; ostringstream copyfn; copyfn << "copyconstructor" << *(c.envUsers) << ".lp"; const string copyfns = copyfn.str(); c.writeLp(copyfns.c_str()); } env = c.env; envUsers = c.envUsers; ++(*envUsers); model = new IloModel(*env); modelvar = new IloNumVarArray(*env); modelcon = new Constraints(); obj = new IloObjective(*env); obj->setSense(IloObjective::Minimize); model->add(*obj); colCount = c.colCount; rowCount = c.rowCount; integervars = c.integervars; map<int,bool>::const_iterator iItr = integervars.begin(); const map<int,bool>::const_iterator iEnd = integervars.end(); for (int ci = 0; ci < colCount; ++ci) { const double lb = (*(c.modelvar))[ci].getLB(); const double ub = (*(c.modelvar))[ci].getUB(); if (iItr != iEnd && iItr->first == ci) { modelvar->add(IloNumVar(*env, lb, ub, (iItr->second ? ILOBOOL : ILOINT))); //cout << "Column " << ci << " in the copy is an integer\n"; ++iItr; } else { modelvar->add(IloNumVar(*env, lb, ub)); } const char * oldName = (*(c.modelvar))[ci].getName(); (*modelvar)[ci].setName(oldName); } coeffs = c.coeffs; map<int,map<int,double> >::const_iterator coItr = coeffs.begin(); const map<int,map<int,double> >::const_iterator coEnd = coeffs.end(); map<int,IloRange>::iterator dItr = c.modelcon->data.begin(); const map<int,IloRange>::iterator dEnd = c.modelcon->data.end(); for (int r = 0; dItr != dEnd; ++r, ++dItr) { const double lb = dItr->second.getLB(); const double ub = dItr->second.getUB(); IloRange & newRange = modelcon->data[r] = IloAdd(*model, IloRange(*env, lb,ub)); if (dItr->second.getName()) { newRange.setName(dItr->second.getName()); } if (coItr == coEnd) continue; if (r < coItr->first) continue; map<int,double>::const_iterator fItr = coItr->second.begin(); const map<int,double>::const_iterator fEnd = coItr->second.end(); for (; fItr != fEnd; ++fItr) { newRange.setLinearCoef((*modelvar)[fItr->first], fItr->second); } ++coItr; } cplex = new IloCplex(*model); setILS(cplex); solArray = 0; if (debug) { ostringstream copyfn; copyfn << "aftercopyconstructor" << *(c.envUsers) << ".lp"; const string copyfns = copyfn.str(); writeLp(copyfns.c_str()); } }
int main(int argc, char **argv) { IloEnv env; try { IloInt i, j; IloNum rollWidth; IloNumArray amount(env); IloNumArray size(env); if ( argc > 1 ) readData(argv[1], rollWidth, size, amount); else readData("../../../examples/data/cutstock.dat", rollWidth, size, amount); /// CUTTING-OPTIMIZATION PROBLEM /// IloModel cutOpt (env); IloObjective RollsUsed = IloAdd(cutOpt, IloMinimize(env)); IloRangeArray Fill = IloAdd(cutOpt, IloRangeArray(env, amount, IloInfinity)); IloNumVarArray Cut(env); IloInt nWdth = size.getSize(); for (j = 0; j < nWdth; j++) { Cut.add(IloNumVar(RollsUsed(1) + Fill[j](int(rollWidth / size[j])))); } IloCplex cutSolver(cutOpt); /// PATTERN-GENERATION PROBLEM /// IloModel patGen (env); IloObjective ReducedCost = IloAdd(patGen, IloMinimize(env, 1)); IloNumVarArray Use(env, nWdth, 0.0, IloInfinity, ILOINT); patGen.add(IloScalProd(size, Use) <= rollWidth); IloCplex patSolver(patGen); /// COLUMN-GENERATION PROCEDURE /// IloNumArray price(env, nWdth); IloNumArray newPatt(env, nWdth); /// COLUMN-GENERATION PROCEDURE /// for (;;) { /// OPTIMIZE OVER CURRENT PATTERNS /// cutSolver.solve(); report1 (cutSolver, Cut, Fill); /// FIND AND ADD A NEW PATTERN /// for (i = 0; i < nWdth; i++) { price[i] = -cutSolver.getDual(Fill[i]); } ReducedCost.setLinearCoefs(Use, price); patSolver.solve(); report2 (patSolver, Use, ReducedCost); if (patSolver.getValue(ReducedCost) > -RC_EPS) break; patSolver.getValues(newPatt, Use); Cut.add( IloNumVar(RollsUsed(1) + Fill(newPatt)) ); } cutOpt.add(IloConversion(env, Cut, ILOINT)); cutSolver.solve(); cout << "Solution status: " << cutSolver.getStatus() << endl; report3 (cutSolver, Cut); } catch (IloException& ex) { cerr << "Error: " << ex << endl; } catch (...) { cerr << "Error" << endl; } env.end(); return 0; }