绝对可行的不可行解决方案-CPLEX

时间:2019-05-29 14:01:05

标签: cplex opl

基本上,我有两个雇员,每个雇员可以分配给两个花名册模式中的一个,后者依次为每个雇员分配一组班次。

为员工分配花名册模式->员工只能按该花名册模式进行轮班工作,并且必须全部工作。

为此,我有一个约束条件,该约束条件基本上规定每个雇员执行的所有班次的总和应等于输入shiftsPerRP。因此,如果采用花名册模式,例如0,例如说雇员Allan,那么Allan应该正好工作45个班次。

但是,此约束不断失败并导致不可行的解决方案。我无法弄清我在这里缺少什么。任何帮助表示赞赏。

相关DAT:

days={
    1, 2, 3, 4, 5, 6, 7
}

People = {
    Allan,
    Joe,
};

rosterPatterns = {
    0,1
};


shiftsPerRP = {
    <0,45>
    <1,5>
};

Skills= {
    A, 
    B, 
    C
};

相关代码:

dvar boolean Assign[days][Hours][People][Skills];   // Indicates a shift assignment

range Hours = 0..23; 

forall(h in Hours, d in days, p in People, rp in rosterPatterns, shiftsInRP in shiftsPerRP : shiftsInRP.ID == rp)
      sum(s in Skills)
            Assign[d][h][p][s] == shiftsInRP.shifts;

1 个答案:

答案 0 :(得分:2)

为了对此进行分析,请标记您的约束条件(请参阅添加的“ c1”):

Enable-WindowsOptionalFeature

通过该操作,OPL应该计算出最小冲突,以显示哪些约束不可行。这样做(在命令行上),我发现生成的第一个约束是不可行的。约束的左侧只有三个变量,而右侧为5。这永远无法满足。

鉴于集合forall(h in Hours, d in days, p in People, rp in rosterPatterns, shiftsInRP in shiftsPerRP : shiftsInRP.ID == rp) c1: sum(s in Skills) Assign[d][h][p][s] == shiftsInRP.shifts; 中只有三个元素,约束的左侧将始终具有3个变量。因此,它可以采用{0,1,2,3}中的值。如果对于任何元组Skills的值都大于3,则显然不能满足该约束。

编辑:看来您可能混淆了应加入shifts和应归入forall的内容。为了正确地表述,我认为您将需要一个辅助变量

sum

如果将一个人分配给花名册模式,则为1,否则为0。 这样,您可以将约束公式表示为

dvar boolean RosterAssigned[People][rosterPatterns];

左侧给出了一个人forall(p in People) sum(h in Hours, s in Skills, d in days) Assign[d][h][p][s] == sum(rp in rosterPatterns, shiftsInRP in shiftsPerRP : shitsInRP.ID == rp) (RosterAssigned[p][rp] * shiftsInRP.shifts); 实际工作的班次数。右侧给出了花样图案所需的移位数。当然,您还必须添加约束条件,以确保将每位员工分配到完全相同的花名册模式。