我正在研究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);
}
}
谢谢。
答案 0 :(得分:0)
首先,您应该添加一些约束条件,这些约束条件表示由间隔itvs [t]表示的每个任务都跨越了单个活动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]);