예제 #1
0
void profit_create_vars(graph g, IloModel model, IloNumVarArray x, IloNumVarArray p, IloNumVarArray z, int **columns) {
  IloEnv env = model.getEnv();
  string s;
  assignment_vars(g, model, x, columns);  
  for(int j = 0; j < g->items; j++) {
    s = "p_" + itos(j);
    p.add(IloNumVar(env, 0.0, boundp(j), ILOFLOAT, s.c_str()));
    // p.add(IloNumVar(env, lowerp(j), boundp(j), ILOFLOAT, s.c_str()));
  }
  for(int i = 0; i < g->bidders; i++) {
    s = "z_" + itos(i);
    z.add(IloNumVar(env, 0.0, boundu(i), ILOFLOAT, s.c_str()));
  }
}
예제 #2
0
void addInitColumn(IloNumVarArray lambda, IloObjective rmpObj, 
	IloRangeArray maintConEng, IloRangeArray removeMod, IloRangeArray convex, 
	IloNumArray2 addXCol, IloNumArray addZCol, 
	const IloNumArray compCosts, const IloNumArray convexityCoef) {

	// loop counter
	IloInt t;		

	// counter for objective function coefficient for lambda
	// variable to be added.
	IloNum lambdaObjCoef = 0;

	// function assumes addXCol and addZCol contains proper values.

	// calculate objective function coefficient lambdaObjCoef
	for (t = 0; t < TIME_SPAN; t++) {

		// for each fixed t: scalar product of x[m]* vector and
		// component costs vector compCosts[m]:
		lambdaObjCoef += IloScalProd(addXCol[t],compCosts);

		// also clear the addXCol subarrays as soon as they
		// have been used
		addXCol[t].clear();
	}
			
	// now add this column and it's associated lambda variable to the RMP.
	lambda.add(IloNumVar(rmpObj(lambdaObjCoef) + maintConEng(addZCol) + 
		removeMod(addZCol) + convex(convexityCoef), 0.0, 1.0));

	// clear addZCol num array.
	addZCol.clear();

} // END of addColumn
예제 #3
0
static void
populatebycolumn (IloModel model, IloNumVarArray x, IloRangeArray c)
{
   IloEnv env = model.getEnv();

   IloObjective obj = IloMaximize(env);
   c.add(IloRange(env, -IloInfinity, 20.0));
   c.add(IloRange(env, -IloInfinity, 30.0));

   x.add(IloNumVar(obj(1.0) + c[0](-1.0) + c[1]( 1.0), 0.0, 40.0));
   x.add(obj(2.0) + c[0]( 1.0) + c[1](-3.0));
   x.add(obj(3.0) + c[0]( 1.0) + c[1]( 1.0));

   model.add(obj);
   model.add(c);
}  // END populatebycolumn
예제 #4
0
void addColumn(IloCplex subSolver, IloNumVarArray2 x, IloNumVarArray z, IloNumVarArray lambda,
	IloObjective rmpObj, IloRangeArray maintConEng, IloRangeArray removeMod,
	IloRangeArray convex, IloNumArray2 addXCol, IloNumArray addZCol, 
	const IloNumArray compCosts, const IloNumArray convexityCoef) {

	// loop counter
	IloInt t;		

	// counter for objective function coefficient for lambda
	// variable to be added.
	IloNum lambdaObjCoef = 0;

	// extract subproblem-optimal solution values
	// (into IloNumArrays addXCol (2d) and addZCol (1d)).

	// z values:
	subSolver.getValues(addZCol,z);

	//cout << endl << endl << "z = " << endl << addZCol << endl;
	//cin.get();

	// !!! OBS !!!
	// here we might want to save these z values some column pool's custom-nitted class
	// array. Or to be specific, we want to add the indexes for NON-ZERO-ENTRIES in addZCol
	// to our class that keep place of columns.
	// E.g., given variable lambda(m)_(q_m), we want to know in our own class object,
	// given (m)(q_m), the indexes of non-zeros in that Z column.
	


	// and for each t...
	for (t = 0; t < TIME_SPAN; t++) {

		// x values:
		subSolver.getValues(addXCol[t],x[t]);
		//cout << endl << endl << "x[t=" << t << "] =" << endl << addXCol[t] << endl;
	}
	//cin.get();

	// calculate objective function coefficient lambdaObjCoef
	for (t = 0; t < TIME_SPAN; t++) {

		// for each fixed t: scalar product of x[m]* vector and
		// component costs vector compCosts[m]:
		lambdaObjCoef += IloScalProd(addXCol[t],compCosts);

		// also clear the addXCol subarrays as soon as they
		// have been used
		addXCol[t].clear();
	}
			
	// now add this column and it's associated lambda variable to the RMP.
	lambda.add(IloNumVar(rmpObj(lambdaObjCoef) + maintConEng(addZCol) + 
		removeMod(addZCol) + convex(convexityCoef), 0.0, 1.0));

	// clear addZCol num array.
	addZCol.clear();

} // END of addColumn
예제 #5
0
static void
populatebyrow (IloModel model, IloNumVarArray x, IloRangeArray c)
{
   IloEnv env = model.getEnv();

   x.add(IloNumVar(env, 0.0, 40.0));
   x.add(IloNumVar(env));
   x.add(IloNumVar(env));
   x.add(IloNumVar(env, 2.0, 3.0, ILOINT));
   model.add(IloMaximize(env, x[0] + 2 * x[1] + 3 * x[2] + x[3]));

   c.add( - x[0] +     x[1] + x[2] + 10 * x[3] <= 20);
   c.add(   x[0] - 3 * x[1] + x[2]             <= 30);
   c.add(              x[1]        - 3.5* x[3] == 0);
   model.add(c);

}  // END populatebyrow
예제 #6
0
void PopulateFromGraph(IloModel model, IloNumVarArray s, IloRangeArray c){
  IloEnv env = model.getEnv();

  // Used n+1 for accomodating an extra variable
  // For being able to write the objective function
  for(int i = 0; i <= n; i++)
    s.add(IloNumVar(env));
}
예제 #7
0
static void
populatebyrow (IloModel model, IloNumVarArray x, IloRangeArray c)
{
   IloEnv env = model.getEnv();

   x.add(IloNumVar(env, 0.0, 40.0));
   x.add(IloNumVar(env));
   x.add(IloNumVar(env));
   model.add(IloMaximize(env, x[0] + 2 * x[1] + 3 * x[2]
                            - 0.5 * (33*x[0]*x[0] + 22*x[1]*x[1] +
                                     11*x[2]*x[2] - 12*x[0]*x[1] -
                                     23*x[1]*x[2]                 ) ));

   c.add( - x[0] +     x[1] + x[2] <= 20);
   c.add(   x[0] - 3 * x[1] + x[2] <= 30);
   model.add(c);
}  // END populatebyrow
예제 #8
0
IloExpr minBeamletStr(IloEnv & env, IloNumVarArray & w, Sparse_Matrix<IloInt> & vox)
{
	IloExpr obj(env);

	for(int i=0;i<w.getSize();++i)
	{
		obj += w[i]/IloNum(100);
	}

	return 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);
}
예제 #10
0
static void
populatebyrow (IloModel model, IloNumVarArray x, IloRangeArray c)
{
   IloEnv env = model.getEnv();

   x.add(IloNumVar(env, -1.0, 1.0));
   x.add(IloNumVar(env,  0.0, 1.0));
   model.add(IloMinimize(env, 0.5 * (-3*x[0]*x[0] - 3*x[1]*x[1] +
                                       - 1*x[0]*x[1]               ) ));

   c.add( - x[0] + x[1] >= 0);
   c.add(   x[0] + x[1] >= 0);
   model.add(c);
}  // END populatebyrow
예제 #11
0
 /** 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();
 }
예제 #12
0
static void
populatebyrow (IloModel model, IloNumVarArray x, IloRangeArray c)
{
   IloEnv env = model.getEnv();

   x.add(IloNumVar(env, 0.0, 40.0));
   x.add(IloNumVar(env, 0.0, IloInfinity, ILOINT));
   x.add(IloNumVar(env, 0.0, IloInfinity, ILOINT));
   x.add(IloNumVar(env, 2.0, 3.0, ILOINT));
   model.add(IloMaximize(env, x[0] + 2 * x[1] + 3 * x[2] + x[3]));

   c.add( - x[0] +     x[1] + x[2] + 10 * x[3] <= 20);
   c.add(   x[0] - 3 * x[1] + x[2]             <= 30);
   c.add(              x[1]        - 3.5* x[3] == 0);
   model.add(c);

   IloNumVarArray sosvar(env, 2);
   IloNumArray    sosval(env, 2);
   sosvar[0] = x[2]; sosvar[1] = x[3];
   sosval[0] = 25.0; sosval[1] = 18.0;

   model.add(IloSOS1(model.getEnv(), sosvar, sosval));

}  // END populatebyrow
예제 #13
0
/** Extract sub block number <code>n</code> from <code>problem</code>.
 * The constructor creates a representation of block number <code>n</code>
 * as described in <code>problem</code>.
 * The constructor will also connect the newly created block to a remote
 * object solver instance.
 * @param problem  The problem from which the block is to be extracted.
 * @param n        Index of the block to be extracted.
 * @param argc     Argument for IloCplex constructor.
 * @param argv     Argument for IloCplex constructor.
 * @param machines List of machines to which to connect. If the code is
 *                 compiled for the TCP/IP transport then the block will
 *                 be connected to <code>machines[n]</code>.
 */
