Indexing 如何在Minizing中用集合子集建立域索引模型

Indexing 如何在Minizing中用集合子集建立域索引模型,indexing,mathematical-optimization,minizinc,Indexing,Mathematical Optimization,Minizinc,我正在研究一个护士排班问题,约束条件是,在前一天的夜班之后,不应该为护士分配白班 约束如下所示: 移位集为“整数集:移位=1..7” int的集合:dayshift={1,3,4}; int的集合:dayshift={2,5,6,7} 如何在Minizing中建模此约束 我试过: constraint forall(e in Employee, d in Day where d != Day[card(Day)])( Assign[e, d, sh in NightShfit] +

我正在研究一个护士排班问题,约束条件是,在前一天的夜班之后,不应该为护士分配白班

约束如下所示:

移位集为“整数集:移位=1..7”

int的集合:dayshift={1,3,4}; int的集合:dayshift={2,5,6,7}

如何在Minizing中建模此约束

我试过:

 constraint
  forall(e in Employee, d in Day where d != Day[card(Day)])(
Assign[e, d, sh in NightShfit]   + Assign[e, d+1, sh in DayShift]  < 1
);

error: MiniZinc: type error: undefined identifier `sh'
约束
forall(员工中的e,日中的d,其中d!=日[卡片(日)])(
在夜班时分配[e,d,sh]+在白班时分配[e,d+1,sh]<1
);
错误:Minizin:类型错误:未定义的标识符'sh'

问题的解决方案是计算两个班次的“分配”变量之和:

constraint forall(e in Employee, d in Day where d != Day[card(Day)])(
    sum(sh in NightShift)(Assign[e, d, sh]) + sum(sh in DayShift)(Assign[e, d+1, sh])  < 1
);
all约束(员工中的e,日中的d!=日[卡片(日)])(
总和(夜班时为sh)(分配[e,d,sh])+总和(白班时为sh)(分配[e,d+1,sh])<1
);
作为旁注,我想指出,对这类问题使用0/1变量只是数学优化求解器(MIP)建模的一种好方法。约束编程(CP)解算器和惰性子句生成(LCG)解算器将无法有效地工作,即使它们非常适合此类问题


我的建议是将不同类型的轮班(每天)作为枚举,然后为每个员工每天分配一个版本的轮班。像您在这里表达的约束通常很适合
常规
约束,该约束在MIP和CP/LCG解算器中都表现出色。(如果是MIP,它会自动转换为流模型)。

问题的解决方案是计算两个移位的“赋值”变量之和:

constraint forall(e in Employee, d in Day where d != Day[card(Day)])(
    sum(sh in NightShift)(Assign[e, d, sh]) + sum(sh in DayShift)(Assign[e, d+1, sh])  < 1
);
all约束(员工中的e,日中的d!=日[卡片(日)])(
总和(夜班时为sh)(分配[e,d,sh])+总和(白班时为sh)(分配[e,d+1,sh])<1
);
作为旁注,我想指出,对这类问题使用0/1变量只是数学优化求解器(MIP)建模的一种好方法。约束编程(CP)解算器和惰性子句生成(LCG)解算器将无法有效地工作,即使它们非常适合此类问题

我的建议是将不同类型的轮班(每天)作为枚举,然后为每个员工每天分配一个版本的轮班。像您在这里表达的约束通常很适合
常规
约束,该约束在MIP和CP/LCG解算器中都表现出色。(在MIP的情况下,它会自动转换为流模型)