Decision Optimization

Decision Optimization

Delivers prescriptive analytics capabilities and decision intelligence to improve decision-making.


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
  • 1.  Crew scheduling problem

    Posted 06/11/12 07:48 AM

    Originally posted by: Dmartinc


    Hi all,

    I am having some issue when I am solving a crew scheduling problem, simply when cplex is solving the model it stops without giving
    me any error or anything. After researching the code, I think the problem is related to the soft constraint of the problem. However,
    I don´t figure out where is the mistake. Please find attached the code, in case someone is able to find the mistake and help me.

    thank you
    {
    //Minimize cost of changes
    IloExpr Obj_Func_1(env);
    for (i = 0; i < MEmployees; ++i)
    {
    for (j = 0; j < NTasks; ++j)
    {
    Obj_Func_1 += c[i][j] * y[i][j];
    }
    }
    IloExpr Obj_Func_2 (env);
    for(i=0;i<G_workers; ++i)
    {
    Obj_Func_2 += (Underpaid_rate[i]*Underpaid[i]+Overpaid_rate[i]*Overpaid[i]-OverWorkDays[i]);
    }
    model.add(IloMinimize(env, Obj_Func_1+Obj_Func_2));
    Obj_Func_1.end();
    Obj_Func_2.end();
    //All tasks must be covered
    for(j = 0; j < NTasks; j++)
    {
    IloExpr Cover_tasks(env);
    for(i = 0; i < MEmployees; i++)
    {
    Cover_tasks += z[i][j];
    }
    model.add(Cover_tasks == 1);
    Cover_tasks.end();
    }

    //Crew cannot be assigned overlapping tasks
    for(i=0; i<MEmployees; ++i)
    {

    for(f=0; f<NTasks; ++f)
    {
    for(g=0; g<NTasks; ++g)
    {
    if(Start_Time[g]>=Start_Time[f])
    {
    IloExpr Overlap(env);
    Overlap = M*(y[i][f]+y[i][g]-2);
    model.add(Overlap<=Start_Time[g] - (Start_Time[f]+Duration[f]));
    Overlap.end();
    }
    }
    }

    }

    //Minimum experience level over certain group of tasks
    for(k=0;k<KProjects;++k)
    {
    IloExpr Experience(env);
    for(i=0; i<MEmployees; ++i)
    {
    for(j=0; j<Project[k]; ++j)
    {
    Experience += Experience_score[i][j]*z[i][j];
    }
    }
    model.add(Experience>=Min_experience[k]);
    Experience.end();
    }

    //Constraints on consecutive working days
    /*for(i=0; i<MEmployees; i++)
    {
    for(b=0; b < NTasks ; b++)
    {
    IloExpr ConWorkDays(env);
    ConWorkDays = Accumulated_Work[i]b-1+z[i][b]*LimNumConsDays[b];
    model.add(ConWorkDays <= Accumulated_Work[i][b]);
    ConWorkDays.end();
    }
    }

    //Guarantee of rest periods for crew
    for(i=0; i<MEmployees; i++)
    {
    for(b=0; b < NTasks ; b++)
    {
    IloExpr ConRestDays(env);
    ConRestDays = Rest_Work[i]b-1+z[i][b]*MinNumRestDays[b];
    model.add(ConRestDays <= Rest_Work[i][b]);
    ConRestDays.end();
    }
    }

    //Calculation of any undertime payments
    for(i=0; i<G_workers; i++)
    {
    IloNumExprArg Sum;
    for(j=0; j<NTasks; j++)
    {
    Sum = Sum + Duration[j]*z[i][j];
    }
    model.add(Underpaid[i]>=Guaranteed_Days[i]-(OverWorkDays[i]+Sum));
    }

    //Calculation of any overtime payments
    for(i=0; i<G_workers; i++)
    {
    IloNumExprArg Sum;
    for(j=0; j<NTasks; j++)
    {
    Sum = Sum + Duration[j]*z[i][j];
    }
    model.add(Overpaid[i]>=(OverWorkDays[i]+Sum)-Guaranteed_Days[i]);
    }*/

    for(i=0; i<MEmployees; i++)
    {
    for(j=0; j<NTasks; j++)
    {
    if(x[i][j]==0)
    {
    model.add(z[i][j] == x[i][j]+y[i][j]);
    }
    else
    {
    model.add(z[i][j] == x[i][j]-y[i][j]);
    }
    }
    }
    }
    #DecisionOptimization
    #MathematicalProgramming-General


  • 2.  Re: Crew scheduling problem

    Posted 06/11/12 08:20 AM

    Originally posted by: SystemAdmin


    I don't see you calling cplex.solve() in your code. Does the unexpected stop happen while building up the model or while actually solving it? Do you catch exceptions properly in your code? What do you mean by "CPLEX stops" anyway? Does your program stop? Does your program terminate unexpectedly? Could you show us the output that CPLEX produces?
    #DecisionOptimization
    #MathematicalProgramming-General


  • 3.  Re: Crew scheduling problem

    Posted 06/11/12 10:31 AM

    Originally posted by: Dmartinc


    Hi Daniel,

    First of all, sorry about having posted the rest of the code. As you said, the program terminate unexpectedly, which I don´t know exactly why. Why can this happen?

    Please find attached the whole code and data file.

    Cheers,

    David

    (#include <ilcplex/ilocplex.h>

    ILOSTLBEGIN

    typedef IloArray<IloNumArray> NumMatrix; //Coeffiecients matrix
    typedef IloArray<IloBoolVarArray> BoolVarMatrix; //Decision variable matrix
    int main(int argc, char** argv) {
    IloEnv env;
    try {

    IloInt i, j, b=2, t, f, g, M=t, k;
    IloInt MEmployees, NTasks, KProjects, G_workers;
    IloModel model(env);

    ifstream file("Data1.csv");

    file >> t;
    file.get();
    cout << "Time:" << t << endl;
    file >> NTasks;
    file.get();
    cout << "Number of tasks:" << NTasks << endl;
    file >> KProjects;
    file.get();
    cout << "Number of projects:" << KProjects << endl;
    file >> MEmployees;
    file.get();
    cout << "Number of Employees:" << MEmployees << endl;
    file >> G_workers;
    file.get();
    cout << "Number of guaranteed employees:" << G_workers << endl;
    //-----------------------------------------------Declaration of Variables and Coefficients-----------------------------------------------------------

    /*Decision varibles*/

    BoolVarMatrix y(env, MEmployees); //Decision variable related to change y[i][j] of Size MEmployees x NTasks
    for(i = 0; i < MEmployees; i++)
    {
    y[i] = IloBoolVarArray(env, NTasks);
    }
    BoolVarMatrix z(env, MEmployees); //Decision variable related to change y[i][j] of Size MEmployees x NTasks
    for(i = 0; i < MEmployees; i++)
    {
    z[i] = IloBoolVarArray(env, NTasks);
    }
    IloIntVarArray Underpaid(env, G_workers); //Underpaid decision variables
    IloIntVarArray Overpaid(env, G_workers); //Overpaid decision variables

    //Coefficients

    NumMatrix x(env, MEmployees); //current schedule x[i][j] of Size MEmployees x NTasks
    for(i = 0; i < MEmployees; i++)
    {
    x[i] = IloNumArray(env, NTasks);
    }
    NumMatrix c(env, MEmployees); //Cost coefficients
    for(i = 0; i < MEmployees; i++)
    {
    c[i] = IloNumArray(env, NTasks);
    }
    IloNumArray Start_Time(env, NTasks); //Start time of task j
    IloNumArray Duration(env, NTasks); //Duration time of task j
    IloNumArray Underpaid_rate(env, G_workers); //Underpaid cost coefficients
    IloNumArray Overpaid_rate(env, G_workers); //Overpaid cost coefficients
    IloNumArray Exp_Over_Under_time(env, G_workers); //Expected additional overtime or undertime costs for employee i according to the previous version of the schedule
    for(i = 0; i < MEmployees; i++)
    {
    Exp_Over_Under_time[i] = 0;
    }
    IloNumArray Project(env, KProjects); //Start time of task j
    NumMatrix Experience_score(env, MEmployees); //Experience score coefficients for employee i for task j
    for(i = 0; i < MEmployees; i++)
    {
    Experience_score[i] = IloNumArray(env, NTasks);
    }
    IloNumArray Min_experience(env, KProjects); //Minimum total experience required for Project K
    IloNumArray LimNumConsDays(env, MEmployees); //(w[i])Limit on the number of consecutive days working at sea for Employee i
    NumMatrix Accumulated_Work(env, KProjects); //Accumulated work value for employee i after consideration of all tasks up to and including b
    for(i = 0; i < KProjects; i++)
    {
    Accumulated_Work[i] = IloNumArray(env, G_workers);
    }
    IloNumArray MinNumRestDays(env, MEmployees); //Minimun number of resting days of Employee i
    NumMatrix Rest_Work(env, MEmployees); //(r[i])Rest work value for employee i after consideration of all tasks up to and including b
    for(i = 0; i < MEmployees; i++)
    {
    Rest_Work[i] = IloNumArray(env, b,0,1);
    }
    IloNumArray Guaranteed_Days(env, G_workers); //Working days by contract by employee i
    IloNumArray OverWorkDays(env, G_workers); //Number of days over the rest of the year outwith the time period being rescheduled
    IloNumArray Guaranteed_Workers(env, G_workers);
    //-----------------------------------------------Initilization--------------------------------------------------
    for (i=0;i<G_workers;i++)
    {
    file >> Guaranteed_Workers[i];
    file.get();
    }
    cout << "Guaranteed workers in the new schedule:" << Guaranteed_Workers << endl;

    for (j=0;j<NTasks;j++)
    {
    file >> Start_Time[j];
    file.get();
    }
    cout << "Tasks start time:" << Start_Time << endl;

    for (j=0;j<NTasks;j++)
    {
    file >> Duration[j];
    file.get();
    }
    cout << "Tasks duration:" << Duration << endl;

    for (j=0;j<MEmployees;j++)
    {
    file >> MinNumRestDays[j];
    file.get();
    }
    cout << "Minimum number of rest days:" << MinNumRestDays << endl;

    for (j=0;j<MEmployees;j++)
    {
    file >> LimNumConsDays[j];
    file.get();
    }
    cout << "Maximum number of working days:" << LimNumConsDays << endl;

    for (i=0;i<NTasks;i++)
    {
    for(int j=0;j<MEmployees;j++)
    {
    file >> x[i][j];
    file.get();
    }
    }
    cout << "Initial roster:" << x << endl << endl;

    for (i=0;i<NTasks;i++)
    {
    for(int j=0;j<MEmployees;j++)
    {
    file >> c[i][j];
    file.get();
    }
    }
    cout << "Change costs:" << c << endl << endl;

    for (j=0;j<G_workers;j++)
    {
    file >> Underpaid_rate[j];
    file.get();
    }
    cout << "Under paid rate:" << Underpaid_rate << endl ;

    for (j=0;j<G_workers;j++)
    {
    file >> Overpaid_rate[j];
    file.get();
    }
    cout << "Over paid rate:" << Overpaid_rate << endl ;
    for (j=0;j<G_workers;j++)
    {
    file >> OverWorkDays[j];
    file.get();
    }

    for (j=0;j<G_workers;j++)
    {
    file >> Guaranteed_Days[j];
    file.get();
    }
    cout << "Guaranteed days:" << Guaranteed_Days << endl ;
    for (i=0;i<1;i++)
    {
    for(int j=0;j<G_workers;j++)
    {
    file >> Accumulated_Work[i][j];
    file.get();
    }
    }
    cout << "Accumulated work:" << Accumulated_Work<< endl <<endl ;

    for (i=0;i<NTasks;i++)
    {
    for(int j=0;j<MEmployees;j++)
    {
    file >> Experience_score[i][j];
    file.get();
    }
    }
    cout << "Employees´ experience:" << Experience_score << endl <<endl ;

    for (j=0;j<KProjects;j++)
    {
    file >> Min_experience[j];
    file.get();
    }
    cout << "Minimum experience required:" << Min_experience<< endl <<endl ;
    //---------------------------------------------------Model------------------------------------------------------

    //Minimize cost of changes
    IloExpr Obj_Func_1(env);
    for (i = 0; i < MEmployees; ++i)
    {
    for (j = 0; j < NTasks; ++j)
    {
    Obj_Func_1 += c[i][j] * y[i][j];
    }
    }
    /*IloExpr Obj_Func_2 (env);
    for(i=0;i<G_workers; ++i)
    {
    Obj_Func_2 += (Underpaid_rate[i]*Underpaid[i]+Overpaid_rate[i]*Overpaid[i]-OverWorkDays[i]);
    } */
    model.add(IloMinimize(env, Obj_Func_1));
    // model.add(IloMinimize(env, Obj_Func_2));
    Obj_Func_1.end();
    //Obj_Func_2.end();

    //All tasks must be covered
    for(j = 0; j < NTasks; j++)
    {
    IloExpr Cover_tasks(env);
    for(i = 0; i < MEmployees; i++)
    {
    Cover_tasks += z[i][j];
    }
    model.add(Cover_tasks == 1);
    Cover_tasks.end();
    }

    //Crew cannot be assigned overlapping tasks
    for(i=0; i<MEmployees; ++i)
    {

    for(f=0; f<NTasks; ++f)
    {
    for(g=0; g<NTasks; ++g)
    {
    if(Start_Time[g]>=Start_Time[f])
    {
    IloExpr Overlap(env);
    Overlap = M*(y[i][f]+y[i][g]-2);
    model.add(Overlap<=Start_Time[g] - (Start_Time[f]+Duration[f]));
    Overlap.end();
    }
    }
    }

    }

    //Minimum experience level over certain group of tasks
    for(k=0;k<KProjects;++k)
    {
    IloExpr Experience(env);
    for(i=0; i<MEmployees; ++i)
    {
    for(j=0; j<Project[k]; ++j)
    {
    Experience += Experience_score[i][j]*z[i][j];
    }
    }
    model.add(Experience>=Min_experience[k]);
    Experience.end();
    }

    //Constraints on consecutive working days
    for(i=0; i<MEmployees; i++)
    {
    for(b=0; b < NTasks ; b++)
    {
    IloExpr ConWorkDays(env);
    ConWorkDays = Accumulated_Work[i]b-1+z[i][b]*LimNumConsDays[b];
    model.add(ConWorkDays <= Accumulated_Work[i][b]);
    ConWorkDays.end();
    }
    }

    //Guarantee of rest periods for crew
    for(i=0; i<MEmployees; i++)
    {
    for(b=0; b < NTasks ; b++)
    {
    IloExpr ConRestDays(env);
    ConRestDays = Rest_Work[i]b-1+z[i][b]*MinNumRestDays[b];
    model.add(ConRestDays <= Rest_Work[i][b]);
    ConRestDays.end();
    }
    }

    //Calculation of any undertime payments
    for(i=0; i<G_workers; i++)
    {
    IloNumExprArg Sum;
    for(j=0; j<NTasks; j++)
    {
    Sum = Sum + Duration[j]*z[i][j];
    }
    model.add(Underpaid[i]>=Guaranteed_Days[i]-(OverWorkDays[i]+Sum));
    }

    //Calculation of any overtime payments
    for(i=0; i<G_workers; i++)
    {
    IloNumExprArg Sum;
    for(j=0; j<NTasks; j++)
    {
    Sum = Sum + Duration[j]*z[i][j];
    }
    model.add(Overpaid[i]>=(OverWorkDays[i]+Sum)-Guaranteed_Days[i]);
    }

    for(i=0; i<MEmployees; i++)
    {
    for(j=0; j<NTasks; j++)
    {
    if(x[i][j]==0)
    {
    model.add(z[i][j] == x[i][j]+y[i][j]);
    }
    else
    {
    model.add(z[i][j] == x[i][j]-y[i][j]);
    }
    }
    }

    IloCplex cplex(env);
    cplex.extract(model);
    cplex.exportModel("ILP_VCSP_recovery.lp");
    cplex.solve();

    if ( !cplex.solve() ) {
    env.error() << "It is not possible to solve (Infeasible solution) :-(" << endl;
    throw ( -1 );
    }

    env.out() << "Is it optimal ? = " << cplex.getStatus() << endl;
    env.out() << "Elapsed time = " << env.getTime() << endl;
    env.out() << " - Solution: " << endl;
    for(i = 0; i < MEmployees; i++)
    {
    env.out() << " " << i << ": ";

    for(j = 0; j < NTasks; j++)
    {
    env.out() << cplex.getValue(y[i][j]) << "\t";
    }
    env.out() << endl;
    }

    env.out() << " Minimal Cost = " << cplex.getObjValue() << endl;
    }
    catch (IloException& e) {
    cerr << "ERROR: " << e.getMessage() << endl;
    }
    catch (...) {
    cerr << "Error" << endl;
    }
    env.end();
    return 0;
    } )
    #DecisionOptimization
    #MathematicalProgramming-General


  • 4.  Re: Crew scheduling problem

    Posted 06/17/12 08:47 AM

    Originally posted by: SystemAdmin


    Have you tried running your program through a debugger? This might give good information about why and where the program terminates.
    #DecisionOptimization
    #MathematicalProgramming-General