Decision Optimization

Decision Optimization

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


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
Expand all | Collapse all

How to set relation between two intervals used by the same sequence???

  • 1.  How to set relation between two intervals used by the same sequence???

    Posted 05/24/18 06:35 AM

    Originally posted by: Wahiba123


    Hello everyone.

    My problem is to schedule some jobs on some machines so that each time a machine reaches a limit time it should has a break. The problem is that all breaks are sheduled in the first or in the last of the sequence on each machine (see joint figure 1). what I want to get is something like in figure2.

    I need some help on how to express the relation between the two intervals in the sequence. My Model is the next:

    .mod

    using CP;
    int n = ...;
    int m = ...;
    int L = ...;
    int limit[k in 0..m-1]=...;
    int P[k in 0..m-1][j in 0..n-1] = ...;
    int M[k in 0..m-1][l in 0..L-1]=...;
    
    
    //variable de décision
    dvar interval itvs[k in 0..m-1][j in 0..n-1] size P[k][j];
    dvar interval mts[k in 0..m-1][l in 0..L-1] size M[k][l];
    dvar sequence mchs[k in 0..m-1] in append(all(j in 0..n-1) itvs[k][j],all(l in 0..L-1)mts[k][l]) types append(all(j in 0..n-1) j, all(l in 0..L-1) l);
    execute {
     //cp.param.FailLimit = 10000;
      cp.param.TimeLimit=10;
      cp.param.Workers = 1;
    }
    //the objective function
    minimize max(j in 0..n-1) endOf(itvs[m-1][j]);
    subject to {
      forall (k in 0..m-1)
        noOverlap(mchs[k]);
      forall (j in 0..n-1, k in 0..m-2)
         endBeforeStart(itvs[k][j], itvs[k+1][j]);
      forall(k in 0..m-1, l in 0..L-2)
        endBeforeStart(mts[k][l],mts[k][l+1]);
      forall(k in 0..m-1, l in 0..L-2)
        startBeforeEnd(mts[k][l+1],mts[k][l],-limit[k]); 
    }
    

    .dat

    n=5;

    m=2;

    L=4;

    limit=[132,132];

    P=[[

    98,39,42,79,26],

    [65,84,37,17,18]];

    M=[

    [15,9,22,22],

    [19,6,15,19]];

    Thanks in advance.


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 2.  Re: How to set relation between two intervals used by the same sequence???

    Posted 05/24/18 09:14 AM

    Originally posted by: PhilippeLaborie


    Hello. What does it mean for a machine to reach a time-limit ? What does it mean for a machine to have a break ?

    It seems you are modeling a mix of production and maintenance activities, right? If yes, could you formalize the conditions for having a maintenance activity?

    Philippe


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 3.  Re: How to set relation between two intervals used by the same sequence???

    Posted 05/25/18 03:28 AM

    Originally posted by: Wahiba123


    Hello.

    Yes it is right it's a model of mix production and maintenance activities. The time limit is the maximum cumulated processing time on each machine before a maintenance activity (a maintenance acticity can be run before this limit). In the given example the limit is about 132 time units for each machine.

    The break is the maintenance activity (the machine is unavailable for processing any job) and it is given in the example by "M" with the durations of each maintenance activity (the first one, the second one and so on), it's not necessary that all the maintenance activity be inserted in the schedule . The break times are not fixed in advance it's dependent on the total cumulated processing time.

    Thanks.


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 4.  Re: How to set relation between two intervals used by the same sequence???

    Posted 05/25/18 05:02 AM

    Originally posted by: PhilippeLaborie


    Ok. That is what I guessed but I wanted to be sure.

    In your model, nothing constrains the position of the maintenance activities with respect to the production activities.

    So you could add a set of integer variable (one for each production activity) that counts the total processing time since last maintenance activity (variable ptCountAtEnd in the model below). The domain of these variables is in 0..maxpt where maxpt is the limit on the total processing time before doing a maintenance. 

    In the sequence, each of the n production activities have a type in 1..n whereas the maintenance activities have a type 0. The constraint that maintains the counters ptCountAtEnd is:


    ptCountAtEnd[i] == ptCountAtEnd[typeOfPrev(seq,act[i],0)] + sizeOf(act[i]);

     

    It says that the counter of processing time at the end of a production activity i is the value of the counter of the previous activity plus the size of the activity. But there is a small trick here: if the type of the previous activity is a maintenance (typeOfPrev=0), then the value of the counter is 0, that is why we add an index 0 in the array and post ptCountAtEnd[0]==0 for maintenance activities.

    To speed-up the search, it may be useful to tell CP Optimizer to first focus on fixing the production activities, as the maintenance ones should be fixed by propagation as  consequence. This can be done with a search phase.  This gives the following model:

    using CP;
    
    int n = 100;
    int maxpt  = 20;
    int maintdur = 10;
    int pt[i in 1..n] = 1+rand(10); // Processing time for activity i
    
    int m = n;
    
    dvar interval act[i in 1..n] size pt[i]; // decision variables
    dvar interval maint[j in 1..m] size maintdur;
    
    dvar sequence seq in append(act, maint) types append(all(i in 1..n) i, all(j in 1..m) 0);
    dvar int ptCountAtEnd[i in 0..n] in 0..maxpt;
    
    execute {
      var f = cp.factory;
      cp.setSearchPhases(f.searchPhase(act)); 
    }
    
    minimize max(i in 1..n) endOf(act[i]);
    subject to {
      noOverlap(seq);
      forall(j in 2..m) {
        endBeforeStart(maint[j-1], maint[j], maxpt);
      }
      ptCountAtEnd[0]==0; // For maintenance activities 
      forall(i in 1..n) {
        ptCountAtEnd[i] == ptCountAtEnd[typeOfPrev(seq,act[i],0)] + sizeOf(act[i]);
      }
    }
    

    Now, you can also have a slightly more involved model that 'removes' the useless maintenance activities at the end of the schedule by having those activities optional. Only the first ones, that are required will be executed. The constraint typeOfNext(seq,maint[j],0,1)!=0 says that you cannot have two consecutive maintenance activities without any production in between and that the schedule cannot end with a maintenance activity.

    using CP;
    
    int n = 100;
    int maxpt  = 20;
    int maintdur = 10;
    int pt[i in 1..n] = 1+rand(10); // Processing time for activity i
    
    int m = n;
    
    dvar interval act[i in 1..n] size pt[i]; // decision variables
    dvar interval maint[j in 1..m] optional size maintdur;
    
    dvar sequence seq in append(act, maint) types append(all(i in 1..n) i, all(j in 1..m) 0);
    dvar int ptCountAtEnd[i in 0..n] in 0..maxpt;
    
    execute {
      var f = cp.factory;
      cp.setSearchPhases(f.searchPhase(act)); 
    }
    
    minimize max(i in 1..n) endOf(act[i]);
    subject to {
      noOverlap(seq);
      forall(j in 2..m) {
        endBeforeStart(maint[j-1], maint[j], maxpt);
        presenceOf(maint[j]) => presenceOf(maint[j-1]);
        typeOfNext(seq,maint[j],0,1) != 0;
      }
      ptCountAtEnd[0]==0; // For maintenance activities 
      forall(i in 1..n) {
        ptCountAtEnd[i] == ptCountAtEnd[typeOfPrev(seq,act[i],0)] + sizeOf(act[i]);
      }
    }
    

     

    Hope it helps,

    Philippe

     


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 5.  Re: How to set relation between two intervals used by the same sequence???

    Posted 05/27/18 07:21 PM

    Originally posted by: Wahiba123


    Hello Philippe, thanks a lot for your response. Sure the given example  was helpful. I have wrote the model according to your recommandation but I have a little problems:

    1- On the first machine there is an idle time between "itvs" and "mts" how to deal with it, on the first machine the schedule shouldn't has any idle time. And On the second machine there is an idle time between "mts" and its predecessor "itvs".In general I want that if the "mts" has to been processed it should be just next to its predecessor itvs no idle time between.

    2- On the second machine the "mts" was first on the sequence, how to set the "mts" intervals (maintenance activities) not to be first neither last on the sequence?????

    Next is the model:

    using CP;
    int n = ...;
    int m = ...;
    int L = ...;
    int limit[k in 1..m]=...;
    int P[k in 1..m][j in 1..n] = ...;
    int M[k in 1..m][l in 1..L]=...;
    
    
    dvar interval itvs[k in 1..m][j in 1..n] size P[k][j];
    dvar interval mts[k in 1..m][l in 1..L] optional size  M[k][l];
    dvar sequence mchs[k in 1..m] in append(all(j in 1..n) itvs[k][j],all(l in 1..L)mts[k][l]) types append(all(j in 1..n) j, all(l in 1..L) 0);
    dvar int ptCountAtEnd[k in 1..m][j in 0..n] in 0..limit[k];
    execute {
     //cp.param.FailLimit = 10000;
      cp.param.TimeLimit=10;
      cp.param.Workers = 1;
       //var f = cp.factory;
       //cp.setSearchPhases(f.searchPhase(itvs));
      
    }
    //the objective function
    minimize max(j in 1..n) endOf(itvs[m][j]);
    subject to {
      forall (k in 1..m)
        noOverlap(mchs[k]);
      forall (k in 1..m-1,j in 1..n)
         endBeforeStart(itvs[k][j], itvs[k+1][j]);
      forall(k in 1..m, l in 2..L)
        {
        endBeforeStart(mts[k][l-1],mts[k][l],limit[k]); 
        presenceOf(mts[k][l])=>presenceOf(mts[k][l-1]);
        typeOfNext(mchs[k],mts[k][l],0,1) !=0;
        }
            forall(k in 1..m) 
            {
            ptCountAtEnd[k][0]==0; 
            forall(j in 1..n)
        ptCountAtEnd[k][j] == ptCountAtEnd[k][typeOfPrev(mchs[k],itvs[k][j],0)] + sizeOf(itvs[k][j]);
            }
    }
    

    #DecisionOptimization
    #OPLusingCPOptimizer


  • 6.  Re: How to set relation between two intervals used by the same sequence???

    Posted 05/28/18 02:46 AM

    Originally posted by: PhilippeLaborie


    1- Could it be because you have added a minimal delay limit[k] between two consecutive maintenance on the machines (endBeforeStart(mts[k][l-1],mts[k][l],limit[k]))

    2- In order to prevent to start with a maintenance activity, you could post a constraint typeOfPrev(mchs[k],mts[k][l],0,1)!=0. It the maintenance is first, the value of the expression will be 0 and the constraint is not satisfied. If it is not first, the constraint says that the previous activity should not be a maintenance (so it is redundant with the similar constraint on typeOfNext). And if the maintenance interval is absent, the value is 1 and the constraint is satisfied.

     


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 7.  Re: How to set relation between two intervals used by the same sequence???

    Posted 05/28/18 04:40 AM

    Originally posted by: Wahiba123


    Thanks a lot for your great help. I get my model as I want.


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 8.  Re: How to set relation between two intervals used by the same sequence???

    Posted 05/28/18 04:46 AM

    Originally posted by: PhilippeLaborie


    Hmm, I see "forall(k in 1..m, l in 2..L)", it seems that you are missing the maintenance activity indexed by l=1 in the iteration, at least for typeOfNext (yes I know, that was a typo in my code :-) ), maybe also for typeOfPrev. Also keep in mind that the constraint on typeOfPrev is not fully redundant with the one on typeOfNext. The one on typeOfNext does not ensure that the schedule starts with a production activity,

    Philippe

     

     


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 9.  Re: How to set relation between two intervals used by the same sequence???

    Posted 05/29/18 03:59 AM

    Originally posted by: Wahiba123


    Thanks a lot Philippe for your help, what you describe is just what I make. I wrote the constraints like next and the model works perfectly:

      forall(k in 1..m, l in 2..L)
        {
        presenceOf(mts[k][l])=>presenceOf(mts[k][l-1]);
        startOf(mts[k][l])-endOf(mts[k][l-1])<=limit[k];
        endBeforeStart(mts[k][l-1],mts[k][l]);
        }    
      forall(k in 1..m, l in 1..L)
        {
        typeOfNext(mchs[k],mts[k][l],0,1)!=0;
        typeOfPrev(mchs[k],mts[k][l],0,1)!=0;
        }
    

    Can I ask for help on the way to write the running configuration to an excel file, I need to get the sequence of jobs. I define a tuple like next and even if the "jobs_per_machine" return a value I get an empty "results_within_sequence":

    tuple job_per_machine
    {
    key int s; // start
    int job;
    }
    sorted {job_per_machine} jobs_per_machine[o in 1..m]={<startOf(itvs[k][j]),j> | k in 1..m,j in 1..n:k==o};
    execute
    {
    jobs_per_machine;
    }
    tuple result_within_sequence
    {
    key int Job;
    key int Machine;
    int rank;
    }
    {result_within_sequence} results_within_sequence;
    
    execute
    {
     solve_time = cp.info.SolveTime;
     obj=cp.getObjValue();
    for(var k in 1..m)
    {
    var x=1;
    for(var j in 1..n)
    {
    results_within_sequence.add(Opl.item(jobs_per_machine[k],x).job,k,x);
    x++;
    }
    }
    }
    

     


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 10.  Re: How to set relation between two intervals used by the same sequence???

    Posted 05/29/18 04:18 AM

    Originally posted by: PhilippeLaborie


    What do you mean? In this loop, you add m.n elements to the set:

    for(var k in 1..m) {
      var x=1;
      for(var j in 1..n) {
        results_within_sequence.add(Opl.item(jobs_per_machine[k],x).job,k,x);
        x++;
      }
    }
    

    Did you try printing the value of the tuple that is added at each iteration?


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 11.  Re: How to set relation between two intervals used by the same sequence???

    Posted 05/29/18 04:41 AM

    Originally posted by: Wahiba123


    What I want to get is the sequence of jobs, even if for just one machine.

    How can I write the tuple"jobs_per_machine" to an excel file.When I write "jobs_per_machine to SheetWrite(sheet2,"A101:F1000");" on the data file I got an error????


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 12.  Re: How to set relation between two intervals used by the same sequence???

    Posted 05/29/18 07:19 AM

    Originally posted by: PhilippeLaborie


    Ok, it seems it is a matter of syntax for the iteration in the loop.

    I think you need to do:

    for(var k=1; k<=m; k++) {
      var x=1;
      for(var j=1; j<=n; j++) {
        results_within_sequence.add(Opl.item(jobs_per_machine[k],x).job,k,x);
        x++;
      }
    }
    

     


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 13.  Re: How to set relation between two intervals used by the same sequence???

    Posted 05/29/18 07:24 AM

    Originally posted by: Wahiba123


    Thanks a lot Philippe really You saved me.

    Best regards.


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 14.  Re: How to set relation between two intervals used by the same sequence???

    Posted 06/04/18 05:17 AM

    Originally posted by: Wahiba123


    Hello Philippe. I am sorry to be here again but after many attempts I write this SOS message.

    I have a problem with the sequence of the "itvs", it's not the same for all machines. How could I set it to keep the same sequence of jobs "itvs" all over the machines???

     


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 15.  Re: How to set relation between two intervals used by the same sequence???

    Posted 06/04/18 05:29 AM

    Originally posted by: PhilippeLaborie


    Hello,

    CP Optimizer provides a constraint 'sameSequence'. See https://www.ibm.com/support/knowledgecenter/SSSA5P_12.8.0/ilog.odms.cpo.help/CP_Optimizer/reffileformatcpo/functions/sameSequence.html.

    There is also a version 'sameCommonSubsequence' that may be useful in your case if you only want to consider the production activities and not the maintenance ones.

     


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 16.  Re: How to set relation between two intervals used by the same sequence???

    Posted 06/04/18 05:52 AM

    Originally posted by: Wahiba123


    Thanks for your response. That's what I have do, I define it like next:

    dvar sequence sjobs[k in 1..m] in all(j in 1..n) itvs[j][k] types all(j in 1..n) j;
    dvar sequence mchs[k in 1..m] in append(all(j in 1..n) itvs[k][j],all(l in 1..L)mts[k][l]) types append(all(j in 1..n) j, all(l in 1..L) 0);
     forall (k in 1..m)
        sameCommonSubsequence(mchs[k],sjobs[k]);
    

    But I get the next error "The function sameCommonSubsequence(dvar sequence, dvar sequence) doesn't exist.


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 17.  Re: How to set relation between two intervals used by the same sequence???

    Posted 06/04/18 06:30 AM

    Originally posted by: PhilippeLaborie


    Strange. Which version of CPLEX Optimization Studio are you using?

    Also, did you check that your OPL CP model contains "using CP" ?

    These constraints were introduced long ago in V12.6 (Jan. 2014).

    Philippe


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 18.  Re: How to set relation between two intervals used by the same sequence???

    Posted 06/04/18 06:35 AM

    Originally posted by: Wahiba123


    I am using the version 12.3

    So that's the problem I guess?? In this case how could I set this constarint??

    I think that adding the next constraints solves the problem, isn't it!!!!!!

      forall (k in 1..m, j in 1..n: 1<k)
        typeOfPrev(sjobs[k],itvs[k][j],n)==typeOfPrev(sjobs[1],itvs[1][j],n);


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 19.  Re: How to set relation between two intervals used by the same sequence???

    Posted 06/04/18 06:48 AM

    Originally posted by: PhilippeLaborie


    Yes, that's the way to go in 12.3.

    BUT, if you can you should try to upgrade to the latest version (V12.8). V12.3 is now 7years old and we have made a lot of progress since then (additional constraints for modeling, faster automated search algorithm, less bugs, more model development tools, ...)

     


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 20.  Re: How to set relation between two intervals used by the same sequence???

    Posted 06/04/18 06:53 AM

    Originally posted by: Wahiba123


    OK I will do it. Thanks a lot again Philippe.


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 21.  Re: How to set relation between two intervals used by the same sequence???

    Posted 08/06/18 05:42 AM

    Originally posted by: Wahiba123


    Hello.

    I need help to change the model.

    I need to change the restriction between two consecutives maintenance tasks from "limit[k]" to a maximum number of consecutive jobs per machine. I made the next modifications but the maintenance task is not puted in the exact position I need. How can I formulate the constraint to put a maintenance task exactly after processing "Three" jobs for example. 

    .....

    int maxjob=...;//three for example
    ......
    dvar int ptCountAtEnd[k in 1..m][j in 0..n] in 0..maxjob;
    .........
    minimize max(j in 1..n) endOf(itvs[m][j]);
    
    subject to {
      ..............
      forall(k in 1..m, l in 2..L)
        {
        presenceOf(mts[k][l])=>presenceOf(mts[k][l-1]);
        endBeforeStart(mts[k][l-1],mts[k][l]);
        }    
      forall(k in 1..m, l in 1..L)
        {
        typeOfNext(mchs[k],mts[k][l],0,1)!=0;
        typeOfPrev(mchs[k],mts[k][l],0,1)!=0;
        }  
      forall(k in 1..m) 
            {
            ptCountAtEnd[k][0]==0;
            forall(j in 1..n)
        ptCountAtEnd[k][j] == ptCountAtEnd[k][typeOfPrev(mchs[k],itvs[k][j],0)]+1;
            }
    }
    

    Thanks a lot.


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 22.  Re: How to set relation between two intervals used by the same sequence???