我的问题是关于cplex中的资源约束项目计划问题代码。我正在尝试对其应用抢占

时间:2019-02-14 07:08:27

标签: constraint-programming opl ibm-ilog-opl cp-optimizer

我正在研究RCPSP,并希望对其应用抢占。
我已将每个任务的持续时间分为相等的部分。现在,执行完此操作后,我无法将优先级约束应用于任务的每个单位持续时间。

using CP;

int NbTasks = ...;
int NbRsrcs = ...;
range RsrcIds = 1..NbRsrcs;  

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

tuple Task {                        
  key int id;
  int     pt;
  int     dmds[RsrcIds];
  {int}   succs;            
  {int}   pred;
}
{Task} Tasks=...;


tuple sub_task { 
  Task task; 
  int p_no;
 }

 {sub_task} sub_activities = {<t,i > | t in Tasks, i in 1..t.pt  };  
 dvar interval itvs[t in Tasks]  size t.pt;
 dvar interval a[p in sub_activities] size 1;
 cumulFunction rsrcUsage[r in RsrcIds] = 
   sum (p in sub_activities: p.task.dmds[r]>0) pulse(a[p], p.task.dmds[r]);
 minimize max(t in Tasks) endOf(itvs[t]);

subject to {
  forall (r in RsrcIds)
  rsrcUsage[r] <= Capacity[r];
  forall (t1 in Tasks, t2id in t1.succs)
    endBeforeStart(itvs[t1], itvs[<t2id>]);
}     

execute {
  for (var p in sub_activities) {
    writeln("subactivity of " + p.task.id + " - " + p.p_no + " starts at " + a[p].start + " Ends at " + a[p].end);  
  } 
}

谢谢。

2 个答案:

答案 0 :(得分:0)

首先,您应该添加一些约束条件,这些约束条件表示由间隔itvs [t]表示的每个任务都跨越了单个活动a []的集合,例如: span(itvs [t],all(i in 1..t.pt)a [])

然后说,给定任务t的各个活动形成了一个链,其约束如下: endBeforeStart(a [],[])

但是请注意,对于该抢先版本的问题,您将失去CP Optimizer的主要兴趣之一,因为它避免了枚举时间。在这里,如果任务是完全抢占式的,则必须将持续时间D的每个任务划分为D个单独的活动。如果您知道对任务的抢占有一些限制(例如,每个活动的最小持续时间都大于时间单位),则可以在模型中利用它来创建更少的子活动。

答案 1 :(得分:0)

我认为您的模型缺少一个重要的约束条件,该约束条件表明任务不同部分的持续时间之和等于任务处理时间。像这样:

123456789012.dkr.ecr.us-east-1.amazonaws.com/projectName

此外,由于整数除法会将结果四舍五入,因此您可能会错过一些子活动,所以我宁愿使用类似以下内容:

forall (t in Tasks) {
  sum(p in sub_activities: p.task==t) lengthOf(a[p]) == t.pt;
}

此外,跨接任务的大小不能为t.pt,但如果允许抢占则会更大,因此应为:

{sub_task} sub_activities = {<t,i > | t in Tasks, i in 1..1+(t.pt div t.smin )}; 

最后(但这只是为了稍微加快分辨率),您可以使用任务跨越时间间隔而不是部分(在目标变量中包含更少的变量)来重新构造目标中的makepan表达式:

dvar interval itvs[t in Tasks] size t.pt..H; // H being a large number

此外,如果零件的持续时间最大,则需要防止两个连续的零件连续(否则,我认为它将被视为同一零件),因此零件的间隔变量链应具有最小延迟为1:

minimize max(t in Tasks) endOf(itvs[t]);