如何正确编写多索引约束?员工排班连续白班约束失效求助
解决连续白班约束失效的问题
嘿,我一眼就看到你这个连续白班约束的问题所在啦——你写的约束根本起不到限制作用!咱们来拆解一下:
问题根源
你当前的约束代码是:
max_consecutive_days = 4 for i in medewerkers: for j in range(1, (len(dagen)+1 - max_consecutive_days)): m += D[(i, j)] + D[(i, j + 1)] + D[(i, j + 2)] + D[(i, j + 3)] <= max_consecutive_days
这里的D[(i,j)]都是二进制变量(0或1),四个这样的变量相加最大值就是4,所以总和 ≤4这个条件永远成立,模型完全不会把它当回事,自然就出现了连续4天以上白班的情况。
正确的约束逻辑
要限制连续白班不超过4天,我们需要确保:任何连续的5天里,白班的数量最多只能是4天(也就是至少有1天不是白班)。这样就从根源上杜绝了连续5天及以上白班的可能。
修改后的代码
假设你的days是1-based编号(比如日期编号从1到n),修改后的约束代码如下:
max_consecutive_days = 4 window_size = max_consecutive_days + 1 # 窗口大小设为5天 for i in employees: # 遍历所有可能的起始日期,确保窗口能覆盖到最后一天 for j in range(1, len(days) - window_size + 2): # 计算连续window_size天的白班总和 consecutive_d_shifts = sum(D[(i, j + k)] for k in range(window_size)) m += consecutive_d_shifts <= max_consecutive_days
如果你的days是0-based编号(比如从0开始索引),只需要调整循环范围即可:
max_consecutive_days = 4 window_size = max_consecutive_days + 1 for i in employees: for j in range(len(days) - window_size + 1): consecutive_d_shifts = sum(D[(i, days[j + k])] for k in range(window_size)) m += consecutive_d_shifts <= max_consecutive_days
额外提醒
- 确认你的
days编号是连续的,避免出现索引错误导致约束没作用 - 可以测试一下极端情况:比如强制某员工连续5天白班,看模型是否会拒绝这个解,验证约束是否生效
内容的提问来源于stack exchange,提问作者Joep
相关产品推荐
相关产品推荐

