或-工具护士安排shift_scheduling_sat.py问题/问题

问题描述

我正在尝试使用Google的OR-Tools,或更具体地说,使用示例shift_scheduling_sat.py,该示例更加全面并且更接近我想要的功能。我需要做的问题仍然是相同的(将工人分配到固定的班次中),而且我在添加我想要的东西时遇到了麻烦。例如,我想将单个班次中的工人人数设置为仅一个,就像their guide中所示的更简单的示例一样,该操作可以通过以下方式完成:

for d in all_days:
    for s in all_shifts:
        model.Add(sum(shifts[(n,d,s)] for n in all_nurses) == 1)

我可以这样做,但是示例本身具有一种方法,可以在给定的工作日内设置工人人数:

weekly_cover_demands = [
    (2,3,1),# Monday
    (2,# Tuesday
    (2,2,2),# Wednesday
    (2,# Thursday
    (2,# Friday
    (1,3),# Saturday
    (1,# Sunday
]

因此,我尝试将其所有值设置为:(1,1,1)指示应仅选择一名工人进行指定的班次,并注释掉表明该工人每周应有的休息数量的限制的行:

# Weekly sum constraints on shifts days:
#     (shift,hard_min,soft_min,min_penalty,#             soft_max,hard_max,max_penalty)
weekly_sum_constraints = [
    # Constraints on rests per week.
    # removing constraints on rests
    #(0,7,4),# At least one night-shift per week (penalized). At most 4 (hard).
    (3,4,0),]

但是,解决方案花费了一些时间,因此我不得不添加solver.parameters.max_time_in_seconds变量来限制搜索解决方案所花费的时间,从理论上讲这应该很容易。结果如下:

          M T W T F S S M T W T F S S M T W T F S S 
worker 0: O M O M O O N N O M O O M O O N N O O A O
worker 1: O M N N O O M O O A O N N O O M O O A O O
worker 2: M A O O A O O A O O A O O N N O O A O O A
worker 3: M A O A O O A O O M O O A O O A O O M O O
worker 4: A A O O N N O O A O O A O O A O O N N O O
worker 5: A O M O O M O O N N N O O M O O M O O M O
worker 6: O O A A O A O O M O O M O O M O O M O O M
worker 7: N N O O M O O M O O M O O A O O A O O N N

前两天有两个轮班工作的工人,其余的都是正确的(O是“休息日”)。为什么在最初的两天而不是其余的日子里不起作用?

我觉得最简单的示例就是他们指南页面上的示例,但是我没有这个示例。我仍然有很多问题和疑问,例如;

  1. 如何约束自己?我可以稍微理解一下更简单的指南示例,但我仍在研究此示例,希望对它们如何使用model.Addmodel.Minimize以及如何使用model.Maximize
  2. 进行解释>
  3. 在前面的示例中,它以代数形式显示了查找 x y 等值的问题,我对此有些理解,但是我将如何理解呢?继续实施一个系统,例如说使护士最好与上次一样轮班,直至达到任意最大极限。就像创建某种模式来评估它是否合适。
  4. 罚分的含义是什么?例如,在清单weekly_sum_constraints中,有一种说法是每周清单上有一个夜班“惩罚”值3,“硬”罚则为0(我认为这是一个可靠的规则,不被破坏),值3和0是什么意思,这些值如何选择?

感谢您的帮助,我一直在搜寻“约束编程”以试图理解这一点,但是它们并不是专门针对该库的,但我仍在搜索

解决方法

没有银弹的答案。

  1. 阅读代码。没有约束,只有建模。该模型的constraints是线性方程,是布尔约束(和,或隐含)。

  2. 如果要允许模式或禁止模式的特定列表,可以查看允许分配(禁止分配)约束。参见the doc entryexample中使用了此约束。

  3. 查看关于软约束的惩罚版本。如果应采用惩罚,则总是会创建一个布尔变量,该变量为true。然后将bool_var * weight项添加到最小化部分的线性表达式中。