Decision Optimization

Decision Optimization

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

 View Only
Expand all | Collapse all

Jobshop using CPLEX Optimizer

  • 1.  Jobshop using CPLEX Optimizer

    Posted Fri September 15, 2017 05:02 AM

    Originally posted by: user1234567


    Hello, i'm a beginner in cplex. Can you please give me an example of a jobshop using cplex optimizer, because i just found examples using constraint programming.

    I have a mathematical model (milp model) to applicate on cplex. so, i need examples of a jobshop using cplex optmizer. Unfortunately, you just put the examples of jobshop using CP optimizer. There is no example of a jobshop using CPLEX Optimizer ! 

     

    Thank you.


    #CPLEXOptimizers
    #DecisionOptimization


  • 2.  Re: Jobshop using CPLEX Optimizer

    Posted Fri September 15, 2017 05:55 AM

    Originally posted by: user1234567


    please i need that urgently. 


    #CPLEXOptimizers
    #DecisionOptimization


  • 3.  Re: Jobshop using CPLEX Optimizer

    Posted Fri September 15, 2017 08:36 AM

    Hi,

    as can be read at https://fr.slideshare.net/PhilippeLaborie/vug-scheduling28-may2014

    CPO can really be good at scheduling.

    The jobshop example at CPLEX_Studio1271\opl\examples\opl\sched_jobshop is a very good example

    .mod

    // --------------------------------------------------------------------------
    // Licensed Materials - Property of IBM
    //
    // 5725-A06 5725-A29 5724-Y48 5724-Y49 5724-Y54 5724-Y55
    // Copyright IBM Corporation 1998, 2013. All Rights Reserved.
    //
    // Note to U.S. Government Users Restricted Rights:
    // Use, duplication or disclosure restricted by GSA ADP Schedule
    // Contract with IBM Corp.
    // --------------------------------------------------------------------------

    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("");
      }
    }

    .dat

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

    but you could easily turn this into a MIP:

    .mod

    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 int+ s[j in Jobs][o in Mchs];
    dvar int+ e[j in Jobs][o in Mchs];

     

    minimize max(j in Jobs) e[j][nbMchs-1];
    subject to {

    forall (j in Jobs, o in 0..nbMchs-1) e[j][o]-s[j][o]==Ops[j][o].pt;
     
       
       forall (o1,o2 in Mchs) forall(i,j in Jobs:(Ops[i][o1].mch==Ops[j][o2].mch) && ((i!=j) || (o1!=o2)))
       (s[i][o1]>=e[j][o2]) || (s[j][o2]>=e[i][o1]);
      forall (j in Jobs, o in 0..nbMchs-2)
        (e[j][o]<=s[j][o+1]);
    }

    execute {
      for (var j = 0; j <= nbJobs-1; j++) {
        for (var o = 0; o <= nbMchs-1; o++) {
          write(s[j][o] + " ");
        }
        writeln("");
      }
    }

     

    regards


    #CPLEXOptimizers
    #DecisionOptimization


  • 4.  Re: Jobshop using CPLEX Optimizer

    Posted Sat September 16, 2017 04:02 AM

    Originally posted by: user1234567


    Hello Alex and thank you for your reply.

    Now i want to add to this code some information related to my problem: 1. I want that cplex determines which operation is assigned to which machine (in a way that it minimizes Cmax). So, I want to add the machine as a decision variable.

    2. The Jobshop is Flexible so that each operation of a job can work on more than one machine.

    3. I have two other decision variable Xijk = {1 if machine k is selected for operation Oij, 0 otherwise}, 

    and Yij i'j' k = {1 if operation Oij precedes operation Oi'j' on machine k, 0 otherwise}.

     

    How can I do this ? Can you help me please ? Thank you very much.


    #CPLEXOptimizers
    #DecisionOptimization


  • 5.  Re: Jobshop using CPLEX Optimizer

    Posted Sat September 16, 2017 04:45 AM

    Then you could Have a look at

     

    The flexible job-shop scheduling 

    This problem is an extension of the classical Job-Shop Scheduling problem which allows an operation to be processed by any machine from a given set. The problem is to assign each operation to a machine and to order the operations on the machines such that the maximal completion time (makespan) of all operations is minimized.

    To access this example, go to: examples/opl/sched_jobshopflex.


    #CPLEXOptimizers
    #DecisionOptimization


  • 6.  Re: Jobshop using CPLEX Optimizer

    Posted Sat September 16, 2017 09:24 AM

    Originally posted by: user1234567


    i already had a look at the Flexible Jobshop Scheduling Problem. But, in this example, the user enters the assignment of the different operations on machines.(manually)

    I want that it will be automatically (the assignment of operations to machines) as i explained above.

    So, please help me to solve point 1: Now i want to add to this code some information related to my problem: 1. I want that cplex determines which operation is assigned to which machine (in a way that it minimizes Cmax). So, I want to add the machine as a decision variable.

     

    //.MOD

    int nbJobs = ...;
    int nbMchs = ...;
    int nbOps = ...;

    range Jobs = 0..nbJobs-1;
    range Mchs = 0..nbMchs-1;
    range ops =  0..nbOps;

    // Mchs is used both to index machines and operation position in job
    tuple Operation {
      int id;
      int jobId;
      int pt;  // Processing time
    };
    Operation Ops[j in Jobs][k in Mchs] = ...;

     

     
    dvar int+ s[j in Jobs][o in Mchs];
    dvar int+ c[j in Jobs][o in Mchs];
    dvar int+ k;

    dvar boolean X[i in Jobs][j in ops][k in Mchs];
    dvar boolean Y[i in Jobs][j in ops][i1 in Jobs][j1 in ops][k in Mchs];

    minimize max(j in Jobs) c[j][nbMchs-1];
    subject to {
    forall (j in Jobs, o in 0..nbMchs-1) c[j][o]-s[j][o]==Ops[j][o].pt;

     forall (o1,o2 in Mchs) forall(i,j in Jobs:(Ops[i][o1]==Ops[j][o2]) && ((i!=j) || (o1!=o2)))
       (s[i][o1]>=c[j][o2]) || (s[j][o2]>=c[i][o1]);
      forall (j in Jobs, o in 0..nbMchs-2)
        (c[j][o]<=s[j][o+1]);

     

    //C00
    forall (i in Jobs, j in ops, k in Mchs){
      {
     
    sum (k in Mchs) X[i][j][k]==1;

    }

    }
       
    }


     tuple result {
     int Jobs;
     int Mchs;
     int ops;
     }
     {result} results = {<i,j,k>|i in Jobs, j in ops, k in Mchs: X[i][j][k]==1};
     
     
    execute {
    writeln (results);

      for (var j = 0; j <= nbJobs-1; j++) {
        for (var o = 0; o <= nbMchs-1; o++) {
          write(s[j][o] + " ");
        }
        writeln("");
      }

     

    //.DAT

     

    nbJobs = 6;
    nbMchs = 6;
    nbOps=6;

    Ops = [
     [ <1,1,5>, <2,1,3>, <3,1,3>, <4,1,2>, <5,1,1>, <6,1,2> ],
     [ <1,2,3>, <2,2,8>, <3,2,7>, <4,2,2>, <5,2,9>, <6,2,3> ],
     [ <1,3,1>, <2,3,9>, <3,3,9>, <4,3,7>, <5,3,5>, <6,3,5> ],
     [ <1,4,8>, <2,4,2>, <3,4,1>, <4,4,7>, <5,4,8>, <6,4,9> ],
     [ <1,5,6>, <2,5,2>, <3,5,5>, <4,5,5>, <5,5,3>, <6,5,1> ],
     [ <1,6,10>, <2,6,4>, <3,6,4>, <4,6,3>, <5,6,2>, <6,6,3> ]
    ];

     

     


    #CPLEXOptimizers
    #DecisionOptimization


  • 7.  Re: Jobshop using CPLEX Optimizer

    Posted Sat September 16, 2017 10:41 AM

    I would really use CPO.

    In the example I mentioned The flexible job-shop scheduling :

    forall (o in Ops)
        alternative(ops[o], all(md in Modes: md.opId==o.id) modes[md]);

    could help

    regards


    #CPLEXOptimizers
    #DecisionOptimization


  • 8.  Re: Jobshop using CPLEX Optimizer

    Posted Sat September 16, 2017 04:06 PM

    Originally posted by: user1234567


    Hello, in the jobshopflex.mod:cp, does the program determine the start and the completion time of each operation of a job on machines.

    And where can i see exactly the results which indicates the start and the completion time of each operation of a job on machines in the space which displays the solution

    and also can u explain to me the results (after compilation) related to: 

    dvar interval ops  [Ops]; 
    dvar interval modes[md in Modes] optional size md.pt;
    dvar sequence mchs[m in Mchs] in all(md in Modes: md.mch == m) modes[md];

    (I didn't understand well what is their interest and the result of each decision variable).

     

    Thank you in advance.


    #CPLEXOptimizers
    #DecisionOptimization


  • 9.  Re: Jobshop using CPLEX Optimizer

    Posted Sun September 17, 2017 02:10 PM

    Originally posted by: user1234567


    Hello, can you please help me to correct the error in my code because the result of the decicion variables:  s[o in Oper][k in Mchs]  (the start time of operation j on machine k) and

    c[o in Oper][k in Mchs] (the end time of the operation j on machine k) are not correct !!!

     

    Here is the .MOD and the .DAT files:

    //.MOD

    using CP;

    tuple paramsT{
        int nbJobs;
        int nbMchs;
        int nbOper;
       
    };

    int M=10000;

    paramsT Params = ...;    
    int nbJobs = Params.nbJobs;
    int nbOper = Params.nbOper;
    int nbMchs = Params.nbMchs;


    range Jobs = 1..nbJobs;
    range Oper=1..nbOper;
    range Mchs = 1..nbMchs; 


    tuple Operation {
      int id;    // Operation id
      int jobId; // Job id
      int pos;   // Position in job
    };

    tuple Mode {
      int opId; // Operation id
      int mch;  // Machine
      int pt;   // Processing time
    };

    {Operation} Ops   = ...;
    {Mode}      Modes = ...;


    // Position of last operation of job j
    int jlast[j in Jobs] = max(o in Ops: o.jobId==j) o.pos;
    dvar interval ops  [Ops]; 
    dvar interval modes[md in Modes] optional size md.pt;

    dvar sequence mchs[m in Mchs] in all(md in Modes: md.mch == m) modes[md];

    dvar int+ s[o in Oper][k in Mchs];
    dvar int+ c[o in Oper][k in Mchs];


    dexpr int Cmax  = max(j in Jobs, o in Ops: o.pos==jlast[j]) endOf(ops[o]);

    execute {
              cp.param.FailLimit = 10000;
    }


    minimize Cmax;
    subject to {

    forall ( k in Mchs, o in Oper,  md in Modes: md.mch==k && md.opId==o, op in Ops: op.id==md.opId) 
    c[o][k]-s[o][k]==md.pt;

       
       forall (k1 in Mchs, k2 in Mchs, i in Oper, j in Oper, md1 in Modes, md2 in Modes: md1.mch != md2.mch && md1.mch==k1 && md2.mch==k2, op1 in Ops, op2 in Ops: op1.jobId != op2.jobId && op1.jobId==i && op2.jobId==j)
       
       (s[i][k1]>=c[j][k2]) || (s[j][k2]>=c[i][k1]);

     

      

     
        // Precedence constraints between consecutive operations o,z of a job j
      forall (j in Jobs, m in Mchs, o in Ops, z in Ops: o.jobId==j && z.jobId==j && z.pos==1+o.pos){
        endBeforeStart(ops[o],ops[z]); 
    }

        //Only operations on the same machine can be consecutive operations.
        //******************************************************************

        // Alternative machines for a given operation o
      forall (o in Ops) 
        alternative(ops[o], all(md in Modes: md.opId==o.id) modes[md]);
           
        // Operations on a given machine m cannot overlap
      forall (m in Mchs)
        noOverlap(mchs[m]);
    }


     
       
    execute {
      for (var m in Modes) {
        if (modes[m].present)
          writeln("Operation " + m.opId + " on machine " + m.mch + " starting at " + modes[m].start+ "ends at"+ modes[m].end); 
                     
      }

    }

    tuple solutionT{
        int operation;
        int machine;
        int start;
        int end;
    };
    {solutionT} solution = {<m.opId, m.mch, startOf(modes[m]), endOf(modes[m])> | m in Modes : startOf(modes[m]) != 0 };

     

    //.DAT

    Params = <3, 4, 9>;

    Ops = {
      <1,1,0>, 
      <2,1,1>,
      <3,1,2>,
      <4,1,3>,
      
      <5,2,0>, 
      <6,2,1>,
      <7,2,2>
       
      <8,3,0>, 
      <9,3,1>,
    };

    Modes = {
      <1,1,2>,
      <1,2,3>,
     
      
      <2,1,4>,  

      <3,2,3>,
      <3,3,9>,
     
      
      <4,1,5>,
      
      
      <5,2,4>,
      <5,4,7>, 
        
      <6,1,2>,
      <6,2,4>,
      
      <7,1,4>,
      <7,2,12>,
      
      
      <8,1,4>, 
      <8,3,6>, 
       
      <9,4,15>, 
       
    };

     

    please i need the solution of the start times and end times soon. I have a deadline to give back this work. Thank you.


    #CPLEXOptimizers
    #DecisionOptimization


  • 10.  Re: Jobshop using CPLEX Optimizer

    Posted Fri October 25, 2019 05:12 PM

    Originally posted by: kcapt


    Hi,

    I know it was been some years but I have the exact same problem. Did you find the answer? Thanks!


    #CPLEXOptimizers
    #DecisionOptimization


  • 11.  Re: Jobshop using CPLEX Optimizer

    Posted Mon November 04, 2019 04:33 AM

    It is better to start a new thread and describe exactly what your problem is. If possible also attach your model and data so that others have a chance to figure out what may be wrong.


    #CPLEXOptimizers
    #DecisionOptimization