CPlexSolver::CPlexSolver(const Matrix& A, unsigned int lambda) : env(), model(env), vars(env), constraints(env), solutionVectors() { // Add variables for (int i = 0; i < A.shape()[1]; i++) { vars.add(IloBoolVar(env)); // For simple t-designs } // Add constraints for (int i = 0; i < A.shape()[0]; i++) { constraints.add(IloRange(env, lambda, lambda)); // RHS = lambda in every equation } // Set up model to have as few block orbits as possible IloObjective objective = IloMinimize(env); for (int i = 0; i < A.shape()[1]; i++) { objective.setLinearCoef(vars[i], 1); } // Set up constraints according to input matrix for (int i = 0; i < A.shape()[0]; i++) { for (int j = 0; j < A.shape()[1]; j++) { constraints[i].setLinearCoef(vars[j], A[i][j]); } } // TODO - names for constraints/vars may be necessary // Might have to name these after the row/col labels for K-M Matrix // Finish setting up the model model.add(objective); model.add(constraints); }
void BNC::buildModelNF(){ env = new IloEnv; model = new IloModel(*env); variables = new IloNumVarArray(*env); constraints = new IloRangeArray(*env); //create variables for( int i = 0; i < n; ++i ){ variables->add( IloIntVar( *env, 0, 1 ) ); variables->add( IloIntVar( *env, 0, 1 ) ); } for( int i = 0, k = 0; i < n; ++i ){ for( int j = i; j < n; ++j ){ if( graph[i][j] ){ IloRange newconstraintA( *env, 0, 1 ); IloRange newconstraintB( *env, 0, 1 ); newconstraintA.setLinearCoef( (*variables)[i], 1 ); newconstraintA.setLinearCoef( (*variables)[j], 1 ); newconstraintB.setLinearCoef( (*variables)[n+i], 1 ); newconstraintB.setLinearCoef( (*variables)[n+j], 1 ); constraints->add( newconstraintA ); constraints->add( newconstraintB ); ++k; } } } for( int i = 0; i < n; ++i ){ IloRange newconstraintAB( *env, 0, 1 ); newconstraintAB.setLinearCoef( (*variables)[i], 1 ); newconstraintAB.setLinearCoef( (*variables)[n+i], 1 ); constraints->add( newconstraintAB ); } //objective function IloObjective obj = IloMaximize(*env); //objective for( int i = 0 ; i < n; i++ ){ obj.setLinearCoef((*variables)[i], 1 ); obj.setLinearCoef((*variables)[n+i], 1 ); } model->add( *constraints ); model->add( obj ); cplex = new IloCplex(*model); configureCPLEX(); //write model in file cplexmodel.lp cplex->exportModel("cplexmodel.lp"); }
static void populatebynonzero (IloModel model, IloIntVarArray x, IloRangeArray c) { IloEnv env = model.getEnv(); IloObjective obj = IloMaximize(env); int n, a; scanf("%d", &n); scanf("%d", &a); //restrição c.add(IloRange(env, -IloInfinity, a)); //variaveis for(int i=0 ; i<n; i++){ x.add(IloIntVar(env, 0, 1)); } /*x.add(IloIntVar(env, 0.0, 40.0)); x.add(IloIntVar(env)); x.add(IloIntVar(env));*/ /*obj.setLinearCoef(x[0], 1.0); obj.setLinearCoef(x[1], 2.0); obj.setLinearCoef(x[2], 3.0);*/ /*restricoes*/ for(int i=0 ; i<n; i++){ scanf("%d", &a); c[0].setLinearCoef(x[i], a); } //objetivo for(int i=0 ; i<n; i++){ scanf("%d", &a); obj.setLinearCoef(x[i], a); } /*c[0].setLinearCoef(x[1], 1.0); c[0].setLinearCoef(x[2], 1.0); c[1].setLinearCoef(x[0], 1.0); c[1].setLinearCoef(x[1], -3.0); c[1].setLinearCoef(x[2], 1.0);*/ c[0].setName("c1"); for(int i=0; i<n; i++){ char tmp[10]; printf("x%d", i+1); x[i].setName(tmp); } model.add(obj); model.add(c); } // END populatebynonzero
static void populatebynonzero(IloModel model, NumVarMatrix varOutput, NumVar3Matrix varHelp, Range3Matrix con) { IloEnv env = model.getEnv(); IloObjective obj = IloMaximize(env); //maximization function for (int j = current; j < current + J; ++j) { for (int k = 0; k < K; ++k) { obj.setLinearCoef(varOutput[j][k], 1.0);//add all variables to objective function, factor 1 //constraint 0: express value of output objective variables model.add(varOutput[j][k] + varHelp[j][k][2] - varHelp[j][k][3] == 0); //constraint 1: Td2a>=+Td2b model.add(varHelp[j][k][5] - varHelp[j][k][4] >= 0); //constraint 2: Tj>=Td2a + Tdc + Tblow model.add(varHelp[j][k][5] <= T[j] - Tdc - Tblow[j] - Tslack); //constraint 3: Td2b = Tfa+Tfd model.add(Tfd[k] == varHelp[j][k][4] - varHelp[j][k][3]); //constraint 4: Td1a >= Td1b model.add(0 <= varHelp[j][k][1] - varHelp[j][k][0]); //constraint 5: Tfb >= Td1a+Tdf model.add(Tdf[k] <= varHelp[j][k][2] - varHelp[j][k][1]); //constraint 6: Td1b = T(j-a)+Tcd model.add(T[j - a[k]] + Tcd == varHelp[j][k][0]); //constraint 7: Td1a >= Td2b(j-b) + Tloss, 1 model.add(TlossD[k] <= varHelp[j][k][1] - varHelp[j - b[k]][k][4]); //constraint 8: Tfb >= Tfa(j-1)+Tloss, 2 model.add(TlossF[k] <= varHelp[j][k][2] - varHelp[j - 1][k][3]); //constraint 9: at least X s for every load model.add(varOutput[j][k] >= TloadMin[k]); } //constraint 10: both spoons are picked up at same time at dropoff: Td2a,1 == Td2a,2 model.add(varHelp[j][1][5] == varHelp[j][0][5]); } model.add(obj); }
void generateProblem(const ILPModel& m, IloModel& model, IloNumVarArray& x, IloRangeArray& con) { IloEnv env = model.getEnv(); IloObjective obj = (m.obj == MINIMIZE ? IloMinimize(env) : IloMaximize(env)); for (unsigned long v = 0; v < m.numberOfVariables(); ++v) { switch (m.x[v].type) { case FLT: x.add(IloNumVar(env, m.x[v].lowerBound, m.x[v].upperBound, IloNumVar::Float)); break; case BIN: x.add(IloNumVar(env, m.x[v].lowerBound, m.x[v].upperBound, IloNumVar::Bool)); break; default: x.add(IloNumVar(env, m.x[v].lowerBound, m.x[v].upperBound, IloNumVar::Int)); } obj.setLinearCoef(x[v], m.c[v]); x[v].setName(m.varDesc[v].c_str()); } for (unsigned long c = 0; c < m.numberOfConstraints(); ++c) { switch (m.ops[c]) { case LESS_EQUAL: con.add(IloRange(env, -IloInfinity, m.b[c])); break; case EQUAL: con.add(IloRange(env, m.b[c], m.b[c])); break; case GREATER_EQUAL: con.add(IloRange(env, m.b[c], IloInfinity)); } for (const pair<uint32_t, double>& p : m.A[c]) con[c].setLinearCoef(x[p.first], p.second); con[c].setName(m.conDesc[c].c_str()); } model.add(obj); model.add(con); }
/** Destructor. */ ~Worker() { if ( handle ) { handle.kill(); handle.join(); } if ( cplex.getImpl() ) { cplex.userfunction(USERACTION_REMOVECALLBACK, 0, NULL, 0, 0, NULL); cplex.end(); } rng.end(); x.end(); obj.end(); model.end(); }
int main (int argc, char **argv) { char const *vmconfig = NULL; // Check command line length (exactly two arguments are required). if ( argc != 3 ) { usage (argv[0]); return -1; } // Pick up VMC from command line. vmconfig = argv[1]; // Solve the model. int exitcode = 0; IloEnv env; try { // Create and read the model. IloModel model(env); IloCplex cplex(model); IloObjective obj; IloNumVarArray var(env); IloRangeArray rng(env); IloSOS1Array sos1(env); IloSOS2Array sos2(env); IloRangeArray lazy(env); IloRangeArray cuts(env); cplex.importModel(model, argv[2], obj, var, rng, sos1, sos2, lazy, cuts); cplex.extract(model); if ( lazy.getSize() > 0 ) cplex.addLazyConstraints (lazy); if ( cuts.getSize() > 0 ) cplex.addUserCuts (cuts); // Load the virtual machine configuration. // This will force solve() to use parallel distributed MIP. cplex.readVMConfig(vmconfig); // Install logging info callback. IloNum lastObjVal = (obj.getSense() == IloObjective::Minimize ) ? IloInfinity : -IloInfinity; cplex.use(loggingCallback(env, var, -100000, lastObjVal, cplex.getCplexTime(), cplex.getDetTime())); // Turn off CPLEX logging cplex.setParam(IloCplex::Param::MIP::Display, 0); // Solve the problem and display some results. if ( cplex.solve() ) env.out() << "Solution value = " << cplex.getObjValue() << endl; else env.out() << "No solution" << endl; env.out() << "Solution status = " << cplex.getStatus() << endl; // Cleanup. cplex.end(); model.end(); } catch (IloException& e) { cerr << "Concert exception caught: " << e << endl; exitcode = -1; } catch (...) { cerr << "Unknown exception caught" << endl; exitcode = -1; } env.end(); return exitcode; } // END main
// This routine separates Benders' cuts violated by the current x solution. // Violated cuts are found by solving the worker LP // IloBool separate(const Arcs x, const IloNumArray2 xSol, IloCplex cplex, const IloNumVarArray v, const IloNumVarArray u, IloObjective obj, IloExpr cutLhs, IloNum& cutRhs) { IloBool violatedCutFound = IloFalse; IloEnv env = cplex.getEnv(); IloModel mod = cplex.getModel(); IloInt numNodes = xSol.getSize(); IloInt numArcs = numNodes * numNodes; IloInt i, j, k, h; // Update the objective function in the worker LP: // minimize sum(k in V0) sum((i,j) in A) x(i,j) * v(k,i,j) // - sum(k in V0) u(k,0) + sum(k in V0) u(k,k) mod.remove(obj); IloExpr objExpr = obj.getExpr(); objExpr.clear(); for (k = 1; k < numNodes; ++k) { for (i = 0; i < numNodes; ++i) { for (j = 0; j < numNodes; ++j) { objExpr += xSol[i][j] * v[(k-1)*numArcs + i*numNodes + j]; } } } for (k = 1; k < numNodes; ++k) { objExpr += u[(k-1)*numNodes + k]; objExpr -= u[(k-1)*numNodes]; } obj.setExpr(objExpr); mod.add(obj); objExpr.end(); // Solve the worker LP cplex.solve(); // A violated cut is available iff the solution status is Unbounded if ( cplex.getStatus() == IloAlgorithm::Unbounded ) { IloInt vNumVars = (numNodes-1) * numArcs; IloNumVarArray var(env); IloNumArray val(env); // Get the violated cut as an unbounded ray of the worker LP cplex.getRay(val, var); // Compute the cut from the unbounded ray. The cut is: // sum((i,j) in A) (sum(k in V0) v(k,i,j)) * x(i,j) >= // sum(k in V0) u(k,0) - u(k,k) cutLhs.clear(); cutRhs = 0.; for (h = 0; h < val.getSize(); ++h) { IloInt *index_p = (IloInt*) var[h].getObject(); IloInt index = *index_p; if ( index >= vNumVars ) { index -= vNumVars; k = index / numNodes + 1; i = index - (k-1)*numNodes; if ( i == 0 ) cutRhs += val[h]; else if ( i == k ) cutRhs -= val[h]; } else { k = index / numArcs + 1; i = (index - (k-1)*numArcs) / numNodes; j = index - (k-1)*numArcs - i*numNodes; cutLhs += val[h] * x[i][j]; } } var.end(); val.end(); violatedCutFound = IloTrue; } return violatedCutFound; } // END separate
// This routine set up the IloCplex algorithm to solve the worker LP, and // creates the worker LP (i.e., the dual of flow constraints and // capacity constraints of the flow MILP) // // Modeling variables: // forall k in V0, i in V: // u(k,i) = dual variable associated with flow constraint (k,i) // // forall k in V0, forall (i,j) in A: // v(k,i,j) = dual variable associated with capacity constraint (k,i,j) // // Objective: // minimize sum(k in V0) sum((i,j) in A) x(i,j) * v(k,i,j) // - sum(k in V0) u(k,0) + sum(k in V0) u(k,k) // // Constraints: // forall k in V0, forall (i,j) in A: u(k,i) - u(k,j) <= v(k,i,j) // // Nonnegativity on variables v(k,i,j) // forall k in V0, forall (i,j) in A: v(k,i,j) >= 0 // void createWorkerLP(IloCplex cplex, IloNumVarArray v, IloNumVarArray u, IloObjective obj, IloInt numNodes) { IloInt i, j, k; IloEnv env = cplex.getEnv(); IloModel mod(env, "atsp_worker"); // Set up IloCplex algorithm to solve the worker LP cplex.extract(mod); cplex.setOut(env.getNullStream()); // Turn off the presolve reductions and set the CPLEX optimizer // to solve the worker LP with primal simplex method. cplex.setParam(IloCplex::Reduce, 0); cplex.setParam(IloCplex::RootAlg, IloCplex::Primal); // Create variables v(k,i,j) forall k in V0, (i,j) in A // For simplicity, also dummy variables v(k,i,i) are created. // Those variables are fixed to 0 and do not partecipate to // the constraints. IloInt numArcs = numNodes * numNodes; IloInt vNumVars = (numNodes-1) * numArcs; IloNumVarArray vTemp(env, vNumVars, 0, IloInfinity); for (k = 1; k < numNodes; ++k) { for (i = 0; i < numNodes; ++i) { vTemp[(k-1)*numArcs + i *numNodes + i].setBounds(0, 0); } } v.clear(); v.add(vTemp); vTemp.end(); mod.add(v); // Set names for variables v(k,i,j) for (k = 1; k < numNodes; ++k) { for(i = 0; i < numNodes; ++i) { for(j = 0; j < numNodes; ++j) { char varName[100]; sprintf(varName, "v.%d.%d.%d", (int) k, (int) i, (int) j); v[(k-1)*numArcs + i*numNodes + j].setName(varName); } } } // Associate indices to variables v(k,i,j) IloIntArray vIndex(env, vNumVars); for (j = 0; j < vNumVars; ++j) { vIndex[j] = j; v[j].setObject(&vIndex[j]); } // Create variables u(k,i) forall k in V0, i in V IloInt uNumVars = (numNodes-1) * numNodes; IloNumVarArray uTemp(env, uNumVars, -IloInfinity, IloInfinity); u.clear(); u.add(uTemp); uTemp.end(); mod.add(u); // Set names for variables u(k,i) for (k = 1; k < numNodes; ++k) { for(i = 0; i < numNodes; ++i) { char varName[100]; sprintf(varName, "u.%d.%d", (int) k, (int) i); u[(k-1)*numNodes + i].setName(varName); } } // Associate indices to variables u(k,i) IloIntArray uIndex(env, uNumVars); for (j = 0; j < uNumVars; ++j) { uIndex[j] = vNumVars + j; u[j].setObject(&uIndex[j]); } // Initial objective function is empty obj.setSense(IloObjective::Minimize); mod.add(obj); // Add constraints: // forall k in V0, forall (i,j) in A: u(k,i) - u(k,j) <= v(k,i,j) for (k = 1; k < numNodes; ++k) { for(i = 0; i < numNodes; ++i) { for(j = 0; j < numNodes; ++j) { if ( i != j ) { IloExpr expr(env); expr -= v[(k-1)*numArcs + i*(numNodes) + j]; expr += u[(k-1)*numNodes + i]; expr -= u[(k-1)*numNodes + j]; mod.add(expr <= 0); expr.end(); } } } } }// END createWorkerLP
/** Separation function. * This function is invoked whenever CPLEX finds an integer feasible * solution. It then separates either feasibility or optimality cuts * on this solution. */ void BendersOpt::LazyConstraintCallback::main() { std::cout << "Callback invoked. Separate Benders cuts." << std::endl; IloNumArray x(getEnv()); IloNumArray rayVals(getEnv()); IloNumVarArray rayVars(getEnv()); IloNumArray cutVal(getEnv()); IloNumVarArray cutVar(getEnv()); getValues(x, master->vars); bool error = false; // Iterate over blocks and trigger a separation on each of them. // The separation is triggered asynchronously so that it can happen // on different remote objects simultaneously. for (BlockVector::size_type b = 0; b < blocks.size(); ++b) { Block *const block = blocks[b]; // Remove current objective from the block's model. IloModel model = block->cplex.getModel(); IloObjective obj = block->obj; model.remove(obj); IloExpr newObj = obj.getExpr(); // Iterate over the fixed master variables in this block to update // the block's objective function. // Each fixed variable goes to the right-hand side and therefore // into the objective function. for (std::vector<Block::FixData>::const_iterator it = block->fixed.begin(); it != block->fixed.end(); ++it) newObj -= block->vars[it->row] * (it->val * x[it->col]); obj.setExpr(newObj); model.add(obj); newObj.end(); // If the problem is unbounded we need to get an infinite ray in // order to be able to generate the respective Benders cut. If // CPLEX proves unboundedness in presolve then it will return // CPX_STAT_INForUNBD and no ray will be available. So we need to // disable presolve. block->cplex.setParam(IloCplex::Param::Preprocessing::Presolve, false); block->cplex.setParam(IloCplex::Param::Preprocessing::Reduce, 0); // Solve the updated problem to optimality. block->cplex.setParam(IloCplex::Param::RootAlgorithm, IloCplex::Primal); try { handles[b] = block->cplex.solve(true); } catch (...) { // If there is an exception then we need to kill and join // all remaining solves. Otherwise we may leak handles. while (--b > 0) { handles[b].kill(); handles[b].join(); } throw; } } // Wait for the various LP solves to complete. for (BlockVector::size_type b = 0; b < blocks.size(); ++b) handles[b].join(); // See if we need to generate cuts. for (BlockVector::size_type b = 0; b < blocks.size(); ++b) { Block *const block = blocks[b]; cutVal.clear(); cutVar.clear(); double cutlb = -IloInfinity; double cutub = IloInfinity; // We ust STL types here since they are exception safe. std::vector<double> tmp(master->vars.getSize(), 0); std::map<IloNumVar,double,ExtractableLess<IloNumVar> > rayMap; // Depending on the status either seperate a feasibility or an // optimality cut. switch (block->cplex.getStatus()) { case IloAlgorithm::Unbounded: { // The subproblem is unbounded. We need to extract a feasibility // cut from an unbounded ray of the problem (see also the comments // at the top of this file). std::cout << "unbounded "; block->cplex.getRay(rayVals, rayVars); cutub = 0.0; for (IloInt j = 0; j < rayVars.getSize(); ++j) { cutub -= rayVals[j] * block->objMap[rayVars[j]]; rayMap[rayVars[j]] = rayVals[j]; } for (std::vector<Block::FixData>::const_iterator it = block->fixed.begin(); it != block->fixed.end(); ++it) tmp[it->col] -= it->val * rayMap[block->vars[it->row]]; for (IloInt j = 0; j < master->vars.getSize(); ++j) { if ( fabs (tmp[j]) > 1e-6 ) { cutVar.add(master->vars[j]); cutVal.add(tmp[j]); } } } break; case IloAlgorithm::Optimal: { // The subproblem has a finite optimal solution. // We need to check if this gives rise to an optimality cut (see // also the comments at the top of this file). std::cout << "optimal "; double const objval = block->cplex.getObjValue(); double const eta = x[etaind + b]; block->cplex.getValues(block->vars, rayVals); if ( objval > eta + 1e-6 ) { cutub = 0.0; for (IloInt j = 0; j < block->vars.getSize(); ++j) cutub -= rayVals[j] * block->objMap[block->vars[j]]; for (std::vector<Block::FixData>::const_iterator it = block->fixed.begin(); it != block->fixed.end(); ++it) tmp[it->col] -= it->val * rayVals[it->row]; for (IloInt j = 0; j < master->vars.getSize(); ++j) { if ( fabs (tmp[j]) > 1e-6 ) { cutVal.add(tmp[j]); cutVar.add(master->vars[j]); } } cutVal.add(-1.0); cutVar.add(master->vars[etaind + b]); } } break; default: std::cerr << "Unexpected status " << block->cplex.getStatus() << std::endl; error = true; break; } // If a cut was found then add that. if ( cutVar.getSize() > 0 ) { IloExpr expr(master->env); for (IloInt i = 0; i < cutVar.getSize(); ++i) expr += cutVar[i] * cutVal[i]; IloRange cut(getEnv(), cutlb, expr, cutub); expr.end(); std::cout << "cut found: " << cut << std::endl; add(cut).end(); } else std::cout << "no cuts." << std::endl; } cutVar.end(); cutVal.end(); rayVars.end(); rayVals.end(); x.end(); if ( error ) throw -1; }
ILOSTLBEGIN int main(int argc, char **argv) { IloEnv env; try { IloArray<IloNumArray> distance(env); //Model Initialization IloModel model(env); //Taking Data from Distance Data File ifstream in; in.open("carpool-data.txt",ios::in); in >> distance; in.close(); cout<<distance<<endl; //2D Array for Results IloArray<IloNumArray> X_val(env, 7); for (int i = 0; i < 7; i++) { X_val[i] = IloNumArray(env,7); } IloArray<IloNumArray> Y_val(env, 7); for (int i = 0; i < 7; i++) { Y_val[i] = IloNumArray(env,7); } //2D Array for Xij IloArray<IloNumVarArray> X(env, 7); for (int i = 0; i < 7; i++) { X[i] = IloNumVarArray(env,7,0,1,ILOINT); } //2D Array for Yij IloArray<IloNumVarArray> Y(env, 7); for (int i = 0; i < 7; i++) { Y[i] = IloNumVarArray(env,7,0,1,ILOINT); } // 1D array for Ui and U-val //IloNumVarArray U(env,7,0,7,ILOINT); //IloNumArray U_val(env,7); // Defining Obj to be equal to sum-product(Dij*Xij + Dij*Yij) IloExpr Obj(env); for (int i = 0; i < 7; ++i) { for (int j = 0; j < 7; j++) { if(i != j) { Obj += distance[i][j]*X[i][j] + distance[i][j]*Y[i][j]; } } } //model.add(IloMaximize(env,Obj)); // IloMinimize is used for minimization problems //Alternatively, model.add(IloMaximize(env,Obj)); can be replaced by the following three lines. //This is useful while iterating in Decomposition Techniques where the objective function is redefined at each iteration IloObjective Objective = IloMinimize(env); model.add(Objective); Objective.setExpr(Obj); Obj.end(); //Constraints for the model //One Input per Node except Office IloExpr Input(env); for (int i = 0; i < 6; i++) { for (int j = 0; j < 7; j++) { if(i != j ) { Input += X[i][j] + Y[i][j]; } } model.add(Input == 1); } Input.end(); //One Output per Node except Office IloExpr Output(env); for (int j = 0; j < 6; j++) { for (int i = 0; i < 7; i++) { if(i != j ) { Output += X[i][j] + Y[i][j]; } } model.add(Output == 1); } Output.end(); //Ensuring 2 entries and exits for the Office node IloExpr Entryx(env); for (int i = 0; i <6; i++) { Entryx = Entryx + X[i][6]; } model.add(Entryx == 1); Entryx.end(); IloExpr Exitx(env); for (int i = 0; i <6; i++) { Exitx = Exitx + X[6][i]; } model.add(Exitx == 1); Exitx.end(); IloExpr Entryy(env); for (int i = 0; i <6; i++) { Entryy = Entryy + Y[i][6]; } model.add(Entryy == 1); Entryy.end(); IloExpr Exity(env); for (int i = 0; i <6; i++) { Exity = Exity + Y[6][i]; } model.add(Exity == 1); Exity.end(); // Optimize IloCplex cplex(model); cplex.setOut(env.getNullStream()); // if we get an empty stream in return //cplex.setWarning(env.getNullStream()); cplex.solve();//solving the MODEL //cout << "hey there I reached the breakpoint" << endl; if (cplex.getStatus() == IloAlgorithm::Infeasible) // if the problem is infeasible { env.out() << "Problem Infeasible" << endl; } for(int i = 0; i < 7 ; i++) { cplex.getValues(X_val[i], X[i]); } cout<<X_val<<endl; for(int i = 0; i < 7 ; i++) { cplex.getValues(Y_val[i], Y[i]); } cout<<Y_val<<endl; // cplex.getValues(U_val,U); // Print results cout<< "Objective Value = " << cplex.getObjValue() << endl; //cout<<"X = "<<X_val<<endl; } catch(IloException &e) { env.out() << "ERROR: " << e << endl; } catch(...) { env.out() << "Unknown exception" << endl; } env.end(); return 0; }
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; }
/** Create a new worker. * The constructor mainly does the following: * - create an IloCplex instance that refers to a remote worker, * - load the model in <code>modelfile</code>, * - setup parameters depending on this worker's index, * - start an asynchronous solve. * If anything fails then an exception will be thrown. * @param env The environment used for instantiating Ilo* objects. * @param i The index of the worker to be created. This also * determines the parameter settings to use in this worker. * @param s A pointer to the global solve state. * @param transport The transport name for the IloCplex constructor. * @param argc The argument count for the IloCplex constructor. * @param argv The array of transport arguments for the IloCplex * constructor. * @param modelfile Name of the model to be loaded into the worker. * @param output The output mode. * @param objdiff The minimal difference between so that two * consecutive objective function values are considered * different. */ Worker(IloEnv env, int i, SolveState *s, char const *transport, int argc, char const **argv, char const *modelfile, OUTPUT output, double objdiff) : idx(i), state(s), model(env), cplex(0), handle(0), primal(IloInfinity), dual(-IloInfinity), obj(env), x(env), rng(env), infoHandler(this), outb(idx), outs(&outb) { try { // Create remote object, setup output and load the model. cplex = IloCplex(model, transport, argc, argv); switch (output) { case OUTPUT_SILENT: // Disable output on the output and warning stream. cplex.setOut(env.getNullStream()); cplex.setWarning(env.getNullStream()); break; case OUTPUT_PREFIXED: // Redirect output to our custom stream. cplex.setOut(outs); cplex.setWarning(outs); break; case OUTPUT_LOG: // Nothing to do here. By default output is enabled. break; } cplex.importModel(model, modelfile, obj, x, rng); if ( obj.getSense() == IloObjective::Minimize ) { primal = -IloInfinity; dual = IloInfinity; } // We set the thread count for each solver to 1 so that we do not // run into problems if multiple solves are performed on the same // machine. cplex.setParam(IloCplex::Param::Threads, 1); // Each worker runs with a different random seed. This way we // get different paths through the tree even if the other // parameter settings are the same. cplex.setParam(IloCplex::Param::RandomSeed, idx); // Apply parameter settings. for (class ParamValue const *vals = settings[idx % NUMSETTINGS].values; vals->isValid(); ++vals) vals->apply(cplex); // Install callback and set objective change. int status = cplex.userfunction (USERACTION_ADDCALLBACK, 0, NULL, 0, 0, NULL); if ( status ) throw status; IloCplex::Serializer s; s.add(objdiff); status = cplex.userfunction (USERACTION_CHANGEOBJDIFF, s.getRawLength(), s.getRawData(), 0, 0, NULL); if ( status ) throw status; // Register the handler that will process info messages sent // from the worker. cplex.setRemoteInfoHandler(&infoHandler); // Everything is setup. Launch the asynchronous solve. handle = cplex.solve(true); } catch (...) { // In case of an exception we need to take some special // cleanup actions. Note that if we get here then the // solve cannot have been started and we don't need to // kill or join the asynchronous solve. if ( cplex.getImpl() ) cplex.end(); rng.end(); x.end(); obj.end(); model.end(); throw; } }
int main (int argc, char **argv) { int result = 0; IloEnv env; try { static int indices[] = { 0, 1, 2, 3, 4, 5, 6 }; IloModel model(env); /* ***************************************************************** * * * * S E T U P P R O B L E M * * * * The model we setup here is * * Minimize * * obj: 3x1 - x2 + 3x3 + 2x4 + x5 + 2x6 + 4x7 * * Subject To * * c1: x1 + x2 = 4 * * c2: x1 + x3 >= 3 * * c3: x6 + x7 <= 5 * * c4: -x1 + x7 >= -2 * * q1: [ -x1^2 + x2^2 ] <= 0 * * q2: [ 4.25x3^2 -2x3*x4 + 4.25x4^2 - 2x4*x5 + 4x5^2 ] + 2 x1 <= 9.0 * q3: [ x6^2 - x7^2 ] >= 4 * * Bounds * * 0 <= x1 <= 3 * * x2 Free * * 0 <= x3 <= 0.5 * * x4 Free * * x5 Free * * x7 Free * * End * * * * ***************************************************************** */ IloNumVarArray x(env); x.add(IloNumVar(env, 0, 3, "x1")); x.add(IloNumVar(env, -IloInfinity, IloInfinity, "x2")); x.add(IloNumVar(env, 0, 0.5, "x3")); x.add(IloNumVar(env, -IloInfinity, IloInfinity, "x4")); x.add(IloNumVar(env, -IloInfinity, IloInfinity, "x5")); x.add(IloNumVar(env, 0, IloInfinity, "x6")); x.add(IloNumVar(env, -IloInfinity, IloInfinity, "x7")); for (IloInt i = 0; i < x.getSize(); ++i) x[i].setObject(&indices[i]); IloObjective obj = IloMinimize(env, 3*x[0] - x[1] + 3*x[2] + 2*x[3] + x[4] + 2*x[5] + 4*x[6], "obj"); model.add(obj); IloRangeArray linear(env); linear.add(IloRange(env, 4.0, x[0] + x[1], 4.0, "c1")); linear.add(IloRange(env, 3.0, x[0] + x[2], IloInfinity, "c2")); linear.add(IloRange(env, -IloInfinity, x[5] + x[6], 5.0, "c3")); linear.add(IloRange(env, -2.0, -x[0] + x[6], IloInfinity, "c4")); for (IloInt i = 0; i < linear.getSize(); ++i) linear[i].setObject(&indices[i]); model.add(linear); IloRangeArray quad(env); quad.add(IloRange(env, -IloInfinity, -x[0]*x[0] + x[1] * x[1], 0, "q1")); quad.add(IloRange(env, -IloInfinity, 4.25*x[2]*x[2] - 2*x[2]*x[3] + 4.25*x[3]*x[3] + -2*x[3]*x[4] + 4*x[4]*x[4] + 2*x[0], 9.0, "q2")); quad.add(IloRange(env, 4.0, x[5]*x[5] - x[6]*x[6], IloInfinity, "q3")); for (IloInt i = 0; i < quad.getSize(); ++i) quad[i].setObject(&indices[i]); model.add(quad); /* ***************************************************************** * * * * O P T I M I Z E P R O B L E M * * * * ***************************************************************** */ IloCplex cplex(model); cplex.setParam(IloCplex::Param::Barrier::QCPConvergeTol, 1e-10); cplex.solve(); /* ***************************************************************** * * * * Q U E R Y S O L U T I O N * * * * ***************************************************************** */ IloNumArray xval(env); IloNumArray slack(env); IloNumArray qslack(env); IloNumArray cpi(env); IloNumArray rpi(env); IloNumArray qpi; cplex.getValues(x, xval); cplex.getSlacks(slack, linear); cplex.getSlacks(qslack, quad); cplex.getReducedCosts(cpi, x); cplex.getDuals(rpi, linear); qpi = getqconstrmultipliers(cplex, xval, quad); /* ***************************************************************** * * * * C H E C K K K T C O N D I T I O N S * * * * Here we verify that the optimal solution computed by CPLEX * * (and the qpi[] values computed above) satisfy the KKT * * conditions. * * * * ***************************************************************** */ // Primal feasibility: This example is about duals so we skip this test. // Dual feasibility: We must verify // - for <= constraints (linear or quadratic) the dual // multiplier is non-positive. // - for >= constraints (linear or quadratic) the dual // multiplier is non-negative. for (IloInt i = 0; i < linear.getSize(); ++i) { if ( linear[i].getLB() <= -IloInfinity ) { // <= constraint if ( rpi[i] > ZEROTOL ) { cerr << "Dual feasibility test failed for <= row " << i << ": " << rpi[i] << endl; result = -1; } } else if ( linear[i].getUB() >= IloInfinity ) { // >= constraint if ( rpi[i] < -ZEROTOL ) { cerr << "Dual feasibility test failed for >= row " << i << ":" << rpi[i] << endl; result = -1; } } else { // nothing to do for equality constraints } } for (IloInt q = 0; q < quad.getSize(); ++q) { if ( quad[q].getLB() <= -IloInfinity ) { // <= constraint if ( qpi[q] > ZEROTOL ) { cerr << "Dual feasibility test failed for <= quad " << q << ": " << qpi[q] << endl; result = -1; } } else if ( quad[q].getUB() >= IloInfinity ) { // >= constraint if ( qpi[q] < -ZEROTOL ) { cerr << "Dual feasibility test failed for >= quad " << q << ":" << qpi[q] << endl; result = -1; } } else { // nothing to do for equality constraints } } // Complementary slackness. // For any constraint the product of primal slack and dual multiplier // must be 0. for (IloInt i = 0; i < linear.getSize(); ++i) { if ( fabs (linear[i].getUB() - linear[i].getLB()) > ZEROTOL && fabs (slack[i] * rpi[i]) > ZEROTOL ) { cerr << "Complementary slackness test failed for row " << i << ": " << fabs (slack[i] * rpi[i]) << endl; result = -1; } } for (IloInt q = 0; q < quad.getSize(); ++q) { if ( fabs (quad[q].getUB() - quad[q].getLB()) > ZEROTOL && fabs (qslack[q] * qpi[q]) > ZEROTOL ) { cerr << "Complementary slackness test failed for quad " << q << ":" << fabs (qslack[q] * qpi[q]) << endl; result = -1; } } for (IloInt j = 0; j < x.getSize(); ++j) { if ( x[j].getUB() < IloInfinity ) { double const slk = x[j].getUB() - xval[j]; double const dual = cpi[j] < -ZEROTOL ? cpi[j] : 0.0; if ( fabs (slk * dual) > ZEROTOL ) { cerr << "Complementary slackness test failed for ub " << j << ": " << fabs (slk * dual) << endl; result = -1; } } if ( x[j].getLB() > -IloInfinity ) { double const slk = xval[j] - x[j].getLB(); double const dual = cpi[j] > ZEROTOL ? cpi[j] : 0.0; if ( fabs (slk * dual) > ZEROTOL ) { cerr << "Complementary slackness test failed for lb " << j << ": " << fabs (slk * dual) << endl; result = -1; } } } // Stationarity. // The difference between objective function and gradient at optimal // solution multiplied by dual multipliers must be 0, i.e., for the // optimal solution x // 0 == c // - sum(r in rows) r'(x)*rpi[r] // - sum(q in quads) q'(x)*qpi[q] // - sum(c in cols) b'(x)*cpi[c] // where r' and q' are the derivatives of a row or quadratic constraint, // x is the optimal solution and rpi[r] and qpi[q] are the dual // multipliers for row r and quadratic constraint q. // b' is the derivative of a bound constraint and cpi[c] the dual bound // multiplier for column c. IloNumArray kktsum(env, x.getSize()); // Objective function. for (IloExpr::LinearIterator it = obj.getLinearIterator(); it.ok(); ++it) kktsum[idx(it.getVar())] = it.getCoef(); // Linear constraints. // The derivative of a linear constraint ax - b (<)= 0 is just a. for (IloInt i = 0; i < linear.getSize(); ++i) { for (IloExpr::LinearIterator it = linear[i].getLinearIterator(); it.ok(); ++it) kktsum[idx(it.getVar())] -= rpi[i] * it.getCoef(); } // Quadratic constraints. // The derivative of a constraint xQx + ax - b <= 0 is // Qx + Q'x + a. for (IloInt q = 0; q < quad.getSize(); ++q) { for (IloExpr::LinearIterator it = quad[q].getLinearIterator(); it.ok(); ++it) kktsum[idx(it.getVar())] -= qpi[q] * it.getCoef(); for (IloExpr::QuadIterator it = quad[q].getQuadIterator(); it.ok(); ++it) { kktsum[idx(it.getVar1())] -= qpi[q] * xval[idx(it.getVar2())] * it.getCoef(); kktsum[idx(it.getVar2())] -= qpi[q] * xval[idx(it.getVar1())] * it.getCoef(); } } // Bounds. // The derivative for lower bounds is -1 and that for upper bounds // is 1. // CPLEX already returns dj with the appropriate sign so there is // no need to distinguish between different bound types here. for (IloInt j = 0; j < x.getSize(); ++j) kktsum[j] -= cpi[j]; for (IloInt j = 0; j < kktsum.getSize(); ++j) { if ( fabs (kktsum[j]) > ZEROTOL ) { cerr << "Stationarity test failed at index " << j << ": " << kktsum[j] << endl; result = -1; } } if ( result == 0) { // KKT conditions satisfied. Dump out the optimal solutions and // the dual values. streamsize oprec = cout.precision(3); ios_base::fmtflags oflags = cout.setf(ios::fixed | ios::showpos); cout << "Optimal solution satisfies KKT conditions." << endl; cout << " x[] = " << xval << endl; cout << " cpi[] = " << cpi << endl; cout << " rpi[] = " << rpi << endl; cout << " qpi[] = " << qpi << endl; cout.precision(oprec); cout.flags(oflags); } } catch (IloException& e) { cerr << "Concert exception caught: " << e << endl; result = -1; } catch (...) { cerr << "Unknown exception caught" << endl; result = -1; } env.end(); return result; } // END main
void Instance::optKara2007() { CPUTimer t; t.start(); int size = Gifts.size(); double totalWeight = 0; for (int i = 0; i < (int)Gifts.size(); i++) { totalWeight += Gifts[i].weight; } cout << "Optimizing Instance by Kara2007 Two-Index One-Commodity Flow Integer Model to CPLEX..." << endl; cout << "Number of Gifts:\t" << size << endl; vector<vector<double> > c(size+1); for (int i = 0; i < size+1; i++) { c[i].resize(size+1); } for (int i = 0; i < size+1; i++) { for (int j = i+1; j < size+1; j++) { c[i][j] = getDistance(getGiftId(i), getGiftId(j)); c[j][i] = c[i][j]; } } IloEnv env; IloModel model(env); IloObjective obj = IloMinimize(env); NumVarMatrix var_x(env); NumVarMatrix var_f(env); string varName; string consName; for (int i = 0; i < size+1; i++) { var_x.add(IloNumVarArray(env)); var_f.add(IloNumVarArray(env)); } varName = "K"; IloNumVar var_K(env, 1, size, IloNumVar::Int, (char*)varName.c_str()); for (int i = 0; i < size+1; i++) { for (int j = 0; j < size+1; j++) { varName = "x" + to_string(getGiftId(i)) + "_" + to_string(getGiftId(j)); var_x[i].add( IloNumVar(env, 0, 1, IloNumVar::Int, (char*)varName.c_str()) ); varName = "f" + to_string(getGiftId(i)) + "_" + to_string(getGiftId(j)); var_f[i].add( IloNumVar(env, 0, 1010, IloNumVar::Float, (char*)varName.c_str()) ); } } for (int i = 0; i < size+1; i++) { for (int j = 0; j < size+1; j++) { obj.setLinearCoef(var_x[i][j], 10*c[i][j]); obj.setLinearCoef(var_f[i][j], c[i][j]); } } model.add(obj); //numeracao segundo Fukasawa 2015 // (1a) - tudo que sai de todo i for (int i = 0; i < size; i++) { consName = "c1a_" + to_string(getGiftId(i)); IloRange c1a(env, 1, 1, (char*)consName.c_str()); for (int j = 0; j < size+1; j++) { if (c[i][j] > 0) { c1a.setLinearCoef(var_x[i][j], 1); } } model.add(c1a); } // (1b) - tudo que entra em todo i for (int i = 0; i < size; i++) { consName = "c1b_" + to_string(getGiftId(i)); IloRange c1b( env, 1, 1, (char*)consName.c_str() ); for (int j = 0; j < size+1; j++) { if (c[i][j] > 0) { c1b.setLinearCoef(var_x[j][i], 1); } } model.add(c1b); } //(1c) ensures that q_i units are delivered //tudo que sai de i deve ser menor w_i de tudo que entra for (int i = 0; i < size; i++) { consName = "c1c_" + to_string(getGiftId(i)); IloRange c1c( env, getWeight(i), getWeight(i), (char*)consName.c_str() ); for (int j = 0; j < size+1; j++) { if (c[j][i] > 0) //tudo que entra { c1c.setLinearCoef(var_f[j][i], 1); } if (c[i][j] > 0) //tudo que sai { c1c.setLinearCoef(var_f[i][j], -1); } } model.add(c1c); } consName = "c1c_0"; IloRange c1c( env, totalWeight, totalWeight, (char*)consName.c_str() ); for (int j = 0; j < size; j++) { if (c[size][j] > 0) { c1c.setLinearCoef(var_f[size][j], 1); } if (c[j][size] > 0) { c1c.setLinearCoef(var_f[j][size], -1); } } model.add(c1c); //(1d) f bounds for (int i = 0; i < size+1; i++) { for (int j = 0; j < size+1; j++) { if (c[i][j] > 0) { model.add(IloConstraint( getWeight(j)* var_x[i][j] <= var_f[i][j] )); //o que entra em j deve pelo menos carregar o peso de j model.add(IloConstraint( var_f[i][j] <= (totalWeight - getWeight(i)) * var_x[i][j] )); //o que sai de i nao pode carregar o peso de i } } } // (1e) - tudo que entra em 0 consName = "c1e_in"; IloRange c1e_in( env, 0, 0, (char*)consName.c_str() ); consName = "c1e_out"; IloRange c1e_out( env, 0, 0, (char*)consName.c_str() ); c1e_in.setLinearCoef(var_K, -1); c1e_out.setLinearCoef(var_K, -1); for (int i = 0; i < size; i++) { if (c[i][size] > 0) { c1e_in.setLinearCoef(var_x[i][size], 1); } if (c[size][i] > 0) { c1e_out.setLinearCoef(var_x[size][i], 1); } } model.add(c1e_in); model.add(c1e_out); IloCplex cplex(model); #ifdef _WIN32 cplex.setParam(IloCplex::Threads,1); //cplex.setParam(IloCplex::TiLim,10); //cplex.setParam(IloCplex::VarSel,3); #else //cplex.setParam(IloCplex::TiLim,60); #endif cplex.setParam(IloCplex::CutUp, 13632670.39); try { cplex.exportModel("trip_kara2007.lp"); } catch (IloException e) { cerr << e; } try { if ( cplex.solve() ) { cout << "Solution status = " << cplex.getStatus() << endl; double objValue = cplex.getObjValue(); cout << "Best Solution Found:\t" << setprecision(17) << objValue << endl; cout << "Num Trips:\t" << setprecision(17) << cplex.getValue(var_K) << endl; vector<vector<int> > adjacencyMatrix (size+1); for (int i = 0; i < size+1; i++) { adjacencyMatrix[i].resize(size + 1); } for (int i = 0; i < size+1; i++) { for (int j = 0; j < size+1; j++) { if (c[i][j] > 0) { double val = cplex.getValue(var_x[i][j]); double valf = cplex.getValue(var_f[i][j]); if (val != 0) { cout << var_x[i][j].getName() << ": " << val << endl; cout << var_f[i][j].getName() << ": " << valf << endl; adjacencyMatrix[i][j] = 1; //adjacencyMatrix[j][i] = 1; } } } } vector<bool> visited(size+1); //starts at north pole visited[size] = true; int last = size; /*Trip Kara_Trip(); while (Kara_Trip.getSize() < size) { for (int j = 0; j < size+1; j++) { if ( ( adjacencyMatrix[last][j] == 1) && (!visited[j] ) ) { visited[j] = true; Kara_Trip.appendGift(inst, Gifts[j-1]); last = j; break; } } } cout << "OriginalTripCost:\t" << std::setprecision(17) << getCost() << endl; cout << "OptimalKaraTripCost:\t" << std::setprecision(17) << Kara_Trip.getCost() << endl;*/ } } catch (IloException e) { cerr << e; } env.end(); }
/** Get the objective sense for this worker's objective. */ IloObjective::Sense getObjectiveSense() const { return obj.getSense(); }
int main (int argc, char **argv) { IloEnv env; try { IloModel model(env); IloCplex cplex(env); IloBool useLoggingCallback = IloFalse; IloBool useTimeLimitCallback = IloFalse; IloBool useAborter = IloFalse; if (( argc != 3 ) || ( strchr ("lat", argv[2][0]) == NULL ) ) { usage (argv[0]); throw(-1); } switch (argv[2][0]) { case 'l': useLoggingCallback = IloTrue; break; case 't': useTimeLimitCallback = IloTrue; break; case 'a': useAborter = IloTrue; break; default: break; } IloObjective obj; IloNumVarArray var(env); IloRangeArray rng(env); IloSOS1Array sos1(env); IloSOS2Array sos2(env); IloRangeArray lazy(env); IloRangeArray cuts(env); IloCplex::Aborter myAborter; cplex.importModel(model, argv[1], obj, var, rng, sos1, sos2, lazy, cuts); cplex.extract(model); if ( lazy.getSize() > 0 ) cplex.addLazyConstraints (lazy); if ( cuts.getSize() > 0 ) cplex.addUserCuts (cuts); if ( useLoggingCallback ) { // Set an overall node limit in case callback conditions // are not met. cplex.setParam(IloCplex::Param::MIP::Limits::Nodes, 5000); IloNum lastObjVal = (obj.getSense() == IloObjective::Minimize ) ? IloInfinity : -IloInfinity; cplex.use(loggingCallback(env, var, -100000, lastObjVal, cplex.getCplexTime(), cplex.getDetTime())); // Turn off CPLEX logging cplex.setParam(IloCplex::Param::MIP::Display, 0); } else if ( useTimeLimitCallback ) { cplex.use(timeLimitCallback(env, cplex, IloFalse, cplex.getCplexTime(), 1.0, 10.0)); } else if ( useAborter ) { myAborter = IloCplex::Aborter(env); cplex.use(myAborter); // Typically, you would pass the Aborter object to // another thread or pass it to an interrupt handler, // and monitor for some event to occur. When it does, // call the Aborter's abort method. // // To illustrate its use without creating a thread or // an interrupt handler, abort immediately by calling // abort before the solve. // myAborter.abort(); } cplex.solve(); env.out() << endl; env.out() << "Solution status = " << cplex.getStatus() << endl; env.out() << "CPLEX status = " << cplex.getCplexStatus() << endl; } catch (IloException& e) { cerr << "Concert exception caught: " << e << endl; } catch (...) { cerr << "Unknown exception caught" << endl; } env.end(); return 0; } // END main
// Test KKT conditions on the solution. // The function returns true if the tested KKT conditions are satisfied // and false otherwise. // The function assumes that the model currently extracted to CPLEX is fully // described by obj, vars and rngs. static bool checkkkt (IloCplex& cplex, IloObjective const& obj, IloNumVarArray const& vars, IloRangeArray const& rngs, IloIntArray const& cone, double tol) { IloEnv env = cplex.getEnv(); IloModel model = cplex.getModel(); IloNumArray x(env), dslack(env); IloNumArray pi(env, rngs.getSize()), slack(env); // Read primal and dual solution information. cplex.getValues(x, vars); cplex.getSlacks(slack, rngs); // pi for second order cone constraints. getsocpconstrmultipliers(cplex, vars, rngs, pi, dslack); // pi for linear constraints. for (IloInt i = 0; i < rngs.getSize(); ++i) { IloRange r = rngs[i]; if ( !r.getQuadIterator().ok() ) pi[idx(r)] = cplex.getDual(r); } // Print out the data we just fetched. streamsize oprec = env.out().precision(3); ios_base::fmtflags oflags = env.out().setf(ios::fixed | ios::showpos); env.out() << "x = ["; for (IloInt i = 0; i < x.getSize(); ++i) env.out() << " " << x[i]; env.out() << " ]" << endl; env.out() << "dslack = ["; for (IloInt i = 0; i < dslack.getSize(); ++i) env.out() << " " << dslack[i]; env.out() << " ]" << endl; env.out() << "pi = ["; for (IloInt i = 0; i < rngs.getSize(); ++i) env.out() << " " << pi[i]; env.out() << " ]" << endl; env.out() << "slack = ["; for (IloInt i = 0; i < rngs.getSize(); ++i) env.out() << " " << slack[i]; env.out() << " ]" << endl; env.out().precision(oprec); env.out().flags(oflags); // Test primal feasibility. // This example illustrates the use of dual vectors returned by CPLEX // to verify dual feasibility, so we do not test primal feasibility // here. // Test dual feasibility. // We must have // - for all <= constraints the respective pi value is non-negative, // - for all >= constraints the respective pi value is non-positive, // - the dslack value for all non-cone variables must be non-negative. // Note that we do not support ranged constraints here. for (IloInt i = 0; i < vars.getSize(); ++i) { IloNumVar v = vars[i]; if ( cone[i] == NOT_IN_CONE && dslack[i] < -tol ) { env.error() << "Dual multiplier for " << v << " is not feasible: " << dslack[i] << endl; return false; } } for (IloInt i = 0; i < rngs.getSize(); ++i) { IloRange r = rngs[i]; if ( fabs (r.getLB() - r.getUB()) <= tol ) { // Nothing to check for equality constraints. } else if ( r.getLB() > -IloInfinity && pi[i] > tol ) { env.error() << "Dual multiplier " << pi[i] << " for >= constraint" << endl << r << endl << "not feasible" << endl; return false; } else if ( r.getUB() < IloInfinity && pi[i] < -tol ) { env.error() << "Dual multiplier " << pi[i] << " for <= constraint" << endl << r << endl << "not feasible" << endl; return false; } } // Test complementary slackness. // For each constraint either the constraint must have zero slack or // the dual multiplier for the constraint must be 0. We must also // consider the special case in which a variable is not explicitly // contained in a second order cone constraint. for (IloInt i = 0; i < vars.getSize(); ++i) { if ( cone[i] == NOT_IN_CONE ) { if ( fabs(x[i]) > tol && dslack[i] > tol ) { env.error() << "Invalid complementary slackness for " << vars[i] << ":" << endl << " " << x[i] << " and " << dslack[i] << endl; return false; } } } for (IloInt i = 0; i < rngs.getSize(); ++i) { if ( fabs(slack[i]) > tol && fabs(pi[i]) > tol ) { env.error() << "Invalid complementary slackness for " << endl << rngs[i] << ":" << endl << " " << slack[i] << " and " << pi[i] << endl; return false; } } // Test stationarity. // We must have // c - g[i]'(X)*pi[i] = 0 // where c is the objective function, g[i] is the i-th constraint of the // problem, g[i]'(x) is the derivate of g[i] with respect to x and X is the // optimal solution. // We need to distinguish the following cases: // - linear constraints g(x) = ax - b. The derivative of such a // constraint is g'(x) = a. // - second order constraints g(x[1],...,x[n]) = -x[1] + |(x[2],...,x[n])| // the derivative of such a constraint is // g'(x) = (-1, x[2]/|(x[2],...,x[n])|, ..., x[n]/|(x[2],...,x[n])| // (here |.| denotes the Euclidean norm). // - bound constraints g(x) = -x for variables that are not explicitly // contained in any second order cone constraint. The derivative for // such a constraint is g'(x) = -1. // Note that it may happen that the derivative of a second order cone // constraint is not defined at the optimal solution X (this happens if // X=0). In this case we just skip the stationarity test. IloNumArray sum(env, vars.getSize()); for (IloExpr::LinearIterator it = obj.getLinearIterator(); it.ok(); ++it) sum[idx(it.getVar())] = it.getCoef(); for (IloInt i = 0; i < vars.getSize(); ++i) { IloNumVar v = vars[i]; if ( cone[i] == NOT_IN_CONE ) sum[i] -= dslack[i]; } for (IloInt i = 0; i < rngs.getSize(); ++i) { IloRange r = rngs[i]; if ( r.getQuadIterator().ok() ) { // Quadratic (second order cone) constraint. IloNum norm = 0.0; for (IloExpr::QuadIterator q = r.getQuadIterator(); q.ok(); ++q) { if ( q.getCoef() > 0 ) norm += x[idx(q.getVar1())] * x[idx(q.getVar1())]; } norm = sqrt(norm); if ( fabs(norm) <= tol ) { // Derivative is not defined. Skip test. env.warning() << "Cannot test stationarity at non-differentiable point." << endl; return true; } else { for (IloExpr::QuadIterator q = r.getQuadIterator(); q.ok(); ++q) { if ( q.getCoef() < 0 ) sum[idx(q.getVar1())] -= pi[i]; else sum[idx(q.getVar1())] += pi[i] * x[idx(q.getVar1())] / norm; } } } else { // Linear constraint. for (IloExpr::LinearIterator l = r.getLinearIterator(); l.ok(); ++l) sum[idx(l.getVar())] -= pi[i] * l.getCoef(); } } // Now test that all elements in sum[] are 0. for (IloInt i = 0; i < vars.getSize(); ++i) { if ( fabs(sum[i]) > tol ) { env.error() << "Invalid stationarity " << sum[i] << " for " << vars[i] << endl; return false; } } return true; }
/** Create the dual of a linear program. * The function can only dualize programs of the form * <code>Ax <= b, x >= 0</code>. The data in <code>primalVars</code> and * <code>dualRows</code> as well as in <code>primalRows</code> and * <code>dualVars</code> is in 1-to-1-correspondence. * @param primalObj Objective function of primal problem. * @param primalVars Variables in primal problem. * @param primalRows Rows in primal problem. * @param dualObj Objective function of dual will be stored here. * @param dualVars All dual variables will be stored here. * @param dualRows All dual rows will be stored here. */ void BendersOpt::makeDual(IloObjective const &primalObj, IloNumVarArray const &primalVars, IloRangeArray const &primalRows, IloObjective *dualObj, IloNumVarArray *dualVars, IloRangeArray *dualRows) { // To keep the code simple we only support problems // of the form Ax <= b, b >= 0 here. We leave it as a reader's // exercise to extend the function to something that can handle // any kind of linear model. for (IloInt j = 0; j < primalVars.getSize(); ++j) if ( primalVars[j].getLB() != 0 || primalVars[j].getUB() < IloInfinity ) { std::stringstream s; s << "Cannot dualize variable " << primalVars[j]; throw s.str(); } for (IloInt i = 0; i < primalRows.getSize(); ++i) if ( primalRows[i].getLB() > -IloInfinity || primalRows[i].getUB() >= IloInfinity ) { std::stringstream s; s << "Cannot dualize constraint " << primalRows[i]; std::cerr << s.str() << std::endl; throw s.str(); } // The dual of // min/max c^T x // Ax <= b // x >= 0 // is // max/min y^T b // y^T A <= c // y <= 0 // We scale y by -1 to get >= 0 IloEnv env = primalVars.getEnv(); IloObjective obj(env, 0.0, primalObj.getSense() == IloObjective::Minimize ? IloObjective::Maximize : IloObjective::Minimize); IloRangeArray rows(env); IloNumVarArray y(env); std::map<IloNumVar,IloInt,ExtractableLess<IloNumVar> > v2i; for (IloInt j = 0; j < primalVars.getSize(); ++j) { IloNumVar x = primalVars[j]; v2i.insert(std::map<IloNumVar,IloInt,ExtractableLess<IloNumVar> >::value_type(x, j)); rows.add(IloRange(env, -IloInfinity, 0, x.getName())); } for (IloExpr::LinearIterator it = primalObj.getLinearIterator(); it.ok(); ++it) rows[v2i[it.getVar()]].setUB(it.getCoef()); for (IloInt i = 0; i < primalRows.getSize(); ++i) { IloRange r = primalRows[i]; IloNumColumn col(env); col += obj(-r.getUB()); for (IloExpr::LinearIterator it = r.getLinearIterator(); it.ok(); ++it) col += rows[v2i[it.getVar()]](-it.getCoef()); y.add(IloNumVar(col, 0, IloInfinity, IloNumVar::Float, r.getName())); } *dualObj = obj; *dualVars = y; *dualRows = rows; }
void BNC::buildModelCF(){ env = new IloEnv; model = new IloModel(*env); variables = new IloNumVarArray(*env); constraints = new IloRangeArray(*env); list< list<int> > cliques; int count_chose = 0; bool chose_edge[n][n]; for( int i = 0; i < n; ++i ) for( int j = 0; j < n; ++j ) chose_edge[i][j] = false; while( count_chose < m ){ list<int> current_clique; //choose a initial node for( int i = 0; i < n; ++i ){ for( int j = 0; j < n; ++j ){ if( graph[i][j] ){ if( !chose_edge[i][j] ){ chose_edge[i][j] = chose_edge[j][i] = true; ++count_chose; current_clique.push_back(i); current_clique.push_back(j); goto done; } } } } done: //build a clique int i = current_clique.front(); for( int j = 0; j < n; ++j ){ if( graph[i][j] ){ if( !chose_edge[i][j] ){ bool add_node = true; list<int>::iterator it = current_clique.begin(); while( it != current_clique.end() ){ if( !graph[*it][j] ){ add_node = false; break; } ++it; } if( add_node ){ { list<int>::iterator it = current_clique.begin(); while( it != current_clique.end() ){ if( !chose_edge[*it][j] ) ++count_chose; chose_edge[*it][j] = chose_edge[j][*it] = true; ++it; } } current_clique.push_back(j); } } } } cliques.push_back( current_clique ); } //create variables for( int i = 0; i < n; ++i ){ variables->add( IloIntVar( *env, 0, 1 ) ); variables->add( IloIntVar( *env, 0, 1 ) ); } list< list<int> >::iterator it1 = cliques.begin(); while( it1 != cliques.end() ){ list<int>::iterator it2 = it1->begin(); IloRange newconstraintA( *env, 0, 1 ); IloRange newconstraintB( *env, 0, 1 ); while( it2 != it1->end() ){ newconstraintA.setLinearCoef( (*variables)[*it2], 1 ); newconstraintB.setLinearCoef( (*variables)[n+*it2], 1 ); ++it2; } constraints->add( newconstraintA ); constraints->add( newconstraintB ); ++it1; } for( int i = 0; i < n; ++i ){ IloRange newconstraintAB( *env, 0, 1 ); newconstraintAB.setLinearCoef( (*variables)[i], 1 ); newconstraintAB.setLinearCoef( (*variables)[n+i], 1 ); constraints->add( newconstraintAB ); } //objective function IloObjective obj = IloMaximize(*env); //objective for( int i = 0 ; i < n; i++ ){ obj.setLinearCoef((*variables)[i], 1 ); obj.setLinearCoef((*variables)[n+i], 1 ); } model->add( *constraints ); model->add( obj ); cplex = new IloCplex(*model); configureCPLEX(); //write model in file cplexmodel.lp cplex->exportModel("cplexmodel.lp"); }
int SolveLpByRuleGeneral(const RULES InputRule, const std::vector<REQ> &Request, const std::vector<DAY> &Day, const std::vector<AIRLINE> &AirLine, std::vector<CAPCONSTRAIN> &CapCon, std::vector<double> &SolVal) { try{ ofstream CheckSolStatus; CheckSolStatus.open("..//OutPut//CplexSatus.txt", ios::trunc); IloBool SolErr= 0; double CurrentProportionEps; if (isIterativeReduceEps) { CurrentProportionEps = StartingProptionEps; } else { CurrentProportionEps = ProportionFairEps; } std::vector<int> ReqSecq2Var;//map Request sequence to variable location std::vector<int> Var2ReqSecq;// revers map Var to request sequence std::vector<int> ReqSecq2ID; // map request sequence to request ID std::vector<int> ReqSecq2DumVar; // map request to dummy variable locations std::vector<int> ID2ReqSecq(Request.size(), InvalidInt);// map request ID to reqeuset secquence std::vector<int> Rio2AirLine;// int NumActRow = 0; int NumVar = getNumVar(InputRule, Request, ReqSecq2Var, Var2ReqSecq, ReqSecq2ID, ID2ReqSecq, ReqSecq2DumVar); int NumAirLineByRule = getAirNumVar(InputRule, AirLine, Rio2AirLine); assert(NumVar > 0); assert(NumAirLineByRule > 0); int Pos; double obj = 0.0; IloEnv env; /***********create variable***************/ IloNumVarArray Xmt(env, NumVar, 0, 1, ILOINT); //IloNumVar DummyTotalObj(env); //IloNumVarArray Xmt(env, NumVar, 0, 1, ILOFLOAT); IloModel LpModel(env); IloExpr TotalDispExp(env); IloExpr WeightedTotalDispExp(env); IloExpr FairObjExp(env); IloExprArray GainEpr(env, Rio2AirLine.size()), LossEpr(env, Rio2AirLine.size()); for (int i = 0; i < Rio2AirLine.size(); i++) { GainEpr[i] = IloExpr(env); LossEpr[i] = IloExpr(env); } /***********Add objective Function***************/ //setDispObj(InputRule, env, LpModel, DummyDisplaceObj, Xmt, Rio2AirLine, Request, AirLine, ID2ReqSecq, ReqSecq2Var, ReqSecq2DumVar); getDispExps(InputRule, env, LpModel, TotalDispExp, WeightedTotalDispExp, Xmt, Rio2AirLine, Request, AirLine, ID2ReqSecq, ReqSecq2Var, ReqSecq2DumVar); //LpModel.add(DummyTotalObj >= TotalDispExp); IloObjective OBJ = IloMinimize(env); //set displacement objective if (DispObj == Disp) { OBJ.setExpr(TotalDispExp); //OBJ.setExpr(DummyTotalObj); } if (DispObj == WeightDisp) { OBJ.setExpr(WeightedTotalDispExp); } LpModel.add(OBJ); /***********Add definational constraints***************/ setDefCon(InputRule, env, LpModel, Xmt, Request, ReqSecq2Var, ID2ReqSecq, ReqSecq2DumVar); /***********Solve the cplex model***************/ IloCplex cplex(env); cplex.setOut(env.getNullStream()); #ifdef DEBUG cplex.setOut(CplexLog); #endif cplex.setParam(IloCplex::Param::TimeLimit, CplexMaxCpuTime); //cplex.setParam(IloCplex::Param::MIP::Tolerances::MIPGap, CplexRelGap); /*if (FairObj!=NoFair) cplex.setParam(IloCplex::Param::MIP::Tolerances::MIPGap, CplexRelGap);*/ cplex.extract(LpModel); SolErr = cplex.solve(); CheckSolStatus << cplex.getCplexStatus() << "\t" << SolErr << "\t" << cplex.getMIPRelativeGap() << "\t" << cplex.getCplexTime() << endl; //cout << "obj = "<<cplex.getObjValue() << endl; /***********Add violated constraints***************/ IloExprArray NewCons(env); addVioCapConByDay(InputRule, env, LpModel, cplex, NewCons, Xmt, CapCon, Request, Day, ReqSecq2Var, ID2ReqSecq); addTurnRoundCon(InputRule, env, LpModel, cplex, NewCons, Xmt, Request, ReqSecq2Var, ID2ReqSecq); while (NewCons.getSize() > 0) { for (int i = 0; i < NewCons.getSize(); i++) { LpModel.add(NewCons[i]); } NumActRow += (int)NewCons.getSize(); cplex.extract(LpModel); SolErr = cplex.solve(); CheckSolStatus << cplex.getCplexStatus() << "\t" << SolErr <<"\t"<<cplex.getMIPRelativeGap()<<"\t"<<cplex.getCplexTime()<<endl; //printf("disp = %f \n", cplex.getValue(TotalDispExp)); //if (FairObj == EnvyFun) //{ // printf("disp = %f \n", cplex.getValue(DummyDisplaceObj)); // printf("envy obj = %f \n", cplex.getValue(FairObjExp)); //} NewCons.clear(); addVioCapConByDay(InputRule, env, LpModel, cplex, NewCons, Xmt, CapCon, Request, Day, ReqSecq2Var, ID2ReqSecq); addTurnRoundCon(InputRule, env, LpModel, cplex, NewCons, Xmt, Request, ReqSecq2Var, ID2ReqSecq); } #ifdef DEBUG cout << "Dummy displacment obj ="<<cplex.getValue(TotalDispExp) <<" expre value"<<cplex.getValue(TotalDispExp)<< endl; #endif if (FairObj == EnvyFun){ BiObj: LpModel.remove(OBJ); GetEnvyLossAndGainExp(InputRule, env, LpModel, GainEpr, LossEpr, Xmt, Rio2AirLine, Request, AirLine, ID2ReqSecq, ReqSecq2Var, ReqSecq2DumVar); FairObjExp.clear(); for (int i = 0; i < Rio2AirLine.size(); i++) { FairObjExp += EnvyGainWeight*GainEpr[i] + EnvyLossWeight*LossEpr[i]; } OBJ.setExpr(EnvyFairWeight*FairObjExp + TotalDispExp); LpModel.add(OBJ); cplex.extract(LpModel); SolErr = cplex.solve(); //CheckSolStatus << cplex.getCplexStatus() << "\t" << SolErr << endl; //printf("disp = %f \n", cplex.getValue(TotalDispExp)); //printf("envy obj = %f \n", cplex.getValue(FairObjExp)); //GetEnvyLossAndGainValue(InputRule, env, LpModel, cplex, Xmt, Rio2AirLine, Request, AirLine, ID2ReqSecq, ReqSecq2Var, ReqSecq2DumVar); //for (int i = 0; i < Rio2AirLine.size(); i++) //{ // //LogMsg("gain = %f, loss = %f \n", cplex.getValue(Gain[i]), cplex.getValue(Loss[i])); // LogMsg("gain = %f, loss = %f \n", cplex.getValue(GainEpr[i]), cplex.getValue(LossEpr[i])); //} NewCons.clear(); addVioCapConByDay(InputRule, env, LpModel, cplex, NewCons, Xmt, CapCon, Request, Day, ReqSecq2Var, ID2ReqSecq); addTurnRoundCon(InputRule, env, LpModel, cplex, NewCons, Xmt, Request, ReqSecq2Var, ID2ReqSecq); while (NewCons.getSize() > 0) { for (int i = 0; i < NewCons.getSize(); i++) { LpModel.add(NewCons[i]); } NumActRow += (int)NewCons.getSize(); cplex.extract(LpModel); SolErr = cplex.solve(); CheckSolStatus << cplex.getCplexStatus() << "\t" << SolErr << "\t" << cplex.getMIPRelativeGap() << "\t" << cplex.getCplexTime() << endl; printf("disp = %f \n", cplex.getValue(TotalDispExp)); printf("envy obj = %f \n", cplex.getValue(FairObjExp)); NewCons.clear(); addVioCapConByDay(InputRule, env, LpModel, cplex, NewCons, Xmt, CapCon, Request, Day, ReqSecq2Var, ID2ReqSecq); addTurnRoundCon(InputRule, env, LpModel, cplex, NewCons, Xmt, Request, ReqSecq2Var, ID2ReqSecq); } if (SolErr == 0) {// resolve displcement first LpModel.remove(OBJ); OBJ.setExpr(TotalDispExp); LpModel.add(OBJ); cplex.extract(LpModel); SolErr = cplex.solve(); CheckSolStatus << cplex.getCplexStatus() << "\t" << SolErr << "\t" << cplex.getMIPRelativeGap() << "\t" << cplex.getCplexTime() << endl; cout << "reinitialize is called" << endl; if (SolErr == 0) { cout << "Resolve falils" << endl; system("Pause"); } else { goto BiObj; } } } AddFairEpsConstraint: int totalFairConstraint = 0; if (ProportionFairEps>MyZero&&EpsCon != NoEps) { NewCons.clear(); addEpsConstraint(InputRule, env, LpModel, Xmt, cplex, NewCons, Rio2AirLine, Request, AirLine, ID2ReqSecq, ReqSecq2Var, ReqSecq2DumVar, CurrentProportionEps); totalFairConstraint += (int)NewCons.getSize(); while (NewCons.getSize() > 0) { for (int i = 0; i < NewCons.getSize(); i++) { LpModel.add(NewCons[i]); } NumActRow += (int)NewCons.getSize(); cplex.extract(LpModel); SolErr = cplex.solve(); CheckSolStatus << cplex.getCplexStatus() << "\t" << SolErr << "\t" << cplex.getMIPRelativeGap() << "\t" << cplex.getCplexTime() << endl; //#ifdef DEBUG //cout << "Dummy displacment obj ="<<cplex.getValue(DummyDisplaceObj) <<" expre value"<<cplex.getValue(TotalDispExp)<< endl; //cout << "Total fair constraint added is " << totalFairConstraint << "; Obj = " <<cplex.getObjValue() << endl; //#endif // DEBUG NewCons.clear(); //addFairConstraints(InputRule, env, LpModel, DummyDisplaceObj, Xmt, cplex, NewCons, Rio2AirLine, Request, AirLine, ID2ReqSecq, ReqSecq2Var, ReqSecq2DumVar); addEpsConstraint(InputRule, env, LpModel, Xmt, cplex, NewCons, Rio2AirLine, Request, AirLine, ID2ReqSecq, ReqSecq2Var, ReqSecq2DumVar, CurrentProportionEps); totalFairConstraint += (int)NewCons.getSize(); //addAbsFairnessConstraint(InputRule, env, LpModel, DummyDisplaceObj, Xmt, cplex, NewCons, Rio2AirLine, Request, AirLine, ID2ReqSecq, ReqSecq2Var, ReqSecq2DumVar); addVioCapConByDay(InputRule, env, LpModel, cplex, NewCons, Xmt, CapCon, Request, Day, ReqSecq2Var, ID2ReqSecq); addTurnRoundCon(InputRule, env, LpModel, cplex, NewCons, Xmt, Request, ReqSecq2Var, ID2ReqSecq); } } // iterative add eps constraints if (CurrentProportionEps > ProportionFairEps && (ProportionFairEps > MyZero) && EpsCon != NoEps) { if (isIterativeReduceEps) { CurrentProportionEps = std::max(CurrentProportionEps - 0.1, ProportionFairEps); goto AddFairEpsConstraint; } } if (isSolveByRule) UpdateCapConByDay(InputRule, cplex, Xmt, CapCon, Request, Day, ReqSecq2Var, ID2ReqSecq); //compute for the weighted //set SolValue for (auto r = Request.begin(); r != Request.end(); r++) { if (isSolveByRule) { if (r->Rule != InputRule) continue; } for (int t = 0; t < NT; t++) { Pos = ReqSecq2Var[ID2ReqSecq[r->ID]] + t; SolVal[r->ID*NT + t] = cplex.getValue(Xmt[Pos]); } if (isIngoreDummy) continue; SolVal[Request.size()*NT + r->ID] = cplex.getValue(Xmt[ReqSecq2DumVar[ID2ReqSecq[r->ID]]]); } TestCaseSum.back().NumRowGenByRule[InputRule] = NumActRow; CheckSolStatus.close(); TestCaseSum.back().CplexRelativeGapByRule[InputRule] = cplex.getMIPRelativeGap(); env.end(); return 0; } catch (IloException& e) { ofstream FinalOut; if (isDefaultFolder) FinalOut.open("..//OutPut//Summary.txt", ios::app); else FinalOut.open((OutPutFolder + "Summary.txt").c_str(), ios::app); FinalOut << "************Warning on cplex****************" << endl; cerr << " ERROR: " << e << endl; FinalOut << " ERROR: " << e << endl; FinalOut.close(); return 1; } catch (...) { cerr << " ERROR" << endl; return 1; } }