问题描述
我正在尝试使用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是“休息日”)。为什么在最初的两天而不是其余的日子里不起作用?
我觉得最简单的示例就是他们指南页面上的示例,但是我没有这个示例。我仍然有很多问题和疑问,例如;
- 如何约束自己?我可以稍微理解一下更简单的指南示例,但我仍在研究此示例,希望对它们如何使用
model.Add
,model.Minimize
以及如何使用model.Maximize
进行解释>
- 在前面的示例中,它以代数形式显示了查找 x 和 y 等值的问题,我对此有些理解,但是我将如何理解呢?继续实施一个系统,例如说使护士最好与上次一样轮班,直至达到任意最大极限。就像创建某种模式来评估它是否合适。
- 罚分的含义是什么?例如,在清单
weekly_sum_constraints
中,有一种说法是每周清单上有一个夜班“惩罚”值3,“硬”罚则为0(我认为这是一个可靠的规则,不被破坏),值3和0是什么意思,这些值如何选择?
感谢您的帮助,我一直在搜寻“约束编程”以试图理解这一点,但是它们并不是专门针对该库的,但我仍在搜索。
解决方法
没有银弹的答案。
-
阅读代码。没有约束,只有建模。该模型的
constraints
是线性方程,是布尔约束(和,或隐含)。 -
如果要允许模式或禁止模式的特定列表,可以查看允许分配(禁止分配)约束。参见the doc entry。 example中使用了此约束。
-
查看关于软约束的惩罚版本。如果应采用惩罚,则总是会创建一个布尔变量,该变量为true。然后将bool_var * weight项添加到最小化部分的线性表达式中。