BendersOpt::Block::Block(Problem const *problem, IloInt n, int argc, char const *const *argv,
                         std::vector<char const *> const &machines)
   : env(), number(n), vars(0), rows(0), cplex(0), cb(0)
{
   IloNumVarArray problemVars = problem->getVariables();
   IloRangeArray problemRanges = problem->getRows();

   // Create a map that maps variables in the original model to their
   // respective index in problemVars.
   std::map<IloNumVar,IloInt,ExtractableLess<IloNumVar> > origIdxMap;
   for (IloInt j = 0; j < problemVars.getSize(); ++j)
      origIdxMap.insert(std::map<IloNumVar,IloInt,ExtractableLess<IloNumVar> >::value_type(problemVars[j], j));

   // Copy non-fixed variables from original problem into primal problem.
   IloExpr primalObj(env);
   IloNumVarArray primalVars(env);
   IloRangeArray primalRows(env);
   IdxMap idxMap; // Index of original variable in block's primal model
   RowSet rowSet;
   for (IloInt j = 0; j < problemVars.getSize(); ++j) {
      IloNumVar x = problemVars[j];
      if ( problem->getBlock(x) == number ) {
         // Create column in block LP with exactly the same data.
         if ( x.getType() != IloNumVar::Float ) {
            std::stringstream s;
            s << "Cannot create non-continuous block variable " << x;
            std::cerr << s.str() << std::endl;
            throw s.str();
         }
         IloNumVar v(env, x.getLB(), x.getUB(), x.getType(), x.getName());
         // Normalize objective function to 'minimize'
         double coef = problem->getObjCoef(x);
         if ( problem->getObjSense() != IloObjective::Minimize )
            coef *= -1.0;
         primalObj += coef * v;
            
         // Record the index that the copied variable has in the
         // block model.
         idxMap.insert(IdxMap::value_type(x, primalVars.getSize()));
         primalVars.add(v);
            
         // Mark the rows that are intersected by this column
         // so that we can collect them later.
         RowSet const &intersected = problem->getIntersectedRows(x);
         for (RowSet::const_iterator it = intersected.begin();
              it != intersected.end(); ++it)
            rowSet.insert(*it);
      }
      else
         idxMap.insert(IdxMap::value_type(x, -1));
   }

   // Now copy all rows that intersect block variables.
   for (IloInt i = 0; i < problemRanges.getSize(); ++i) {
      IloRange r = problemRanges[i];
      if ( rowSet.find(r) == rowSet.end() )
         continue;

      // Create a copy of the row, normalizing it to '<='
      double factor = 1.0;
      if ( r.getLB() > -IloInfinity )
         factor = -1.0;
      IloRange primalR(env,
                       factor < 0 ? -r.getUB() : r.getLB(),
                       factor < 0 ? -r.getLB() : r.getUB(), r.getName());
      IloExpr lhs(env);
      for (IloExpr::LinearIterator it = r.getLinearIterator(); it.ok(); ++it)
      {
         IloNumVar v = it.getVar();
         double const val = factor * it.getCoef();
         if ( problem->getBlock(v) != number ) {
            // This column is not explicitly in this block. This means
            // that it is a column that will be fixed by the master.
            // We collect all such columns so that we can adjust the
            // dual objective function according to concrete fixings.
            // Store information about variables in this block that
            // will be fixed by master solves.
            fixed.push_back(FixData(primalRows.getSize(), origIdxMap[v], -val));
         }
         else {
            // The column is an ordinary in this block. Just copy it.
            lhs += primalVars[idxMap[v]] * val;
         }
      }
      primalR.setExpr(lhs);
      primalRows.add(primalR);
      lhs.end();
   }

   // Create the dual of the primal model we just created.
   // Note that makeDual _always_ returns a 'maximize' objective.
   IloObjective objective(env, primalObj, IloObjective::Minimize);
      
   makeDual(objective, primalVars, primalRows,
            &obj, &vars, &rows);
   objective.end();
   primalRows.endElements();
   primalRows.end();
   primalVars.endElements();
   primalVars.end();
   primalObj.end();
   // Create a model.
   IloModel model(env);
   model.add(obj);
   model.add(vars);
   model.add(rows);
   for (IloExpr::LinearIterator it = obj.getLinearIterator(); it.ok(); ++it)
      objMap.insert(ObjMap::value_type(it.getVar(), it.getCoef()));

   // Finally create the IloCplex instance that will solve
   // the problems associated with this block.
   char const **transargv = new char const *[argc + 3];
   for (int i = 0; i < argc; ++i)
      transargv[i] = argv[i];
#if defined(USE_MPI)
   char extra[128];
   sprintf (extra, "-remoterank=%d", static_cast<int>(number + 1));
   transargv[argc++] = extra;
   (void)machines;
#elif defined(USE_PROCESS)
   char extra[128];
   sprintf (extra, "-logfile=block%04d.log", static_cast<int>(number));
   transargv[argc++] = extra;
   (void)machines;
#elif defined(USE_TCPIP)
   transargv[argc++] = machines[number];
#endif
   cplex = IloCplex(model, TRANSPORT, argc, transargv);
   delete[] transargv;

   // Suppress output from this block's solver.
   cplex.setOut(env.getNullStream());
   cplex.setWarning(env.getNullStream());
}
예제 #14
0
// 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
예제 #15
0
   Example(IloEnv env)
      : nblocks(0), model(env), vars(env), ranges(env)
   {
      // Model data.
      // fixed[] is the fixed cost for opening a facility,
      // cost[i,j] is the cost for serving customer i from facility j.
      static double const fixed[] = { 2.0, 3.0, 3.0 };
      static double const cost[] = { 2.0, 3.0, 4.0, 5.0, 7.0,
                                     4.0, 3.0, 1.0, 2.0, 6.0,
                                     5.0, 4.0, 2.0, 1.0, 3.0 };
#define NFACTORY ((CPXDIM)(sizeof(fixed) / sizeof(fixed[0])))
#define NCUSTOMER ((CPXDIM)((sizeof(cost) / sizeof(cost[0])) / NFACTORY))
      nblocks = NCUSTOMER;

      IloExpr obj(env);
      // Create integer y  variables.
      IloNumVarArray y(env);
      for (IloInt f = 0; f < NFACTORY; ++f) {
         std::stringstream s;
         s << "y" << f;
         IloIntVar v(env, 0, 1, s.str().c_str());
         obj += fixed[f] * v;
         objMap[v] = fixed[f];
         y.add(v);
         blockMap.insert(BlockMap::value_type(v, -1));
         intersectMap.insert(IntersectMap::value_type(v, RowSet()));
      }

      // Create continuous x variables.
      IloNumVarArray x(env);
      for (IloInt f = 0; f < NFACTORY; ++f) {
         for (IloInt c = 0; c < NCUSTOMER; ++c) {
            std::stringstream s;
            s << "x" << f << "#" << c;
            IloNumVar v(env, 0.0, IloInfinity, s.str().c_str());
            obj += v * cost[f * NCUSTOMER + c];
            objMap[v] = cost[f * NCUSTOMER + c];
            x.add(v);
            blockMap.insert(BlockMap::value_type(v, c));
            intersectMap.insert(IntersectMap::value_type(v, RowSet()));
         }
      }
      vars.add(y);
      vars.add(x);
      model.add(vars);

      // Add objective function.
      model.add(IloMinimize(env, obj, "obj"));
      objSense = IloObjective::Minimize;
      obj.end();

      // Satisfy each customer's demand.
      for (IloInt c = 0; c < NCUSTOMER; ++c) {
         std::stringstream s;
         s << "c1_" << c;
         IloRange r(env, 1.0, IloInfinity, s.str().c_str());
         IloExpr lhs(env);
         for (IloInt f = 0; f < NFACTORY; ++f) {
            lhs += x[f * NCUSTOMER + c];
            intersectMap[x[f * NCUSTOMER + c]].insert(r);
         }
         r.setExpr(lhs);
         ranges.add(r);
         lhs.end();
      }

      // A factory must be open if we service from it.
      for (IloInt c = 0; c < NCUSTOMER; ++c) {
         for (IloInt f = 0; f < NFACTORY; ++f) {
            std::stringstream s;
            s << "c2_" << c << "#" << f;
            IloRange r(env, 0.0, IloInfinity, s.str().c_str());
            intersectMap[x[f * NCUSTOMER + c]].insert(r);
            intersectMap[y[f]].insert(r);
            r.setExpr(-x[f * NCUSTOMER + c] + y[f]);
            ranges.add(r);
         }
      }

      // Capacity constraint.
      IloRange r(env, -IloInfinity, NFACTORY - 1, "c3");
      IloExpr lhs(env);
      for (IloInt f = 0; f < NFACTORY; ++f) {
         lhs += y[f];
         intersectMap[y[f]].insert(r);
      }
      r.setExpr(lhs);
      ranges.add(r);
      lhs.end();

      model.add(ranges);

#undef NFACTORY
#undef NCUSTOMER
   }
