You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

护士排班建模:滑动6周窗口内至少14天连续无班次约束实现方法

基于OR-Tools CP-SAT求解器的约束建模方案

你需要新增辅助布尔变量配合滑动窗口逻辑实现该约束,具体步骤如下:

  1. 预定义常量
    首先明确三个基础常量,和你现有排班逻辑的编码规则保持一致:
  • OFF_SHIFT:代表无排班的O班次对应的编码值
  • WINDOW_LENGTH:滑动窗口长度,6周对应42天
  • REQUIRED_OFF_DAYS:要求的连续休息天数,即14天
  1. 新增辅助布尔变量
    为每位护士n、每个可能的连续14天休息起始日期s,定义布尔变量has_14d_off_start_at[n][s]:
  • 变量值为True时,代表护士n从第s天到第s+13天(共14天)全为O班次
  • 变量取值覆盖所有合法的s:即`s + REQUIRED_OFF_DAYS - 1 < 总排班天数
  1. 绑定辅助变量和排班变量
    对每个护士n、每个合法的起始日期s,添加两组约束:
# 约束1:如果has_14d_off_start_at[n][s]为真,对应14天必须全是休息
model.AddBoolAnd([
    shifts[n][d] == OFF_SHIFT for d in range(s, s + REQUIRED_OFF_DAYS)
]).OnlyEnforceIf(has_14d_off_start_at[n][s])

# 约束2:如果对应14天中存在任意一天不是休息,has_14d_off_start_at[n][s]必须为假
for d in range(s, s + REQUIRED_OFF_DAYS):
    model.AddImplication(
        shifts[n][d] != OFF_SHIFT,
        has_14d_off_start_at[n][s].Not()
    )
  1. 添加滑动窗口规则约束
    对每个护士n、每个滑动窗口的起始日期w(窗口覆盖第w天到第w + WINDOW_LENGTH - 1天),要求该窗口内至少存在一个合法的14天连续休息段:
# 每个滑动窗口内合法的连续休息起始日期范围是[w, w + WINDOW_LENGTH - REQUIRED_OFF_DAYS]
valid_starts = [s for s in range(w, w + WINDOW_LENGTH - REQUIRED_OFF_DAYS + 1)]
# 要求至少有一个起始日期对应的14天休息变量为真
model.AddBoolOr([has_14d_off_start_at[n][s] for s in valid_starts])

方案说明

该实现完全匹配你的需求:仅要求每个滑动6周窗口内至少存在一段14天连续休息,不会限制其他非目标休息段的长度,也不会强制所有休息段都满足14天要求,完美避开了add_soft_sequence_constraint的适配问题。
如果需要将该约束设为软约束,只需要给每个滑动窗口新增一个惩罚布尔变量,当窗口不满足约束时触发惩罚,将惩罚值计入目标函数即可。

内容的提问来源于stack exchange,提问作者Nik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 00:36:02