Decision Optimization

Decision Optimization

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

 View Only
Expand all | Collapse all

Multi-Project Scheduling

  • 1.  Multi-Project Scheduling

    Posted Sun March 27, 2016 08:32 PM

    Originally posted by: Lalilu


    Hi,

    I'm trying to transform the basic resource constrained single project scheduling problem(sched_rcpsp example) into a multi-project version.

    I'm still new to CPLEX, got a solution, but I guess what I did is either very clumsy or simply wrong. I tried it with only two projects, named the existing Task tuple "Task1" and added an additional "Task2" tuple with the information about the second project. The min average project duration may not be the best choice of objective but let's ignore that for now.

    Do you have any ideas on how to handle multiple projects? Help would be very much appreciated.

    using CP;

    int NbTasks = ...;
    int NbRsrcs = ...;
    int Projects = ...;


    range RsrcIds = 0..NbRsrcs-1;


    int Capacity[r in RsrcIds] = ...;

    tuple Task1 {
      key int id;
      int     pt;
      int     dmds[RsrcIds];
      {int}   succs;
    }
    tuple Task2 {
      key int id;
      int     pt;
      int     dmds[RsrcIds];
      {int}   succs;
    }

    {Task1} Tasks1 = ...;
    {Task2} Tasks2 = ...;

    dvar interval itvs1[t in Tasks1]  size t.pt;
    dvar interval itvs2[t in Tasks2]  size t.pt;


    cumulFunction rsrcUsage1[r in RsrcIds] =
      sum (t in Tasks1: t.dmds[r]>0) pulse(itvs1[t], t.dmds[r]);
     cumulFunction rsrcUsage2[r in RsrcIds] =    
        sum (t in Tasks2: t.dmds[0]>0) pulse(itvs2[t], t.dmds[r]);
     

    execute {
            cp.param.FailLimit = 10000;
    }

    minimize (sum(t in Tasks1) max(t in Tasks1) endOf(itvs1[t]) + sum(t in Tasks2) max(t in Tasks2) endOf(itvs2[t]) )/ Projects;
    subject to {
      forall (r in RsrcIds)
        rsrcUsage1[r]+rsrcUsage2[r] <= Capacity[r];
      forall (t1 in Tasks1, t2id in t1.succs)
        endBeforeStart(itvs1[t1], itvs1[<t2id>]);
      forall (t1 in Tasks2, t2id in t1.succs)
        endBeforeStart(itvs2[t1], itvs2[<t2id>]);
    }

    execute {
      for (var t in Tasks1) {
        writeln("Task1 " + t.id + " starts at " + itvs1[t].start);
      }
      for (var t in Tasks2) {
        writeln("Task2 " + t.id + " starts at " + itvs2[t].start);}
    }
     


    #DecisionOptimization
    #OPLusingCPOptimizer


  • 2.  Re: Multi-Project Scheduling

    Posted Tue March 29, 2016 05:18 AM

    Originally posted by: PhilippeLaborie


    Well, a multi-project scheduling problem as you seem to define it here is just a particular case of RCPSP problem. You just have a set of "sub-projects" without any precedence constraints in between sub-projects. Then the model will depend on how the data is organized. In your current model you assume you have two sets of tasks, why not. In other cases it may be better to consider just one set of tasks with for instance an additional identifier in the Task tuple that identifies the project the task belongs to. This being said, in your model you do not need to define 2 tuples Task1 and Task2 (they are the same), so you can just use the original Task tuple, but you would keep two tuple sets {Task} Tasks1 and {Task} Tasks2.If you want to model n projects that have the same "structure" (n instance of the same pattern), then you do not need to duplicate the data, you can just add another dimention ([i in 1..n]) in the arrays of decision variables of your problem. 

    As a conclusion, one cannot say your model is good or bad, or right or wrong; it all depends on what sort of multi-project scheduling problem you want to solve and how the related data is "naturally" organized.

     


    #DecisionOptimization
    #OPLusingCPOptimizer