예제 #16
0
void
makeCuts(const IloNumVarArray vars, IloExprArray lhs, IloNumArray rhs) {
   IloNumVar x11, x12, x13, x14, x15;
   IloNumVar x21, x22, x23, x24, x25;
   IloNumVar x31, x32, x33, x34, x35;
   IloNumVar x41, x42, x43, x44, x45;
   IloNumVar x51, x52, x53, x54, x55;
   IloNumVar w11, w12, w13, w14, w15;
   IloNumVar w21, w22, w23, w24, w25;
   IloNumVar w31, w32, w33, w34, w35;
   IloNumVar w41, w42, w43, w44, w45;
   IloNumVar w51, w52, w53, w54, w55;
   IloInt num = vars.getSize();

   for (IloInt i = 0; i < num; i++) {
      if      ( strcmp(vars[i].getName(), "X11") == 0 ) x11 = vars[i];
      else if ( strcmp(vars[i].getName(), "X12") == 0 ) x12 = vars[i];
      else if ( strcmp(vars[i].getName(), "X13") == 0 ) x13 = vars[i];
      else if ( strcmp(vars[i].getName(), "X14") == 0 ) x14 = vars[i];
      else if ( strcmp(vars[i].getName(), "X15") == 0 ) x15 = vars[i];
      else if ( strcmp(vars[i].getName(), "X21") == 0 ) x21 = vars[i];
      else if ( strcmp(vars[i].getName(), "X22") == 0 ) x22 = vars[i];
      else if ( strcmp(vars[i].getName(), "X23") == 0 ) x23 = vars[i];
      else if ( strcmp(vars[i].getName(), "X24") == 0 ) x24 = vars[i];
      else if ( strcmp(vars[i].getName(), "X25") == 0 ) x25 = vars[i];
      else if ( strcmp(vars[i].getName(), "X31") == 0 ) x31 = vars[i];
      else if ( strcmp(vars[i].getName(), "X32") == 0 ) x32 = vars[i];
      else if ( strcmp(vars[i].getName(), "X33") == 0 ) x33 = vars[i];
      else if ( strcmp(vars[i].getName(), "X34") == 0 ) x34 = vars[i];
      else if ( strcmp(vars[i].getName(), "X35") == 0 ) x35 = vars[i];
      else if ( strcmp(vars[i].getName(), "X41") == 0 ) x41 = vars[i];
      else if ( strcmp(vars[i].getName(), "X42") == 0 ) x42 = vars[i];
      else if ( strcmp(vars[i].getName(), "X43") == 0 ) x43 = vars[i];
      else if ( strcmp(vars[i].getName(), "X44") == 0 ) x44 = vars[i];
      else if ( strcmp(vars[i].getName(), "X45") == 0 ) x45 = vars[i];
      else if ( strcmp(vars[i].getName(), "X51") == 0 ) x51 = vars[i];
      else if ( strcmp(vars[i].getName(), "X52") == 0 ) x52 = vars[i];
      else if ( strcmp(vars[i].getName(), "X53") == 0 ) x53 = vars[i];
      else if ( strcmp(vars[i].getName(), "X54") == 0 ) x54 = vars[i];
      else if ( strcmp(vars[i].getName(), "X55") == 0 ) x55 = vars[i];
      else if ( strcmp(vars[i].getName(), "W11") == 0 ) w11 = vars[i];
      else if ( strcmp(vars[i].getName(), "W12") == 0 ) w12 = vars[i];
      else if ( strcmp(vars[i].getName(), "W13") == 0 ) w13 = vars[i];
      else if ( strcmp(vars[i].getName(), "W14") == 0 ) w14 = vars[i];
      else if ( strcmp(vars[i].getName(), "W15") == 0 ) w15 = vars[i];
      else if ( strcmp(vars[i].getName(), "W21") == 0 ) w21 = vars[i];
      else if ( strcmp(vars[i].getName(), "W22") == 0 ) w22 = vars[i];
      else if ( strcmp(vars[i].getName(), "W23") == 0 ) w23 = vars[i];
      else if ( strcmp(vars[i].getName(), "W24") == 0 ) w24 = vars[i];
      else if ( strcmp(vars[i].getName(), "W25") == 0 ) w25 = vars[i];
      else if ( strcmp(vars[i].getName(), "W31") == 0 ) w31 = vars[i];
      else if ( strcmp(vars[i].getName(), "W32") == 0 ) w32 = vars[i];
      else if ( strcmp(vars[i].getName(), "W33") == 0 ) w33 = vars[i];
      else if ( strcmp(vars[i].getName(), "W34") == 0 ) w34 = vars[i];
      else if ( strcmp(vars[i].getName(), "W35") == 0 ) w35 = vars[i];
      else if ( strcmp(vars[i].getName(), "W41") == 0 ) w41 = vars[i];
      else if ( strcmp(vars[i].getName(), "W42") == 0 ) w42 = vars[i];
      else if ( strcmp(vars[i].getName(), "W43") == 0 ) w43 = vars[i];
      else if ( strcmp(vars[i].getName(), "W44") == 0 ) w44 = vars[i];
      else if ( strcmp(vars[i].getName(), "W45") == 0 ) w45 = vars[i];
      else if ( strcmp(vars[i].getName(), "W51") == 0 ) w51 = vars[i];
      else if ( strcmp(vars[i].getName(), "W52") == 0 ) w52 = vars[i];
      else if ( strcmp(vars[i].getName(), "W53") == 0 ) w53 = vars[i];
      else if ( strcmp(vars[i].getName(), "W54") == 0 ) w54 = vars[i];
      else if ( strcmp(vars[i].getName(), "W55") == 0 ) w55 = vars[i];
   }

   lhs.add(x21 - x22);
   rhs.add(0.0);

   lhs.add(x22 - x23);
   rhs.add(0.0);

   lhs.add(x23 - x24);
   rhs.add(0.0);

   lhs.add(2.08*x11 + 2.98*x21 + 3.47*x31 + 2.24*x41 + 2.08*x51 +
           0.25*w11 + 0.25*w21 + 0.25*w31 + 0.25*w41 + 0.25*w51);
   rhs.add(20.25);

   lhs.add(2.08*x12 + 2.98*x22 + 3.47*x32 + 2.24*x42 + 2.08*x52 +
           0.25*w12 + 0.25*w22 + 0.25*w32 + 0.25*w42 + 0.25*w52);
   rhs.add(20.25);

   lhs.add(2.08*x13 + 2.98*x23 + 3.47*x33 + 2.24*x43 + 2.08*x53 +
           0.25*w13 + 0.25*w23 + 0.25*w33 + 0.25*w43 + 0.25*w53);
   rhs.add(20.25);

   lhs.add(2.08*x14 + 2.98*x24 + 3.47*x34 + 2.24*x44 + 2.08*x54 +
           0.25*w14 + 0.25*w24 + 0.25*w34 + 0.25*w44 + 0.25*w54);
   rhs.add(20.25);

   lhs.add(2.08*x15 + 2.98*x25 + 3.47*x35 + 2.24*x45 + 2.08*x55 +
           0.25*w15 + 0.25*w25 + 0.25*w35 + 0.25*w45 + 0.25*w55);
   rhs.add(16.25);
}
예제 #17
0
파일: ilosocpex1.cpp 프로젝트: renvieir/ioc
// This function creates the following model:
//   Minimize
//    obj: x1 + x2 + x3 + x4 + x5 + x6
//   Subject To
//    c1: x1 + x2      + x5      = 8
//    c2:           x3 + x5 + x6 = 10
//    q1: [ -x1^2 + x2^2 + x3^2 ] <= 0
//    q2: [ -x4^2 + x5^2 ] <= 0
//   Bounds
//    x2 Free
//    x3 Free
//    x5 Free
//   End
// which is a second order cone program in standard form.
// The function returns objective, variables and constraints in the
// values obj, vars and rngs.
// The function also sets up cone so that for a column j we have
// cone[j] >= 0               Column j is in a cone constraint and is the
//                            cone's head variable.
// cone[j] == NOT_CONE_HEAD   Column j is in a cone constraint but is
//                            not the cone's head variable..
// cone[j] == NOT_IN_CONE     Column j is not contained in any cone constraint.
static void
createmodel (IloModel& model, IloObjective &obj, IloNumVarArray &vars,
             IloRangeArray &rngs, IloIntArray& cone)
{
   // The indices we assign as user objects to the modeling objects.
   // We define them as static data so that we don't have to worry about
   // dynamic memory allocation/leakage.
   static int indices[] = { 0, 1, 2, 3, 4, 5, 6 };

   IloEnv env = model.getEnv();

   // Create variables.
   IloNumVar x1(env,            0, IloInfinity, "x1");
   IloNumVar x2(env, -IloInfinity, IloInfinity, "x2");
   IloNumVar x3(env, -IloInfinity, IloInfinity, "x3");
   IloNumVar x4(env,            0, IloInfinity, "x4");
   IloNumVar x5(env, -IloInfinity, IloInfinity, "x5");
   IloNumVar x6(env,            0, IloInfinity, "x6");

   // Create objective function and immediately store it in return value.
   obj = IloMinimize(env, x1 + x2 + x3 + x4 + x5 + x6);

   // Create constraints.
   IloRange c1(env, 8,  x1 + x2      + x5,       8, "c1");
   IloRange c2(env, 10,           x3 + x5 + x6, 10, "c2");
   IloRange q1(env, -IloInfinity, -x1*x1 + x2*x2 + x3*x3, 0, "q1");
   cone.add(2);             // x1, cone head of constraint at index 2
   cone.add(NOT_CONE_HEAD); // x2
   cone.add(NOT_CONE_HEAD); // x3
   IloRange q2(env, -IloInfinity, -x4*x4 + x5*x5, 0, "q2");
   cone.add(3);             // x4, cone head of constraint at index 3
   cone.add(NOT_CONE_HEAD); // x5

   cone.add(NOT_IN_CONE);   // x6

   // Setup model.
   model.add(obj);
   model.add(obj);
   model.add(c1);
   model.add(c2);
   model.add(q1);
   model.add(q2);

   // Setup return values.
   vars.add(x1);
   vars.add(x2);
   vars.add(x3);
   vars.add(x4);
   vars.add(x5);
   vars.add(x6);

   rngs.add(c1);
   rngs.add(c2);
   rngs.add(q1);
   rngs.add(q2);

   // We set the user object for each modeling object to its index in the
   // respective array. This makes the code in checkkkt a little simpler.
   for (IloInt i = 0; i < vars.getSize(); ++i)
      vars[i].setObject(&indices[i]);
   for (IloInt i = 0; i < rngs.getSize(); ++i)
      rngs[i].setObject(&indices[i]);
}
예제 #18
0
void LpSolver::populatebyrow (CplexConverter& cplexConverter, 
	IloModel model, IloNumVarArray x, IloRangeArray c)
{
	IloEnv env = model.getEnv();
	// CAPITAL LETTERS MEAN I NEED YOUR HELP, here is help 

	// IloExpr cost(env);
	
	// Create Variables
	// cout << "size of var: " << cplexConverter.variables.size() << endl;
	for (int i = 0; i < cplexConverter.variables.size(); ++i){
		IloNumVar iloVar(env, 0.0, cplexConverter.capacities[i], IloNumVar::Int);
		// cout << iloVar << endl;
		x.add(iloVar);
	}

	//Capacity Constraints
	for (auto &it : cplexConverter.atomicIdToVarIdDict){
		IloExpr t(env);
		// cout << "adding constraint ";
		for (int j = 0; j < it.second.size(); j++){
			// cout << "x[" << it.second[j] << "] + ";
			t += x[it.second[j]];
		}
		// cout << endl;
		c.add(t <= cplexConverter.graph->atomicEdges[it.first]->capacity);
		// cout << c << endl;
		t.end();
	}

	// other constraints
	for (auto nodePair : cplexConverter.graph->nodes){

		// For all nodes
		Node* n = nodePair.second;

		if(n == cplexConverter.src){

			// source constraints
			// IloExpr inFlow(env);
			IloExpr outFlow(env);	
			for(auto &atoIn : n->atomicEdge_in){
				int aeId = atoIn.second->atomicEdgeId;
				for (int j = 0; j < cplexConverter.atomicIdToVarIdDict[aeId].size(); j++){
					// var Id
					int vId = cplexConverter.atomicIdToVarIdDict[aeId][j];
					outFlow += x[vId];
					// cost += cplexConverter.graph->atomicEdges[cplexConverter.variables[vId].atomicEdgeId]->interest_rate * x[vId];
				}
			}
			for (auto &atoOut : n->atomicEdge_out){
				int aeId = atoOut.second->atomicEdgeId;
				for (int j = 0; j < cplexConverter.atomicIdToVarIdDict[aeId].size(); j++){
					// var Id
					int vId = cplexConverter.atomicIdToVarIdDict[aeId][j];
					// inFlow += x[vId];
					c.add(x[vId] == 0);
					// cost -= cplexConverter.graph->atomicEdges[cplexConverter.variables[vId].atomicEdgeId]->interest_rate * x[vId];
				}
			}

			c.add(outFlow == cplexConverter.request);
			// inFlow.end();
			outFlow.end();

		} else if(n == cplexConverter.dest){

			// destination constraints
			IloExpr inFlow(env);
			// IloExpr outFlow(env);
			for(auto &atoIn : n->atomicEdge_in){
				int aeId = atoIn.second->atomicEdgeId;
				for (int j = 0; j < cplexConverter.atomicIdToVarIdDict[aeId].size(); j++){
					// var Id
					int vId = cplexConverter.atomicIdToVarIdDict[aeId][j];
					// outFlow += x[vId];
					c.add(x[vId] == 0);
				}
			}
			for (auto &atoOut : n->atomicEdge_out){
				int aeId = atoOut.second->atomicEdgeId;
				for (int j = 0; j < cplexConverter.atomicIdToVarIdDict[aeId].size(); j++){
					// var Id
					int vId = cplexConverter.atomicIdToVarIdDict[aeId][j];
					inFlow += x[vId];
				}
			}

			c.add(inFlow == cplexConverter.request);
			inFlow.end();
			// outFlow.end();

		} else {

			// Monotonicity Constraints
			for (int i = 0; i < credNetConstants.totalIrs.size(); ++i){
				IloExpr tempin(env);
				IloExpr tempout(env);

				for (auto &atoIn : n->atomicEdge_in){
					int aeId = atoIn.second->atomicEdgeId;
					for (int j = 0; j < cplexConverter.atomicIdToVarIdDict[aeId].size(); j++){

						// var Id
						int vId = cplexConverter.atomicIdToVarIdDict[aeId][j];
						if (cplexConverter.variables[vId].interest_rate <= credNetConstants.totalIrs[i]){
							tempout += x[vId];
						}
					}
				}
				for (auto &atoOut : n->atomicEdge_out){
					int aeId = atoOut.second->atomicEdgeId;
					for (int j = 0; j < cplexConverter.atomicIdToVarIdDict[aeId].size(); j++){

						// var Id
						int vId = cplexConverter.atomicIdToVarIdDict[aeId][j];
						if (cplexConverter.variables[vId].interest_rate <= credNetConstants.totalIrs[i]){
							tempin += x[vId];
						}
					}
				}

				c.add(tempout - tempin >= 0);
				tempout.end();
				tempin.end();
			}

			//Flow Constraints
			IloExpr inFlow(env);
			IloExpr outFlow(env);	
			for(auto &atoIn : n->atomicEdge_in){
				int aeId = atoIn.second->atomicEdgeId;
				for (int j = 0; j < cplexConverter.atomicIdToVarIdDict[aeId].size(); j++){
					// var Id
					int vId = cplexConverter.atomicIdToVarIdDict[aeId][j];
					outFlow += x[vId];
				}
			}
			for (auto &atoOut : n->atomicEdge_out){
				int aeId = atoOut.second->atomicEdgeId;
				for (int j = 0; j < cplexConverter.atomicIdToVarIdDict[aeId].size(); j++){
					// var Id
					int vId = cplexConverter.atomicIdToVarIdDict[aeId][j];
					inFlow += x[vId];
				}
			}

			c.add(inFlow - outFlow == 0);
			inFlow.end();
			outFlow.end();

		}

	}


	model.add(c);
	// model.add(IloMinimize(env, cost));
	// model.add(IloMaximize(env,cost));  //option to minimize cost
	// cost.end();

}  // END populatebyrow
예제 #19
0
static void populatebyrow (IloModel model, IloNumVarArray x, IloRangeArray c) {
  
  IloEnv env = model.getEnv();
  IloNumArray costs(env);
  IloNumArray time(env);
IloNumArray product(env);

  int costs_array[]  = {1,1,1,10,1,12,2,2,5,10};
  int time_array[]  = {10,1,7,3,2,3,2,3,7,1};
  int product_array[]  = {0,3,1,2,-2,0,0,0,0,0};
  

  for(int i=0;i<10;i++)
    costs.add(costs_array[i]);

  for(int i=0;i<10;i++)
    time.add(time_array[i]);

  for(int i=0;i<10;i++)
    product.add(product_array[i]);



  x.add(IloBoolVar(env,"x12")); //0
  x.add(IloBoolVar(env,"x24")); //1
  x.add(IloBoolVar(env,"x46")); //2
  x.add(IloBoolVar(env,"x13")); //3
  x.add(IloBoolVar(env,"x32")); //4
  x.add(IloBoolVar(env,"x35")); //5
  x.add(IloBoolVar(env,"x56")); //6
  x.add(IloBoolVar(env,"x25")); //7
  x.add(IloBoolVar(env,"x34")); //8
  x.add(IloBoolVar(env,"x45")); //9


x.add(IloNumVar(env,0,IloInfinity,ILOINT,"s2")); //10
x.add(IloNumVar(env,0,IloInfinity,ILOINT,"s3")); //11
x.add(IloNumVar(env,0,IloInfinity,ILOINT,"s4")); //12
x.add(IloNumVar(env,0,IloInfinity,ILOINT,"s5")); //13
x.add(IloNumVar(env,0,IloInfinity,ILOINT,"s1")); //14
x.add(IloNumVar(env,0,IloInfinity,ILOINT,"s6")); //15

x.add(IloNumVar(env,0,IloInfinity,ILOINT,"q2")); //16
x.add(IloNumVar(env,0,IloInfinity,ILOINT,"q3")); //17
x.add(IloNumVar(env,0,IloInfinity,ILOINT,"q4")); //18
x.add(IloNumVar(env,0,IloInfinity,ILOINT,"q5")); //19
x.add(IloNumVar(env,0,IloInfinity,ILOINT,"q1")); //20
x.add(IloNumVar(env,0,IloInfinity,ILOINT,"q6")); //21



  
  model.add(IloMinimize(env, costs[0]*x[0] + costs[1]*x[1] + costs[2]*x[2] + costs[3]*x[3] + costs[4]*x[4] + costs[5]*x[5] + costs[6]*x[6] + costs[7]*x[7] + costs[8]*x[8] + costs[9]*x[9]));
  c.add(x[0]+ x[3] == 1); // arcs sortant du noeud de depart
  c.add(x[2]+ x[6] == 1); // arcs entrant au noeud d arrivee
  c.add(x[1]+ x[7] - x[0] - x[4] == 0);
  c.add(x[8]+ x[5] + x[4] - x[3] == 0);
  c.add(x[9]+ x[2] - x[1] - x[8] == 0);
  c.add(x[6]- x[7] - x[5] - x[9] == 0);
  c.add(time[0]*x[0] + time[1]*x[1] + time[2]*x[2] + time[3]*x[3] + time[4]*x[4] + time[5]*x[5] + time[6]*x[6] + time[7]*x[7] + time[8]*x[8] + time[9]*x[9] <= 14);
//c.add(product[0]*x[0] + product[1]*x[1] + product[2]*x[2] + product[3]*x[3] + product[4]*x[4] + product[5]*x[5] + product[6]*x[6] + product[7]*x[7] + product[8]*x[8] + product[9]*x[9] <= 4);

c.add(x[14]+time[0]-1000*(1-x[0]) - x[10]<= 0);
c.add(x[20]+product[0]-1000*(1-x[0]) - x[16]<= 0);


c.add(x[10]+time[1]-1000*(1-x[1]) - x[12]<= 0);
c.add(x[16]+product[1]-1000*(1-x[1]) - x[18]<= 0);
c.add(x[18]-product[1]-1000*(1-x[1]) - x[16]<= 0);


c.add(x[12]+time[2]-1000*(1-x[2]) - x[15]<= 0);
c.add(x[18]+product[2]-1000*(1-x[2]) - x[21]<= 0);
c.add(x[21]-product[2]-1000*(1-x[2]) - x[18]<= 0);


c.add(x[14]+time[3]-1000*(1-x[3]) - x[11]<= 0);
c.add(x[20]+product[3]-1000*(1-x[3]) - x[17]<= 0);
c.add(x[17]-product[3]-1000*(1-x[3]) - x[20]<= 0);

c.add(x[13]+time[6]-1000*(1-x[6]) - x[15]<= 0);
c.add(x[19]+product[6]-1000*(1-x[6]) - x[21]<= 0);

c.add(x[10]+time[7]-1000*(1-x[7]) - x[13]<= 0);
c.add(x[16]+product[7]-1000*(1-x[7]) - x[19]<= 0);

c.add(x[12]+time[9]-1000*(1-x[9]) - x[13]<= 0);
c.add(x[18]+product[9]-1000*(1-x[9]) - x[19]<= 0);

c.add(x[11]+time[4]-1000*(1-x[4]) - x[10] <=0);
c.add(x[17]+product[4]-1000*(1-x[4]) - x[16]<= 0);
c.add(x[16]-product[4]-1000*(1-x[4]) - x[17]<= 0);


c.add(x[11]+time[8]-1000*(1-x[8]) - x[12]<= 0);
c.add(x[17]+product[8]-1000*(1-x[8]) - x[18]<= 0);

c.add(x[11]+time[5]-1000*(1-x[5]) - x[13]<= 0);
c.add(x[17]+product[5]-1000*(1-x[5]) - x[19]<= 0);



c.add(5 <= x[10] <= 7);
c.add(2 <= x[11] <= 5);
c.add(5 <= x[12] <= 9);
c.add(0 <= x[13] <= 20);
c.add(0 <= x[14] <= 0);
c.add(0 <= x[15] <= 14);

/*
c.add(2 <= x[17] <= 4);
c.add(0 <= x[16] <= 2);
c.add(3 <= x[18] <= 4);

c.add(0 <= x[19] <= 1000);
//c.add(0 <= x[20] <= 0);*/
c.add(3 <= x[21] <= 4);

c.add( x[20] == 1);









  model.add(c);
}
예제 #20
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;
      }
   }
