我正在尝试使用谷歌的or工具,或者更具体地说是sat.py,它更全面,更接近我想要的功能。我需要做的问题仍然是一样的(工人的分配成固定的轮班),我只是在添加我想要的东西有困难。例如,我希望将单个轮班中的工人人数设置为一个,正如他们的向导中所示的更简单的示例所示,该示例由以下方法完成:
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, 3, 1), # Tuesday
(2, 2, 2), # Wednesday
(2, 3, 1), # Thursday
(2, 2, 2), # Friday
(1, 2, 3), # Saturday
(1, 3, 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, 1, 2, 7, 2, 3, 4),
# At least one night-shift per week (penalized). At most 4 (hard).
(3, 0, 1, 3, 4, 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。weekly_sum_constraints有这样的说法:每周有一次夜班,每周有一个值为3的“惩罚”,“严厉”的惩罚是0(我假设这是一个坚实的规则,是不能打破的),3和0是什么意思?这些值是如何选择的?谢谢你的帮助,我一直在谷歌上搜索“约束编程”,试图理解这一点,但它们并不是专门针对这个库的,但我仍然在搜索。
发布于 2020-10-05 15:31:23
没有银弹的答案。
constraints是线性方程组和布尔约束(和,或,蕴涵)。https://stackoverflow.com/questions/64211109
复制相似问题