Decision Optimization

Decision Optimization

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


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
  • 1.  As do a little planning workers?

    Posted 07/13/15 01:10 PM

    Originally posted by: JuanCarlosPego


    Hello, I need to do a little exercise to make a calendar. I have the following shifts for 1 months
     

    start           end             chief      workers
    08:00        12:00           2            4
    12:00        16:00           3            6
    16:00         20:00          4            8


    I have to try to cover all shifts with N workers with the following restrictions:

    - One shift per day.
    - Not more than 40 hours every 7 days.
    - No more than 162 hours in the month.

    I do not know how to do it ?. IloPack I can use?

     

    Need help, thank you very much


    #CPOptimizer
    #DecisionOptimization


  • 2.  Re: As do a little planning workers?

    Posted 07/15/15 03:56 AM

    Originally posted by: JuanCarlosPego


    Please, any ideas.

     

    thank you very much.

     

    Juan Carlos

     


    #CPOptimizer
    #DecisionOptimization


  • 3.  Re: As do a little planning workers?

    Posted 07/16/15 04:15 AM

    Originally posted by: JuanCarlosPego


    With which tool would be better, CPLEX or CP Optimizer, any suggestions please.

     

    A small example with which to start?

     

    thank you very much.

     

    Juan Carlos


    #CPOptimizer
    #DecisionOptimization


  • 4.  Re: As do a little planning workers?

    Posted 07/16/15 10:42 AM

    Originally posted by: ol


    Hello,

    the answer to which solver to use depends on the precise problem you want to solve. From the very small description you did, CP Optimizer with interval variables seems a good candidate to me. You can have a look at the different scheduling examples provided with the product.

    In CP Optimizer with integer variables you should be able to express easily your problem  (although I do not see what you have in mind with IloPack). Maybe this is a good starting point to clarify the constraint model, and possibly to move later to interval variables or CPLEX.

    Regards,

    Olivier


    #CPOptimizer
    #DecisionOptimization


  • 5.  Re: As do a little planning workers?

    Posted 08/03/15 06:54 AM

    Originally posted by: JuanCarlosPego


    Hi, Oliver, thank you for answering me,

     

    This is a small example of what I try to do.

    I need to cover ten activities with a maximum capacity of 2 employees each. Each employee is a different specialty.
    But when I try to get EI index of activity each employee assigned to the same employee returns me to the two slots.

    I need to get the index of activities to limit the working time and the possible incompatibilities between employees.

     

    this is my code

    *****

    int EjemploPregunta()
        {
            
            typedef IloArray<IloIntVarArray>    IloIntVarArray2;
            
            // FILE LOG
            ofstream salida("Log1.txt");
            
            IloEnv env;
            try
            {
                IloModel model(env);
                IloInt i, j, t, f, g, k;
                IloInt NEmployees=20;           // Total number of employees
                IloInt NTasks=10;                // Total number of activities to cover
                IloInt NCantTask=2;                // Number of employees by activity

                IloIntArray ArrayBoss(env,10,0,1,2,3,4,5,6,7,8,9);
                IloIntArray ArrayEmployee(env,10,10,11,12,13,14,15,16,17,18,19);

                IloIntArray ArrayBeginAct(env,10,18,21,31,31,33,35,36,39,45,46);
                IloIntArray ArrayEndAct(env,10,37,40,68,68,53,40,68,47,83,83);

            
                // Array for specialties (0=BOSS,1=EMPLOYEE)
                IloIntArray ArrayEmp_B_E(env, NEmployees);

                for (IloInt i=0;i<ArrayBoss.getSize();i++){
                        ArrayEmp_B_E[i]=0;
                }
                for (IloInt i=0;i<ArrayBoss.getSize();i++){
                        ArrayEmp_B_E[i]=1;
                }

                
                // Variable to cover activities
                
                IloIntVarArray2 VarActivities(env, NTasks);
                for(i = 0; i < NTasks; i++)
                {
                    VarActivities[i] = IloIntVarArray(env, NCantTask,0,NEmployees);
                    
                }
                
                // Variable activities per employee
                
                IloIntVarArray2 EmpActivity(env, NEmployees);

                for(i = 0; i < NEmployees; i++)
                {
                    EmpActivity[i] = IloIntVarArray(env, NTasks,-1,NTasks);
                }

                for(i = 0; i < NEmployees; i++)
                {
                    for(j = 0; j < NTasks; j++)
                    {
                        for(k = 0; k < NCantTask; k++){
                            // I need to get the index of activity
                            model.add(IloIfThen(env, VarActivities[j][k] == i, EmpActivity[i][VarActivities[j][k]]==j));
                        }
                    }
                }
                
        
                // *** If no solution is uncommented  ***

                // each activity will exist as much a boss and an employee
                /*for(i = 0; i < NTasks; i++){
                    IloIntVarArray TrpPM_COVar(env, 2, 0, NEmployees - 1);
                    for (j = 0; j < 2; j++){
                        model.add(TrpPM_COVar[j] == ArrayEmp_B_E[VarActivities[i][j]]);
                    }

                    for (j = 0; j < 2; j++){
                        model.add(IloCount(TrpPM_COVar, j) <= 1);
                    }
                            
                }*/
                
                
                IloExpr Obj_Func_2(env);
                for (i = 0; i < NTasks; ++i)
                {
                    for (j = 0; j < 2; ++j)
                    {
                        Obj_Func_2 += VarActivities[i][j];
                    }
                }
                model.add( IloMaximize(env,Obj_Func_2) );

                

                /* ---------------------------------------EXTRACTING THE MODEL AND SOLVING-----------------------------------------. */
                //Call to Ilog Optimizer
                IloCP cp(model);
                cp.setParameter(IloCP::TimeLimit, 5);
                cp.setParameter(IloCP::LogPeriod, 10000);
                if (cp.solve())
                {
                    cp.out() <<std::endl;
                    cp.out() <<std::endl;
                    cp.out() << "SOLUTION.... " << std::endl;
                    salida << "Solution : " << std::endl;
                    salida <<std::endl;

                    salida << "     ";
                    salida<< "Activities and employees assigned :"<<std::endl;
                    salida<< std::endl;

                    for(j = 0; j < NCantTask; j++){
                            salida <<"   Task "<<j<<" ";
                    }
                    salida<< std::endl;
                    
                    for(i = 0; i < NTasks; i++)
                    {
                        salida << " " << i+1 << ":  ";
                        for(j = 0; j < NCantTask; j++){
                            salida <<"("<<cp.getValue(VarActivities[i][j])<<")"<<"    ";
                        }
                        salida<< std::endl;
                    }
                    salida<< std::endl;
                    salida<< std::endl;
                    salida<< "Employees and assigned activities :"<<std::endl;
                    int id_actividad=0;
                    for(i = 0; i < NEmployees; i++)
                    {
                        salida << " " << i << ":  ";
                        
                        for(j = 0; j < NTasks; j++)
                        {
                            id_actividad=cp.getValue(EmpActivity[i][j]);
                            if (id_actividad>=0){
                                salida <<id_actividad+1<< "   ";
                            }
                        }

                        salida<< std::endl;
                    }

                
                }
                else
                {
                    cp.out() << "No solution found. " << std::endl;
                }

            }catch (IloException& ex)
            {
                env.out() << "Error: " << ex << std::endl;
            }
            
            env.end();

            return 0;
        }

    ***

     

    Thank you very much!

    Juan Carlos

     

     


    #CPOptimizer
    #DecisionOptimization


  • 6.  Re: As do a little planning workers?

    Posted 08/04/15 03:39 AM

    Originally posted by: JuanCarlosPego


    Sorry, there is a small error:

              for (IloInt i=0;i<ArrayBoss.getSize();i++){
                        ArrayEmp_B_E[i]=0;
                }
                for (IloInt i=0;i<ArrayBoss.getSize();i++){
                        ArrayEmp_B_E[i]=1;
                }

     

    should be:

              for (IloInt i=0;i<ArrayBoss.getSize();i++){
                        ArrayEmp_B_E[i]=0;
                }
                for (IloInt i=0;i<ArrayEmployee.getSize();i++){
                        ArrayEmp_B_E[i]=1;
                }

     

    Add, if uncommented the piece
     

     // *** If no solution is uncommented  ***

    ...


    is not the solution.

     

     Please, any ideas.

     

    thank you very much.

     

    Juan Carlos

     

     


    #CPOptimizer
    #DecisionOptimization


  • 7.  Re: As do a little planning workers?

    Posted 08/04/15 10:32 AM

    Originally posted by: ol


    Hello Juan Carlos,

    yes there is some errors in your code, even in your correction above: probably you want the second loop to iterate over the indices ArrayBoss.getSize() to ArrayBoss.getSize() + ArrayEmployee.getSize() -1, don't you?

     

    The 2nd dimension of EmpActivity is tasks, but in your code you fill it with VarActivities[j][k] which is not a task but an employee.

    It is not simple to understand such a confusing code, so explain clearly what you want to do if you want someone can help you.

     

    In your explanation:

         "But when I try to get EI index of activity each employee assigned to the same employee returns me to the two slots "

    What do you mean?

     

    .


    #CPOptimizer
    #DecisionOptimization


  • 8.  Re: As do a little planning workers?

    Posted 08/04/15 11:16 AM

    Originally posted by: JuanCarlosPego


    Hello Olivier, sorry for not explaining well but my English is not good.

    copy the code again:

    int EjemploPregunta()
        {
            
            typedef IloArray<IloIntVarArray>    IloIntVarArray2;
            
            // FILE LOG
            ofstream salida("Log1.txt");
            
            IloEnv env;
            try
            {
                IloModel model(env);
                IloInt i, j, t, f, g, k;
                IloInt NEmployees=20;           // Total number of employees
                IloInt NActivities=10;                // Total number of activities to cover
                IloInt NCantEmpPerAct=2;                // Number of employees by activity

                IloIntArray ArrayBoss(env,10,0,1,2,3,4,5,6,7,8,9);
                IloIntArray ArrayEmployee(env,10,10,11,12,13,14,15,16,17,18,19);

                IloIntArray ArrayBeginAct(env,10,18,21,31,31,33,35,36,39,45,46);
                IloIntArray ArrayEndAct(env,10,37,40,68,68,53,40,68,47,83,83);

            
                // Array for specialties (0=BOSS,1=EMPLOYEE)
                IloIntArray ArrayEmp_B_E(env, NEmployees);

                for (IloInt i=0;i<ArrayBoss.getSize();i++){
                        ArrayEmp_B_E[i]=0;
                }
                for (IloInt i=0;i<ArrayEmployee.getSize();i++){
                        ArrayEmp_B_E[i]=1;
                }

                
                // Variable to cover activities
                
                IloIntVarArray2 VarActivities(env, NActivities);
                for(i = 0; i < NActivities; i++)
                {
                    VarActivities[i] = IloIntVarArray(env, NCantEmpPerAct,0,NEmployees);
                    
                }
                
                // Variable activities per employee
                
                IloIntVarArray2 EmpActivity(env, NEmployees);

                for(i = 0; i < NEmployees; i++)
                {
                    EmpActivity[i] = IloIntVarArray(env, NActivities,-1,NActivities);
                }

                for(i = 0; i < NEmployees; i++)
                {
                    for(j = 0; j < NActivities; j++)
                    {
                        for(k = 0; k < NCantEmpPerAct; k++){
                            // I need to get the index of activity
                            model.add(IloIfThen(env, VarActivities[j][k] == i, EmpActivity[i][VarActivities[j][k]]==j));
                        }
                    }
                }
                
        
                // *** If no solution is uncommented  ***

                // each activity will exist as much a boss and an employee
                /*for(i = 0; i < NActivities; i++){
                    IloIntVarArray TrpPM_COVar(env, 2, 0, NEmployees - 1);
                    for (j = 0; j < 2; j++){
                        model.add(TrpPM_COVar[j] == ArrayEmp_B_E[VarActivities[i][j]]);
                    }

                    for (j = 0; j < 2; j++){
                        model.add(IloCount(TrpPM_COVar, j) <= 1);
                    }
                            
                }*/
                
                
                IloExpr Obj_Func_2(env);
                for (i = 0; i < NActivities; ++i)
                {
                    for (j = 0; j < 2; ++j)
                    {
                        Obj_Func_2 += VarActivities[i][j];
                    }
                }
                model.add( IloMaximize(env,Obj_Func_2) );

                

                /* ---------------------------------------EXTRACTING THE MODEL AND SOLVING-----------------------------------------. */
                //Call to Ilog Optimizer
                IloCP cp(model);
                cp.setParameter(IloCP::TimeLimit, 5);
                cp.setParameter(IloCP::LogPeriod, 10000);
                if (cp.solve())
                {
                    cp.out() <<std::endl;
                    cp.out() <<std::endl;
                    cp.out() << "SOLUTION.... " << std::endl;
                    salida << "Solution : " << std::endl;
                    salida <<std::endl;

                    salida << "     ";
                    salida<< "Activities and employees assigned :"<<std::endl;
                    salida<< std::endl;

                    for(j = 0; j < NCantEmpPerAct; j++){
                            salida <<"     IdEmp"<<j+1<<" ";
                    }
                    salida<< std::endl;
                    
                    for(i = 0; i < NActivities; i++)
                    {
                        salida << " " << i+1 << ":  ";
                        for(j = 0; j < NCantEmpPerAct; j++){
                            salida <<"    ("<<cp.getValue(VarActivities[i][j])<<")"<<"    ";
                        }
                        salida<< std::endl;
                    }
                    salida<< std::endl;
                    salida<< std::endl;
                    salida<< "Employees and assigned activities :"<<std::endl;
                    int id_actividad=0;
                    for(i = 0; i < NEmployees; i++)
                    {
                        salida << " " << i << ":  ";
                        
                        for(j = 0; j < NActivities; j++)
                        {
                            id_actividad=cp.getValue(EmpActivity[i][j]);
                            if (id_actividad>=0){
                                salida <<id_actividad+1<< "   ";
                            }
                        }

                        salida<< std::endl;
                    }

                
                }
                else
                {
                    cp.out() << "No solution found. " << std::endl;
                }

            }catch (IloException& ex)
            {
                env.out() << "Error: " << ex << std::endl;
            }
            
            env.end();

            return 0;
        }

     

    probably you want the second loop to iterate over the indices ArrayBoss.getSize() to ArrayBoss.getSize() + ArrayEmployee.getSize() -1, don't you?

    the answer is yes.

     

    I need to get the ID of all activities where each employee is assigned. For example, the solution is now this

     

    Solution :

         Activities and employees assigned :

         IdEmp1      IdEmp2
     1:      (4)        (4)    
     2:      (3)        (3)    
     3:      (5)        (5)    
     4:      (7)        (7)    
     5:      (1)        (1)    
     6:      (6)        (6)    
     7:      (8)        (8)    
     8:      (2)        (2)    
     9:      (9)        (9)    
     10:      (0)        (0)    


    Employees and assigned activities :
     0:  10   
     1:  5   
     2:  8   
     3:  2   
     4:  1   
     5:  3   
     6:  6   
     7:  4   
     8:  7   
     9:  9   
     10:  
     11:  
     12:  
     13:  
     14:  
     15:  
     16:  
     17:  
     18:  
     19: 

    ********************

    and try to find the solution that is:

    Solution :

         Activities and employees assigned :

         IdEmp1      IdEmp2
     1:      (1)        (10)    
     2:      (2)        (11)    
     3:      (3)        (12)    
     4:      (4)        (13)    
     5:      (5)        (14)    
     6:      (6)        (15)    
     7:      (7)        (16)    
     8:      (1)        (17)    
     9:      (2)        (10)    
     10:      (3)        (11)    


    Employees and assigned activities :
     0:     
     1:  1,8   
     2:  2,9   
     3:  3,10   
     4:  4   
     5:  5   
     6:  6   
     7:  7   
     8:     
     9:     
     10: 1,9
     11: 2,10
     12: 3
     13: 4
     14: 5
     15: 6
     16: 7
     17:  
     18:  
     19: 

     

    Thank you very much and sorry

    Juan Carlos

     


    #CPOptimizer
    #DecisionOptimization


  • 9.  Re: As do a little planning workers?

    Posted 08/05/15 09:24 AM

    Originally posted by: ol


    Hello,

    there are many possible approaches, here is a sketch of a simple approach that seems to be compatible with all the features you mentioned.

    Let Tasks be the range 0 .. nbTasks-1
    Let Boss be the range 0 .. nbBoss-1
    let Employees be the range 0 .. nbEmployees-1

    Let B[Tasks] an int var array giving for each task the boss associated with it: the domain of B[i] is Boss.
    Let Emp[Tasks] an int var array giving for each task the employee associated with it: the domain of Emp[i] is Employees.

    As all the tasks are already scheduled, it is easy (e.g. by sorting) to compute which pairs of tasks overlap.

    Then, for an overlapping pair of tasks (i,j) you need to add the constraints:
       B[i] != B[j]
    and
       Emp[i] != Emp[j]

    In your first post in this thread you wrote that you want to constrain the working time of the workers. You can do this by summing the durations of the tasks involving the workers. For example, you will need summing over the tasks of each week if you need to constraint the working time per week.

    Hope it helps,
    Regards,
    Olivier


    #CPOptimizer
    #DecisionOptimization