예제 #21
0
파일: ilosocpex1.cpp 프로젝트: renvieir/ioc
// 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;   
}
예제 #22
0
/** Extract the master block from <code>problem</code>.
 * The constructor also sets up the solver for the newly created master
 * block. The master block can only be extracted if all sub-blocks have
 * already been extracted.
 * @param problem The problem from which to extract the master.
 * @param blocks  The sub blocks that have already been extracted.
 */
BendersOpt::Block::Block(Problem const *problem, BlockVector const &blocks)
   : env(), number(-1), vars(0), rows(0), cplex(0), cb(0)
{
   IloNumVarArray problemVars = problem->getVariables();
   IloRangeArray problemRanges = problem->getRows();

   IloExpr masterObj(env);
   IloNumVarArray masterVars(env);
   IloRangeArray masterRows(env);

   // Find columns that do not intersect block variables and
   // copy them to the master block.
   IdxMap idxMap;
   RowSet rowSet;
   for (IloInt j = 0; j < problemVars.getSize(); ++j) {
      IloNumVar x = problemVars[j];
      if ( problem->getBlock(x) < 0 ) {
         // Column is not in a block. Copy it to the master.
         IloNumVar v(env, x.getLB(), x.getUB(), x.getType(), x.getName());
         varMap.insert(VarMap::value_type(v, x));
         masterObj += problem->getObjCoef(x) * v;

         idxMap[x] = masterVars.getSize();
         masterVars.add(v);
      }
      else {
         // Column is in a block. Collect all rows that intersect
         // this column.
         RowSet const &intersected = problem->getIntersectedRows(x);
         for (RowSet::const_iterator it = intersected.begin();
              it != intersected.end(); ++it)
            rowSet.insert(*it);
         idxMap[x] = -1;
      }
   }

   // Pick up the rows that we need to copy.
   // These are the rows that are only intersected by master variables,
   // that is, the rows that are not in any block's rowset.
   for (IloInt i = 0; i < problemRanges.getSize(); ++i) {
      IloRange r = problemRanges[i];
      if ( rowSet.find(r) == rowSet.end() ) {
         IloRange masterRow(env, r.getLB(), r.getUB(), r.getName());
         IloExpr lhs(env);
         for (IloExpr::LinearIterator it = r.getLinearIterator(); it.ok(); ++it)
         {
            lhs += it.getCoef() * masterVars[idxMap[it.getVar()]];
         }
         masterRow.setExpr(lhs);
         masterRows.add(masterRow);
      }
   }

   // Adjust variable indices in blocks so that reference to variables
   // in the original problem become references to variables in the master.
   for (BlockVector::const_iterator b = blocks.begin(); b != blocks.end(); ++b) {
      for (std::vector<FixData>::iterator it = (*b)->fixed.begin(); it != (*b)->fixed.end(); ++it)
         it->col = idxMap[problemVars[it->col]];
   }

   // Create the eta variables, one for each block.
   // See the comments at the top of this file for details about the
   // eta variables.
   IloInt const firsteta = masterVars.getSize();
   for (BlockVector::size_type i = 0; i < blocks.size(); ++i) {
      std::stringstream s;
      s << "_eta" << i;
      IloNumVar eta(env, 0.0, IloInfinity, s.str().c_str());
      masterObj += eta;
      masterVars.add(eta);
   }

   // Create model and solver instance
   vars = masterVars;
   rows = masterRows;
   IloModel model(env);
   model.add(obj = IloObjective(env, masterObj, problem->getObjSense()));
   model.add(vars);
   model.add(rows);
   cplex = IloCplex(model);

   cplex.use(cb = new (env) LazyConstraintCallback(env, this, blocks,
                                              firsteta));

   for (IloExpr::LinearIterator it = obj.getLinearIterator(); it.ok(); ++it)
      objMap.insert(ObjMap::value_type(it.getVar(), it.getCoef()));
}
ILOSTLBEGIN

