예제 #1
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
예제 #2
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();
}