Decision Optimization

 View Only
Expand all | Collapse all

Idle Time Calculation in sched_jobshop

  • 1.  Idle Time Calculation in sched_jobshop

    Posted Tue August 29, 2023 04:21 PM

    Hello! I'm starting to use cplex optimizer and i'm not being able to calculate the idle time in the model provided by cplex itself called sched_jobshop

    How can i calculate the idle time per machine? (starting time of work i in machine m - ending time of work i-1 in machine m). I would like to assume that i turn on the machines all at time 0 and therefore if the first activity of a machine only starts at time 3 then this counts as idle time also.

    using CP;

    int nbJobs = ...;

    int nbMchs = ...;

    range Jobs = 0..nbJobs-1;

    range Mchs = 0..nbMchs-1;

    // Mchs is used both to index machines and operation position in job

    tuple Operation {

      int mch; // Machine

      int pt;  // Processing time

    };

    Operation Ops[j in Jobs][m in Mchs] = ...;

    dvar interval itvs[j in Jobs][o in Mchs] size Ops[j][o].pt;

    dvar sequence mchs[m in Mchs] in all(j in Jobs, o in Mchs : Ops[j][o].mch == m) itvs[j][o];

    execute {

                 cp.param.FailLimit = 10000;

    }

    minimize max(j in Jobs) endOf(itvs[j][nbMchs-1]);

    subject to {

      forall (m in Mchs)

        noOverlap(mchs[m]);

      forall (j in Jobs, o in 0..nbMchs-2)

        endBeforeStart(itvs[j][o], itvs[j][o+1]);

    }

    execute {

      for (var j = 0; j <= nbJobs-1; j++) {

        for (var o = 0; o <= nbMchs-1; o++) {

          write(itvs[j][o].start + " ");

        }

        writeln("");

      }

    }

    data:

    nbJobs = 6;

    nbMchs = 6;

    Ops = [

     [ <5,4>, <1,3>, <4,3>, <3,2>, <0,1>, <2,2> ],

     [ <1,3>, <0,8>, <5,7>, <2,2>, <4,9>, <3,3> ],

     [ <3,1>, <4,9>, <1,9>, <0,7>, <5,5>, <2,5> ],

     [ <3,8>, <4,2>, <1,1>, <5,7>, <2,8>, <0,9> ],

     [ <1,6>, <3,2>, <4,5>, <5,5>, <0,3>, <2,1> ],

     [ <4,10>, <2,4>, <0,4>, <3,3>, <1,2>, <5,3> ]

    ];

    Thank you so much!



    ------------------------------
    Pedro Casal
    ------------------------------


  • 2.  RE: Idle Time Calculation in sched_jobshop

    Posted Thu August 31, 2023 10:12 AM

    Hi Pedro

    As you saw, one can access interval start and end in OplScript. In the following postprocess, I store the results in two matrices that I will use later to created sorted collections for start and end per machine. I then use collections methods first and item to compute the idle time

    Note that you could also complexify your model to define expressions using startOf and endOfPrev on the sequence variables, but this postprocess makes it lighter 

    David

    int astart[j in Jobs][o in Mchs];
    int aend[j in Jobs][o in Mchs];
    
    execute {
    
        for (var j in Jobs)
        for(var o in Mchs){
          astart[j][o] = itvs[j][o].start;
          aend[j][o] = itvs[j][o].end;
    
      }
    }
    
    sorted {int} startItvM[m in Mchs] = {  astart[j][o] | j in Jobs, o in Mchs : Ops[j][o].mch == m};
    sorted {int} endItvM[m in Mchs] = {  aend[j][o] | j in Jobs, o in Mchs : Ops[j][o].mch == m};
    
    assert forall(m in Mchs) card(startItvM[m]) == nbJobs;
    assert forall(m in Mchs) card(endItvM[m]) == nbJobs;
    
    int idleDuration[m in Mchs] = first(startItvM[m]) + sum(j in 1..nbJobs-1) ( item(startItvM[m], j) - item(endItvM[m], j-1) );
    
    execute{
      idleDuration;
    }


    ------------------------------
    David Gravot
    ------------------------------



  • 3.  RE: Idle Time Calculation in sched_jobshop

    Posted Fri September 01, 2023 11:05 AM

    Thank you so much for the help David!

    If i don't want to assume the initial time between 0 and the actual start of the first task of each machine as idle time, what would i change in the script?



    ------------------------------
    Pedro Casal
    ------------------------------



  • 4.  RE: Idle Time Calculation in sched_jobshop

    Posted Tue September 05, 2023 04:44 AM

    simply update the formula 

    int idleDuration[m in Mchs] =  sum(j in 1..nbJobs-1) ( item(startItvM[m], j) - item(endItvM[m], j-1)


    ------------------------------
    David Gravot
    ------------------------------



  • 5.  RE: Idle Time Calculation in sched_jobshop

    Posted Thu September 07, 2023 03:42 PM

    Thank you for offering such an excellent solution for calculating idle time in sched_jobshop. I truly appreciate your efforts. Your contribution has significantly improved our workflow efficiency, and your dedication to quality solutions is commendable. We look forward to more collaborations in the future.



    ------------------------------
    John Will
    ------------------------------



  • 6.  RE: Idle Time Calculation in sched_jobshop

    Posted Fri September 01, 2023 05:25 AM
    Edited by Olivier Lhomme Mon September 04, 2023 05:03 AM

    To complete the answer from David, as you use a sequence variable you can directly access the last interval variable of the sequence, hence its ending time with "mchs[m].last().end".
    Then, you need to substract the durations of the interval in the sequence: you can iterate over all the interval variables of the sequence with "s=mchs[m].first()" and "s=mchs[m].next(s)". 
    For example:
      
      

    execute {
      for (var m = 0; m < nbMchs; m++) {
        var s=mchs[m].first();
        var usage = 0;
        for(var i = 0; i < nbJobs; i++)
        {
          usage = usage + s.length;
          writeln(s);
          s=mchs[m].next(s) ;
        }
        writeln("Idle time for machine " + m + " = " + (mchs[m].last().end - usage));
      }
    }





    ------------------------------
    Olivier Lhomme
    ------------------------------



  • 7.  RE: Idle Time Calculation in sched_jobshop

    Posted Fri September 01, 2023 11:06 AM

    Hi Olivier thank you very much also for the contribution!! Just in case David doesn't see my reply, i would also like to ask you if you know what would i change in the script if i don't want to assume the initial time between 0 and the actual start of the first task of each machine as idle time?



    ------------------------------
    Pedro Casal
    ------------------------------



  • 8.  RE: Idle Time Calculation in sched_jobshop

    Posted Fri September 01, 2023 11:34 AM

    if each machine is started at the start of its first operation, you can use:

        writeln("Idle time for machine " + m + " = " + (mchs[m].last().end - mchs[m].first().start - usage));
    


    ------------------------------
    Olivier Lhomme
    ------------------------------



  • 9.  RE: Idle Time Calculation in sched_jobshop

    Posted Fri September 01, 2023 10:03 PM
    Edited by Pedro Casal Fri September 01, 2023 10:04 PM

    Thank you very much Olivier! I just have one more question. Does this script work well if the number of jobs is higher than machines? for example a problem instance with 20 jobs and 15 machines. I'm trying another problem instance and the idle time is giving incorrect values. 

    <1 0 59 59>
     <1 59 129 70>
     <1 129 225 96>
     <1 225 227 2>
     <1 227 322 95>
     <1 322 372 50>
     <1 372 431 59>
     <1 431 487 56>
     <1 487 556 69>
     <1 556 632 76>
     <1 632 637 5>
     <1 637 667 30>
     <1 667 737 70>
     <1 737 764 27>
     <1 764 798 34>
    Idle time for machine 1 = 679

    this is the scripting log for machine 1 and it only gives 15 values (it should give 20 since there are 20 jobs) and i have no idea from where that "679" came from. for that 15 values it should be actually 0.

    Thank you again!



    ------------------------------
    Pedro Casal
    ------------------------------



  • 10.  RE: Idle Time Calculation in sched_jobshop

    Posted Mon September 04, 2023 05:06 AM

    Sorry, I made a typo... I edited my first answer, replacing nbMachs by nbJobs in the 2nd loop:

        for(var i = 0; i <  nbJobs ; i++)


    ------------------------------
    Olivier Lhomme
    ------------------------------



  • 11.  RE: Idle Time Calculation in sched_jobshop

    Posted Sun September 10, 2023 10:15 AM

    Hello again,

    I was now wondering if its possible to create a model that minimizes both makespan and idle time? Until now, for what i'm understanding, the idle time calculations have been after the minimization of the makespan so maybe it isnt possible to minimize it together with the makespan? (creating a pareto frontier and then seeing the possible candidates)



    ------------------------------
    Pedro Casal
    ------------------------------



  • 12.  RE: Idle Time Calculation in sched_jobshop

    Posted Mon September 11, 2023 04:44 AM
    Edited by Hugues Juille Mon September 11, 2023 04:55 AM

    Hello Pedro,

    Using the following formulation for the objective, one can also minimize idle time:

    minimize max(j in Jobs) endOf(itvs[j][nbMchs-1]) + 
            sum(m in Mchs) (max(j in Jobs, o in Mchs : Ops[j][o].mch == m) endOf(itvs[j][o], 0) - 
                                        min(j in Jobs, o in Mchs : Ops[j][o].mch == m) startOf(itvs[j][o], 99999) - 
                                        sum(j in Jobs, o in Mchs : Ops[j][o].mch == m) Ops[j][o].pt);
    

    In this formulation, one adds both maximum end time and idle times.
    One may want a weighted combination.
    Note also that solve time is also longer when using this objective.



    ------------------------------
    Hugues Juille
    ------------------------------