void makeCuts(IloRangeArray cuts, const IloNumVarArray& vars) {
   IloNumVar x11, x12, x13, x14, x15;
   IloNumVar x21, x22, x23, x24, x25;
   IloNumVar x31, x32, x33, x34, x35;
   IloNumVar x41, x42, x43, x44, x45;
   IloNumVar x51, x52, x53, x54, x55;
   IloNumVar w11, w12, w13, w14, w15;
   IloNumVar w21, w22, w23, w24, w25;
   IloNumVar w31, w32, w33, w34, w35;
   IloNumVar w41, w42, w43, w44, w45;
   IloNumVar w51, w52, w53, w54, w55;
   IloInt num = vars.getSize();
   for (IloInt i = 0; i < num; i++) {
      if      ( strcmp(vars[i].getName(), "X11") == 0 ) x11 = vars[i];
      else if ( strcmp(vars[i].getName(), "X12") == 0 ) x12 = vars[i];
      else if ( strcmp(vars[i].getName(), "X13") == 0 ) x13 = vars[i];
      else if ( strcmp(vars[i].getName(), "X14") == 0 ) x14 = vars[i];
      else if ( strcmp(vars[i].getName(), "X15") == 0 ) x15 = vars[i];
      else if ( strcmp(vars[i].getName(), "X21") == 0 ) x21 = vars[i];
      else if ( strcmp(vars[i].getName(), "X22") == 0 ) x22 = vars[i];
      else if ( strcmp(vars[i].getName(), "X23") == 0 ) x23 = vars[i];
      else if ( strcmp(vars[i].getName(), "X24") == 0 ) x24 = vars[i];
      else if ( strcmp(vars[i].getName(), "X25") == 0 ) x25 = vars[i];
      else if ( strcmp(vars[i].getName(), "X31") == 0 ) x31 = vars[i];
      else if ( strcmp(vars[i].getName(), "X32") == 0 ) x32 = vars[i];
      else if ( strcmp(vars[i].getName(), "X33") == 0 ) x33 = vars[i];
      else if ( strcmp(vars[i].getName(), "X34") == 0 ) x34 = vars[i];
      else if ( strcmp(vars[i].getName(), "X35") == 0 ) x35 = vars[i];
      else if ( strcmp(vars[i].getName(), "X41") == 0 ) x41 = vars[i];
      else if ( strcmp(vars[i].getName(), "X42") == 0 ) x42 = vars[i];
      else if ( strcmp(vars[i].getName(), "X43") == 0 ) x43 = vars[i];
      else if ( strcmp(vars[i].getName(), "X44") == 0 ) x44 = vars[i];
      else if ( strcmp(vars[i].getName(), "X45") == 0 ) x45 = vars[i];
      else if ( strcmp(vars[i].getName(), "X51") == 0 ) x51 = vars[i];
      else if ( strcmp(vars[i].getName(), "X52") == 0 ) x52 = vars[i];
      else if ( strcmp(vars[i].getName(), "X53") == 0 ) x53 = vars[i];
      else if ( strcmp(vars[i].getName(), "X54") == 0 ) x54 = vars[i];
      else if ( strcmp(vars[i].getName(), "X55") == 0 ) x55 = vars[i];
      else if ( strcmp(vars[i].getName(), "W11") == 0 ) w11 = vars[i];
      else if ( strcmp(vars[i].getName(), "W12") == 0 ) w12 = vars[i];
      else if ( strcmp(vars[i].getName(), "W13") == 0 ) w13 = vars[i];
      else if ( strcmp(vars[i].getName(), "W14") == 0 ) w14 = vars[i];
      else if ( strcmp(vars[i].getName(), "W15") == 0 ) w15 = vars[i];
      else if ( strcmp(vars[i].getName(), "W21") == 0 ) w21 = vars[i];
      else if ( strcmp(vars[i].getName(), "W22") == 0 ) w22 = vars[i];
      else if ( strcmp(vars[i].getName(), "W23") == 0 ) w23 = vars[i];
      else if ( strcmp(vars[i].getName(), "W24") == 0 ) w24 = vars[i];
      else if ( strcmp(vars[i].getName(), "W25") == 0 ) w25 = vars[i];
      else if ( strcmp(vars[i].getName(), "W31") == 0 ) w31 = vars[i];
      else if ( strcmp(vars[i].getName(), "W32") == 0 ) w32 = vars[i];
      else if ( strcmp(vars[i].getName(), "W33") == 0 ) w33 = vars[i];
      else if ( strcmp(vars[i].getName(), "W34") == 0 ) w34 = vars[i];
      else if ( strcmp(vars[i].getName(), "W35") == 0 ) w35 = vars[i];
      else if ( strcmp(vars[i].getName(), "W41") == 0 ) w41 = vars[i];
      else if ( strcmp(vars[i].getName(), "W42") == 0 ) w42 = vars[i];
      else if ( strcmp(vars[i].getName(), "W43") == 0 ) w43 = vars[i];
      else if ( strcmp(vars[i].getName(), "W44") == 0 ) w44 = vars[i];
      else if ( strcmp(vars[i].getName(), "W45") == 0 ) w45 = vars[i];
      else if ( strcmp(vars[i].getName(), "W51") == 0 ) w51 = vars[i];
      else if ( strcmp(vars[i].getName(), "W52") == 0 ) w52 = vars[i];
      else if ( strcmp(vars[i].getName(), "W53") == 0 ) w53 = vars[i];
      else if ( strcmp(vars[i].getName(), "W54") == 0 ) w54 = vars[i];
      else if ( strcmp(vars[i].getName(), "W55") == 0 ) w55 = vars[i];
   }
   cuts.add(x21 - x22 <= 0);
   cuts[0].setName("cut0");
   cuts.add(x22 - x23 <= 0);
   cuts.add(x23 - x24 <= 0);
   cuts.add(2.08*x11 + 2.98*x21 + 3.47*x31 + 2.24*x41 + 2.08*x51 + 0.25*w11 +
            0.25*w21 + 0.25*w31 + 0.25*w41 + 0.25*w51 <= 20.25);
   cuts.add(2.08*x12 + 2.98*x22 + 3.47*x32 + 2.24*x42 + 2.08*x52 + 0.25*w12 +
            0.25*w22 + 0.25*w32 + 0.25*w42 + 0.25*w52 <= 20.25);
   cuts.add(2.08*x13 + 2.98*x23 + 3.4722*x33 + 2.24*x43 + 2.08*x53 + 0.25*w13
            + 0.25*w23 + 0.25*w33 + 0.25*w43 + 0.25*w53 <= 20.25);
   cuts.add(2.08*x14 + 2.98*x24 + 3.47*x34 + 2.24*x44 + 2.08*x54 + 0.25*w14 +
            0.25*w24 + 0.25*w34 + 0.25*w44 + 0.25*w54 <= 20.25);
   cuts.add(2.08*x15 + 2.98*x25 + 3.47*x35 + 2.24*x45 + 2.08*x55 + 0.25*w15 +
            0.25*w25 + 0.25*w35 + 0.25*w45 + 0.25*w55 <= 16.25);
}
예제 #24
0
/** 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;
}
예제 #25
0
/** Solve the <code>problem</code> using a distributed implementation of
 * Benders' decomposition.
 */
