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; }
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; }