如何解决减少 Google OR-tools python 脚本的运行时间使用 Google Cloud
我正在用 Python 为我工作的医院的一个科室开发护士排班程序。此类程序的各种示例已经存在并在线共享。其中之一如下:https://github.com/google/or-tools/blob/master/examples/python/shift_scheduling_sat.py
到目前为止,我已经修改了上面链接中的代码,以包含各种类型的劳动法规以及个别护士的偏好。现在,我想使用这个量身定制的脚本为 25 名护士在 7 周内(5 种轮班类型,可以减少到 4 人)制作名册。
但是,实施特定类型的约束会导致运行时间显着增加。这些约束是:
-
对早/晚/夜班系列长度的限制:
shift_constraints = [ #Morning shifts (1,2,4,0),#Evening shifts (2,Night shifts (3,1,5,0) ]
-
限制休息日。我想通过添加到轮班限制列表来阻止安排单天休假:
(0,10,0)
-
强制周末(周六和周日)都安排休息:
for e in range(num_employees): for d in range(num_days): if ( ( d in weekend_day ) & ( ( d+1 ) in weekend_day) ): model.Add(work[e,d + 1] == 1 ).OnlyEnforceIf(work[e,d])
-
强制员工在连续 3 次夜班后休息 2 天
for e in range(num_employees): for d in range(num_days): if ((d > 3) and (d<45)): model.Add(work[e,d] == 1).OnlyEnforceIf(work[e,3,d-3] and work[e,d-2] and work[e,d-1]) model.Add(work[e,d + 1] == 1).OnlyEnforceIf(work[e,d-1])
-
强制员工不能连续工作超过 7 天:
max_seq_length = 7 for e in range(num_employees): works = [work[e,d].Not() for d in range(num_days)] variables,coeffs = add_soft_sequence_constraint( model,works,max_seq_length,'shift_constraint(employee %i,shift %i)' % (e,0)) # model,hard_min,soft_min,min_cost,soft_max,hard_max,#max_cost,shift %i)' % (23 shift)) obj_bool_vars.extend(variables) obj_bool_coeffs.extend(coeffs)
在没有任何这些限制的情况下运行脚本只需不到 1 分钟。但是,将所有这些同时添加到脚本中时,可能需要 48 多个小时才能找到解决方案。因此我想知道是否可以减少运行时间?如果有帮助,我不一定需要最佳解决方案。由于我很少使用惩罚约束,因此任何满足指定约束的解决方案都可以。
解决方法
您的代码中存在错误:
.OnlyEnforceIf(work[e,3,d-3] and work[e,d-2] and work[e,d-1])
应该是:
.OnlyEnforceIf([work[e,d-3],work[e,d-2],d-1]])
不要将 min(),max(),and,not,if
与 ortools 变量一起使用
我终于设法解决了这个问题。下面我将介绍我使用 Google 服务计算引擎的方法。
在我找到解决方案之前,我尝试了几件事:
- 首先,我在运行时优化了代码。例如,我删除了一个每月只分配几次的班次类型,以减少搜索空间。我还删除了个别特定的轮班轮换规则和系列长度限制,因为这些会导致运行时间大幅增加
- 我尝试了“num_search_workers”参数的各种设置。请注意,在最新版本的脚本中,此参数不再包含在代码中,必须手动添加。
但是,这些更改并没有导致运行时间的预期减少。很明显代码很好,但我只是没有足够的计算能力。因此我考虑如何在更强大的设备上运行脚本。我开始尝试在 Google Colab 中运行它,但这里的运行时间比在我自己的设备上还要长
然后我决定在 Google 云服务上试用计算引擎。只需点击几下,GCS 即可设置专用于 CPU 密集型任务(具有自定义规范)的虚拟机。此外,如果您以前从未使用过该服务,您可以获得 300 美元的信用来租用服务器。如果您注册,默认情况下您会获得一个测试帐户,该帐户对 VM 的规格有一些限制。但是,如果您切换到付费帐户,则信用额度会添加到您的帐户中,并且限制会解除。通过这种方式,我可以使用比我的笔记本电脑强大几个数量级的机器。
对于那些对使用 GCS 运行 python 脚本感兴趣的人,我建议观看这个视频作为介绍:
此外,Google 在此代码实验室中提供了使用 VM 的介绍:
这些视频介绍了如何在 Debian 操作系统上设置 python:
- https://www.youtube.com/watch?v=5OL7fu2R4M8&t=194s
- https://www.youtube.com/watch?v=nMY0qDg16y4&t=143s
如果您正在设置 Python,请不要忘记创建一个虚拟环境来安装包和运行脚本:
在我弄清楚如何在 VM 上运行脚本后,我尝试了 VM 配置/num-search 工作器设置。不要忘记,如果您使用多核处理器,则可以增加搜索工作器的数量,从而降低运行时间。
我注意到 8 核(30 GB RAM)计算专用系统(在“试用帐户”中提供)在运行时间方面比我的笔记本电脑快 20-30。但是,我决定使用更强大的 VM。使用 30 核设置(130 GB RAM),脚本在 20 秒内运行完成,而不是 48 小时。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。