bool
BendersOpt::solve (Problem const *problem,
                   int argc, char const *const *argv,
                   std::vector<char const *> const &machines)
{
   IloEnv env = problem->getModel().getEnv();

   std::vector<Block *> blocks;
   Block *master = 0;
   bool result = false;
   try {
      // Extract blocks and master problem.
      std::cout << "Extracting " << problem->getNBlocks() << " blocks."
                << std::endl;
      for (IloInt b = 0; b < problem->getNBlocks(); ++b)
         blocks.push_back(new Block(problem, b, argc, argv, machines));
      master = new Block(problem, blocks);

      // Write out the master and all blocks (for debugging).
      master->cplex.exportModel("master.lp");
      for (BlockVector::size_type b = 0; b < blocks.size(); ++b) {
         std::stringstream s;
         s << "block" << b << ".lp";
         blocks[b]->cplex.exportModel(s.str().c_str());
      }

      // Solve the master.
      // If we find a feasible solution then perform a final solve
      // with the original problem so that we get solution values for
      // all variables in the original problem.
      if ( master->cplex.solve() ) {
         // Perform a last solve to get the solution values.
         IloNumArray vals(env), startVals(env);
         IloNumVarArray startVars(env);
         master->cplex.getValues(vals, master->vars);
         IloCplex cplex(problem->getModel());
         // Fix integral variables to their value in the master solution
         // and add them as MIP start.
         for (IloInt i = 0; i < vals.getSize(); ++i)
            if ( master->vars[i].getType() != IloNumVar::Float ) {
               double const v = IloRound(vals[i]);
               IloNumVar x = master->varMap[master->vars[i]];
               startVals.add(v);
               startVars.add(x);
               // We add lazy constraints so as to make sure that
               // - we don't modify the original model
               // - the problem has only the unique optimal solution
               //   we are interested in
               cplex.addLazyConstraint(x == v);
            }
         cplex.addMIPStart(startVars, startVals);
         cplex.solve();

         // Report the results.
         std::cout << "#### Problem solved (" << cplex.getObjValue() << ", "
                   << cplex.getCplexStatus() << ")." << std::endl;
         IloNumVarArray vars = problem->getVariables();
         for (IloInt i = 0; i < vars.getSize(); ++i)
            std::cout << "#### \tx[" << i << "] = " << cplex.getValue(vars[i])
                      << std::endl;
         cplex.end();
         result = true;
      }
   } catch (...) {
      if ( master )
         delete master;
      while ( blocks.size() > 0 ) {
         delete blocks.back();
         blocks.pop_back();
      }
      throw;
   }

   delete master;
   while ( blocks.size() > 0 ) {
      delete blocks.back();
      blocks.pop_back();
   }

   return result;
}
예제 #26
0
ILOBRANCHCALLBACK1(SOSbranch, IloSOS1Array, sos) {
    IloNumArray    x;
    IloNumVarArray var;

    try {
        IloInt i;
        x   = IloNumArray(getEnv());
        var = IloNumVarArray(getEnv());
        IloNum bestx = EPS;
        IloInt besti = -1;
        IloInt bestj = -1;
        IloInt num = sos.getSize();

        for (i = 0; i < num; i++) {
            if ( getFeasibility(sos[i]) == Infeasible ) {
                var.clear();
                sos[i].getVariables(var);
                getValues(x, var);
                IloInt n = var.getSize();
                for (IloInt j = 0; j < n; j++) {
                    IloNum inf = IloAbs(x[j] - IloRound(x[j]));
                    if ( inf > bestx ) {
                        bestx = inf;
                        besti = i;
                        bestj = j;
                    }
                }
            }
        }

        if ( besti >= 0 ) {
            IloCplex::BranchDirectionArray dir;
            IloNumArray                    val;
            try {
                dir = IloCplex::BranchDirectionArray(getEnv());
                val = IloNumArray(getEnv());
                var.clear();
                sos[besti].getVariables(var);
                IloInt n = var.getSize();
                for (IloInt j = 0; j < n; j++) {
                    if ( j != bestj ) {
                        dir.add(IloCplex::BranchDown);
                        val.add(0.0);
                    } else {
                        dir.add(IloCplex::BranchUp);
                        val.add(1.0);
                    }
                }
                makeBranch(var,        val, dir,                  getObjValue());
                makeBranch(var[bestj], 0.0, IloCplex::BranchDown, getObjValue());
            }
            catch (...) {
                dir.end();
                val.end();
                throw;
            }
            dir.end();
            val.end();
        }
    }
    catch (...) {
        var.end();
        x.end();
        throw;
    }

    var.end();
    x.end();
}