ILOCPLEXGOAL1(MyBranchGoal, IloNumVarArray, vars) {
   IloNumArray x;
   IloNumArray obj;
   IntegerFeasibilityArray feas;

   x    = IloNumArray(getEnv());
   obj  = IloNumArray(getEnv());
   feas = IntegerFeasibilityArray(getEnv());
   getValues(x, vars);
   getObjCoefs(obj, vars);
   getFeasibilities(feas, vars);

   IloInt bestj  = -1;
   IloNum maxinf = 0.0;
   IloNum maxobj = 0.0;
   IloInt cols = vars.getSize();
   for (IloInt j = 0; j < cols; j++) {
      if ( feas[j] == Infeasible ) {
         IloNum xj_inf = x[j] - IloFloor (x[j]);
         if ( xj_inf > 0.5 )
            xj_inf = 1.0 - xj_inf;
         if ( xj_inf >= maxinf                             &&
             (xj_inf > maxinf || IloAbs (obj[j]) >= maxobj)  ) {
            bestj  = j;
            maxinf = xj_inf;
            maxobj = IloAbs (obj[j]);
         }
      }
   }

   IloCplex::Goal res;
   if ( bestj >= 0 ) {
      res = AndGoal(OrGoal(vars[bestj] >= IloFloor(x[bestj])+1,
                           vars[bestj] <= IloFloor(x[bestj])),
                    this);
   }

   x.end();
   obj.end();
   feas.end();

   return res;
}
Beispiel #2
0
ILOBRANCHCALLBACK1(MyBranch, IloNumVarArray, vars) {
   if ( getBranchType() != BranchOnVariable )
      return;

   // Branch on var with largest objective coefficient
   // among those with largest infeasibility

   IloNumArray x;
   IloNumArray obj;
   IntegerFeasibilityArray feas;

   try {
      x    = IloNumArray(getEnv());
      obj  = IloNumArray(getEnv());
      feas = IntegerFeasibilityArray(getEnv());
      getValues(x, vars);
      getObjCoefs(obj, vars);
      getFeasibilities(feas, vars);

      IloInt bestj  = -1;
      IloNum maxinf = 0.0;
      IloNum maxobj = 0.0;
      IloInt cols = vars.getSize();
      for (IloInt j = 0; j < cols; j++) {
         if ( feas[j] == Infeasible ) {
            IloNum xj_inf = x[j] - IloFloor (x[j]);
            if ( xj_inf > 0.5 )
               xj_inf = 1.0 - xj_inf;
            if ( xj_inf >= maxinf                              &&
                 (xj_inf > maxinf || IloAbs (obj[j]) >= maxobj)  ) {
               bestj  = j;
               maxinf = xj_inf;
               maxobj = IloAbs (obj[j]);
            }
         }
      }

      if ( bestj >= 0 ) {
         makeBranch(vars[bestj], x[bestj], IloCplex::BranchUp,   getObjValue());
         makeBranch(vars[bestj], x[bestj], IloCplex::BranchDown, getObjValue());
      }
   }
   catch (...) {
      x.end();
      obj.end();
      feas.end();
      throw;
   }
   x.end();
   obj.end();
   feas.end();
}
int main(int argc, const char* argv[]){
  IloEnv env;
  try {
    const char* filename = "../../../examples/data/learningeffect_default.data";
    IloInt failLimit = IloIntMax;
    if (argc > 1)
      filename = argv[1];
    if (argc > 2)
      failLimit = atoi(argv[2]);
    std::ifstream file(filename);
    if (!file){
      env.out() << "usage: " << argv[0] << " <file> <failLimit>" << std::endl;
      throw FileError();
    }

    IloModel model(env);
    IloInt nbJobs, nbMachines;
    file >> nbJobs;
    file >> nbMachines;
    IloIntervalVarArray2 machines(env, nbMachines);
    IloIntArray2 sizes(env, nbMachines);
    for (IloInt j = 0; j < nbMachines; j++) {
      machines[j] = IloIntervalVarArray(env);
      sizes[j] = IloIntArray(env);
    }
    IloIntExprArray ends(env);
    for (IloInt i = 0; i < nbJobs; i++) {
      IloIntervalVar prec;
      for (IloInt j = 0; j < nbMachines; j++) {
        IloInt m, d;
        file >> m;
        file >> d;
        IloIntervalVar ti(env);
        machines[m].add(ti);
        sizes[m].add(d);
        if (0 != prec.getImpl())
          model.add(IloEndBeforeStart(env, prec, ti));
        prec = ti;
      }
      ends.add(IloEndOf(prec));
    }
    for (IloInt j = 0; j < nbMachines; j++) {
      IloInt lef;
      file >> lef;
      IloNum alpha = lef/100.0;
      IloIntervalVarArray chain(env);
      IloIntVarArray indices(env);
      IloIntervalVar prec;
      for(IloInt i = 0; i < nbJobs; ++i) {
        IloIntervalVar ti = machines[j][i];
        IloInt d = sizes[j][i];
        ti.setSizeMax(d);
        // Building of the chain of intervals for the machine.
        IloIntervalVar syncti(env);
        if (prec.getImpl()) 
          model.add(IloEndBeforeStart(env, prec, syncti));
        prec = syncti;
        IloIntVar index(env, 0, nbJobs - 1);
        // Learning effect captured by the decreasing function
        // of the position (0 <= alpha <= 1).
        // At first position in the sequence index = 0; there is no
        // learning effect and duration of the task is its nominal duration
        model.add(IloSizeOf(ti) == IloFloor(IloNum(d)*IloPower(alpha, index)));
        chain.add(syncti);
        indices.add(index);
      }
      model.add(IloIsomorphism(env, chain, machines[j], indices, nbJobs));

      // The no-overlap is a redundant constraint in this quite simple
      // model - it is used only to provide stronger inference.
      model.add(IloNoOverlap(env, machines[j]));
    }
    IloObjective objective = IloMinimize(env,IloMax(ends));
    model.add(objective);
    
    IloCP cp(model);
    cp.setParameter(IloCP::FailLimit, failLimit);
    cp.setParameter(IloCP::LogPeriod, 10000);
    cp.out() << "Instance \t: " << filename << std::endl;
    if (cp.solve()) {
      cp.out() << "Makespan \t: " << cp.getObjValue() << std::endl;
    } else {
      cp.out() << "No solution found."  << std::endl;
    }
  } catch(IloException& e){
    env.out() << " ERROR: " << e << std::endl;
  }
  env.end();
  return 0;
}