Decision Optimization

 View Only
Expand all | Collapse all

Add constraint to ensure that all jobs within the same group are assigned to the same machine for all tasks.

  • 1.  Add constraint to ensure that all jobs within the same group are assigned to the same machine for all tasks.

    Posted Thu September 07, 2023 09:41 AM
    /*********************************************
     * OPL 22.1.0.0 Model
     * Author: Ghada
     * Creation Date: 17 juil. 2023 at 10:45:20
     *********************************************/
    using CP;
     
    tuple paramsT {
      int nbJobs;
      int nbMchs;
      int nbOfs;
    }
     
    paramsT Params = ...;
    int nbJobs = Params.nbJobs;
    int nbMchs = Params.nbMchs;
    int nbOfs = Params.nbOfs;
     
    range Jobs = 1..nbJobs;
    range Mchs = 1..nbMchs;
    range OFs = 1..nbOfs;
     
    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
    }
     
    tuple Of {
      int OfId;
      int jobId;
    }
    tuple Group {
      int jobId;
      int GrId;
    }
     
    {Operation} Ops = ...;
    {Mode} Modes = ...;
    {Of} OF = ...;
    {Group} Gr=...;
     
    // 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 similarMachine[j in Jobs] in Mchs;
     
    execute {
      cp.param.FailLimit = 100;
    }
     
    // minimize max(j in Jobs, o in Ops: o.pos == jlast[j]) endOf(ops[o]);
    minimize max(off in OF, j in Jobs, o in Ops: o.pos == jlast[j] && off.jobId == j) endOf(ops[o]);
     
    subject to {
      forall(j in Jobs, o1 in Ops, o2 in Ops: o1.jobId == j && o2.jobId == j && o2.pos == 1 + o1.pos)
        endBeforeStart(ops[o1], ops[o2]);
      forall(o in Ops)
        alternative(ops[o], all(md in Modes: md.opId == o.id) modes[md]);
      forall(m in Mchs)
        noOverlap(mchs[m]);
        
    };
     
    tuple Solution {
      Operation operation;
      int job;
      int machine;
      int start;
      int end;
      int of; // Include the 'of' field here
    }
     
    {Solution} solution = {<o, o.jobId, md.mch, startOf(modes[md]), endOf(modes[md]), of.OfId> | o in Ops, md in Modes: o.id == md.opId && presenceOf(modes[md]), of in OF: of.jobId == o.jobId};
     
    // Export the solution to a CSV file
    execute {
      var file = new IloOplOutputFile("solution.csv testSep28");
      file.writeln("Operation,Job,Machine,Start,End,Of");
     
      for (var sol in solution) {
        file.writeln(sol.operation + "," + sol.job + "," + sol.machine + "," + sol.start + "," + sol.end + "," + sol.of);
      }
     
      file.close();
    }


    ------------------------------
    ghada ouerfelli
    ------------------------------


  • 2.  RE: Add constraint to ensure that all jobs within the same group are assigned to the same machine for all tasks.

    Posted Thu September 07, 2023 12:45 PM

    Hello Ghada,

    Assuming I understand your problem correctly, one way to model your constraint, given a groupId, is to iterate over all machines and make sure that if one operation for a job in this group uses this machine, then all the operations for the other jobs in this group will also use this same machine.
    The following OPL code should implement this idea:

      forall (grId in GrIds) {
        sum(mch in Mchs) (sum(g in Gr, m in Modes, o in Ops: g.GrId == grId && m.mch == mch && m.opId == o.id && o.jobId == g.jobId) presenceOf(modes[m]) > 0) <= 1;
      } 

    I haven't been able to test this idea since I don't have any data, but I hope this will give you some ideas to progress.

    Best regards,



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



  • 3.  RE: Add constraint to ensure that all jobs within the same group are assigned to the same machine for all tasks.

    Posted Mon September 11, 2023 06:29 AM

    Hello , I put the new constraint but I have an error , can you check it please in the file uploaded ?



    ------------------------------
    ghada ouerfelli
    ------------------------------



  • 4.  RE: Add constraint to ensure that all jobs within the same group are assigned to the same machine for all tasks.

    Posted Mon September 11, 2023 09:10 AM

    Hello,

    My previous code snippet wasn't providing the initialization of the GrIds set... Sorry about that.
    Here is the relevant code:

    // 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 similarMachine[j in Jobs] in Mchs;
    
    {int} GrIds = { gr.GrId | gr in Gr};
    
    execute {
      cp.param.FailLimit = 100;
    }
     
    // minimize max(j in Jobs, o in Ops: o.pos == jlast[j]) endOf(ops[o]);
    minimize max(off in OF, j in Jobs, o in Ops: o.pos == jlast[j] && off.jobId == j) endOf(ops[o]);
     
    subject to {
      forall(j in Jobs, o1 in Ops, o2 in Ops: o1.jobId == j && o2.jobId == j && o2.pos == 1 + o1.pos)
        endBeforeStart_label:
        endBeforeStart(ops[o1], ops[o2]);
      forall(o in Ops)
        alternative_label:
        alternative(ops[o], all(md in Modes: md.opId == o.id) modes[md]);
      forall(m in Mchs)
        noOverlap_label:
        noOverlap(mchs[m]);
      forall (grId in GrIds) {
        same_machine_label:
        sum(mch in Mchs) (sum(g in Gr, m in Modes, o in Ops: g.GrId == grId && m.mch == mch && m.opId == o.id && o.jobId == g.jobId) presenceOf(modes[m]) > 0) <= 1;
      }  
        
    };
    

    Note however that this code generates a non-feasible model...

    My understanding of your constraint was that all operations for jobs in a same group should use the same machine.

    However, for Group=2 (which includes jobs 3 and 4), operations 27 and 49 do not have an overlapping set of machines to execute. This makes the problem infeasible.

    I'm not sure whether this is a data issue or a misunderstanding from me of the constraint you want to implement.

    Anyway, I guess that the above example should help you define your constraint as you'd like by reformulating the OPL code properly...



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



  • 5.  RE: Add constraint to ensure that all jobs within the same group are assigned to the same machine for all tasks.

    Posted Mon September 11, 2023 10:18 AM

    hello thanks for your answer : I modify the data but it still infeasible also can you help me 



    ------------------------------
    ghada ouerfelli
    ------------------------------