首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >连续几天的作品

连续几天的作品
EN

Stack Overflow用户
提问于 2019-04-16 08:22:35
回答 1查看 518关注 0票数 0

我正在尝试使用or-tool创建一个调度程序。我现在遇到了以下问题。我希望员工至少连续工作n天。

我试过这个:

代码语言:javascript
复制
for n in all_nurses:
    for d in all_days:
        if sum([shifts[(n, d, 0)], shifts[(n, d, 1)], shifts[(n, (d), 2)]]) == 1: # if employee works this day, then he should works the 2 days after too
            model.Add(sum([shifts[(n, d+1, 0)], shifts[(n, (d+1), 1)], shifts[(n, (d+1), 2)]]) == 1)
            model.Add(sum([shifts[(n, d+2, 0)], shifts[(n, (d+2), 1)], shifts[(n, (d+2), 2)]]) == 1)

它适用于3个员工,但如果我添加更多的员工(10),模型找不到任何解决方案。

你有什么想法吗?

编辑:我尝试在https://github.com/google/or-tools/blob/39f44709bba203f5ff3bc18fab8098739f189a6d/examples/python/shift_scheduling_sat.py#L61上实现该示例,但失败了。这是我的尝试:

代码语言:javascript
复制
for n in all_nurses:
    works = [sum(shifts[n, d, s] for s in all_shifts) for d in all_days]
    print (works)
    for length in range(3, 4):
        for start in range(len(works) - length - 1):
            model.AddBoolOr(negated_bounded_span(works, start, length))
    for start in range(len(works) - 5 - 1):
        model.AddBoolOr([works[i].Not() for i in range(start, start + hard_max + 1)])

我得到了错误:

代码语言:javascript
复制
AttributeError: '_SumArray' object has no attribute 'Not'

我被迫计算一天的班次总和,因为我需要连续几天的工作,而不是特定的班次。

另外,如果有人在这里很好地解释了这个方法是如何工作的:https://github.com/google/or-tools/blob/39f44709bba203f5ff3bc18fab8098739f189a6d/examples/python,因为我真的不明白AddBoolOr是如何确保我们有一个真正的连续布尔值序列的

编辑2:

我成功地在github上实现了这个解决方案。但是,我仍然有一个问题。我创建了我的一天/班次的镜像,如下所示:

代码语言:javascript
复制
shifts = {}
mirrors = {}
for n in all_nurses:
    for d in all_days:
        mirrors[(n,d)] = model.NewBoolVar('mirror_n%id%i' % (n, d))
        for s in all_shifts:
            shifts[(n, d, s)] = model.NewBoolVar('shift_n%id%is%i' % (n, d,
                                                                      s))    


#Creation du mirroir
for n in all_nurses:
    for d in all_days:
        model.Add(sum(shifts[(n, d, s)] for s in all_shifts) == mirrors[(n,d)])

这样对于护士1: 0010 0100 0010 1000 0000 0000 0000镜像将是:1 1 1 0 0 0

然后我应用该方法在我的镜像上连续几天的工作,因为他链接到我的主表。

代码语言:javascript
复制
for n in all_nurses:
    works = [mirrors[n,d] for d in range(num_days)]
    for length in range(1, 3):
        for start in range(len(works) - length - 1):
            model.AddBoolOr(negated_bounded_span(works, start, length))
    for start in range(len(works) - 5 - 1):
        model.AddBoolOr([works[i].Not() for i in range(start, start + 5 + 1)])

现在,我希望结果不会有3到5之间不包含的任何工作周期。但是,当我打印一个护士的解决方案时,我得到了以下结果:

代码语言:javascript
复制
0010 0010 0010 0010 0010 0000 0000 0000 0001 0000

而对于镜子,它是:

代码语言:javascript
复制
1111100010

这应该是不可能的,因为工作周期是在3到5之间。

你有什么想法吗?谢谢!

EN

回答 1

Stack Overflow用户

发布于 2019-04-16 09:08:59

这是在shift_scheduling_sat.py中作为软件版本实现的

请参阅:https://github.com/google/or-tools/blob/39f44709bba203f5ff3bc18fab8098739f189a6d/examples/python/shift_scheduling_sat.py#L61

在……里面

代码语言:javascript
复制
    # Forbid sequences that are too short.
    for length in range(1, hard_min):
        for start in range(len(works) - length - 1):
            model.AddBoolOr(negated_bounded_span(works, start, length))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55698908

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档