上一篇介绍了《使用.Net Core与Google Optimization Tools实现员工排班计划Scheduling》,这次将Google官方文档python实现的版本的完整源码献出来,以满足喜爱python的朋友。

顺便可以多展开一下话题,到现在为止的这一套用法,可以应对在线教育中的排班、排课场景, 本质上就是如何合理地设计变量与约束,欢迎交流各种踩坑经历,分享巧妙的应用场景。

from __future__ import print_function
import sys
from ortools.constraint_solver import pywrapcp def main():
# Creates the solver.
solver = pywrapcp.Solver("schedule_shifts") num_nurses = 4
num_shifts = 4 # Nurse assigned to shift 0 means not working that day.
num_days = 7
# [START]
# Create shift variables.
shifts = {} for j in range(num_nurses):
for i in range(num_days):
shifts[(j, i)] = solver.IntVar(0, num_shifts - 1, "shifts(%i,%i)" % (j, i))
shifts_flat = [shifts[(j, i)] for j in range(num_nurses) for i in range(num_days)] # Create nurse variables.
nurses = {} for j in range(num_shifts):
for i in range(num_days):
nurses[(j, i)] = solver.IntVar(0, num_nurses - 1, "shift%d day%d" % (j,i))
# Set relationships between shifts and nurses.
for day in range(num_days):
nurses_for_day = [nurses[(j, day)] for j in range(num_shifts)] for j in range(num_nurses):
s = shifts[(j, day)]
solver.Add(s.IndexOf(nurses_for_day) == j)
# Make assignments different on each day
for i in range(num_days):
solver.Add(solver.AllDifferent([shifts[(j, i)] for j in range(num_nurses)]))
solver.Add(solver.AllDifferent([nurses[(j, i)] for j in range(num_shifts)]))
# Each nurse works 5 or 6 days in a week.
for j in range(num_nurses):
solver.Add(solver.Sum([shifts[(j, i)] > 0 for i in range(num_days)]) >= 5)
solver.Add(solver.Sum([shifts[(j, i)] > 0 for i in range(num_days)]) <= 6)
# Create works_shift variables. works_shift[(i, j)] is True if nurse
# i works shift j at least once during the week.
works_shift = {} for i in range(num_nurses):
for j in range(num_shifts):
works_shift[(i, j)] = solver.BoolVar('shift%d nurse%d' % (i, j)) for i in range(num_nurses):
for j in range(num_shifts):
solver.Add(works_shift[(i, j)] == solver.Max([shifts[(i, k)] == j for k in range(num_days)])) # For each shift (other than 0), at most 2 nurses are assigned to that shift
# during the week.
for j in range(1, num_shifts):
solver.Add(solver.Sum([works_shift[(i, j)] for i in range(num_nurses)]) <= 2)
# If s nurses works shifts 2 or 3 on, he must also work that shift the previous
# day or the following day.
solver.Add(solver.Max(nurses[(2, 0)] == nurses[(2, 1)], nurses[(2, 1)] == nurses[(2, 2)]) == 1)
solver.Add(solver.Max(nurses[(2, 1)] == nurses[(2, 2)], nurses[(2, 2)] == nurses[(2, 3)]) == 1)
solver.Add(solver.Max(nurses[(2, 2)] == nurses[(2, 3)], nurses[(2, 3)] == nurses[(2, 4)]) == 1)
solver.Add(solver.Max(nurses[(2, 3)] == nurses[(2, 4)], nurses[(2, 4)] == nurses[(2, 5)]) == 1)
solver.Add(solver.Max(nurses[(2, 4)] == nurses[(2, 5)], nurses[(2, 5)] == nurses[(2, 6)]) == 1)
solver.Add(solver.Max(nurses[(2, 5)] == nurses[(2, 6)], nurses[(2, 6)] == nurses[(2, 0)]) == 1)
solver.Add(solver.Max(nurses[(2, 6)] == nurses[(2, 0)], nurses[(2, 0)] == nurses[(2, 1)]) == 1) solver.Add(solver.Max(nurses[(3, 0)] == nurses[(3, 1)], nurses[(3, 1)] == nurses[(3, 2)]) == 1)
solver.Add(solver.Max(nurses[(3, 1)] == nurses[(3, 2)], nurses[(3, 2)] == nurses[(3, 3)]) == 1)
solver.Add(solver.Max(nurses[(3, 2)] == nurses[(3, 3)], nurses[(3, 3)] == nurses[(3, 4)]) == 1)
solver.Add(solver.Max(nurses[(3, 3)] == nurses[(3, 4)], nurses[(3, 4)] == nurses[(3, 5)]) == 1)
solver.Add(solver.Max(nurses[(3, 4)] == nurses[(3, 5)], nurses[(3, 5)] == nurses[(3, 6)]) == 1)
solver.Add(solver.Max(nurses[(3, 5)] == nurses[(3, 6)], nurses[(3, 6)] == nurses[(3, 0)]) == 1)
solver.Add(solver.Max(nurses[(3, 6)] == nurses[(3, 0)], nurses[(3, 0)] == nurses[(3, 1)]) == 1)
# Create the decision builder.
db = solver.Phase(shifts_flat, solver.CHOOSE_FIRST_UNBOUND,
solver.ASSIGN_MIN_VALUE)
# Create the solution collector.
solution = solver.Assignment()
solution.Add(shifts_flat)
collector = solver.AllSolutionCollector(solution) solver.Solve(db, [collector])
print("Solutions found:", collector.SolutionCount())
print("Time:", solver.WallTime(), "ms")
print()
# Display a few solutions picked at random.
a_few_solutions = [859, 2034, 5091, 7003] for sol in a_few_solutions:
print("Solution number" , sol, '\n') for i in range(num_days):
print("Day", i)
for j in range(num_nurses):
print("Nurse", j, "assigned to task",
collector.Value(sol, shifts[(j, i)]))
print() if __name__ == "__main__":
main()

Google Optimization Tools实现员工排班计划Scheduling【Python版】的更多相关文章

  1. 使用.NET Core与Google Optimization Tools实现员工排班计划Scheduling

    上一篇说完<Google Optimization Tools介绍>,让大家初步了解了Google Optimization Tools是一款约束求解(CP)的高效套件.那么我们用.NET ...

  2. 使用.NET Core与Google Optimization Tools实现加工车间任务规划

    前一篇文章<使用.NET Core与Google Optimization Tools实现员工排班计划Scheduling>算是一种针对内容的规划,而针对时间顺序任务规划,加工车间的工活儿 ...

  3. Google Optimization Tools实现加工车间任务规划【Python版】

    上一篇介绍了<使用.NET Core与Google Optimization Tools实现加工车间任务规划>,这次将Google官方文档python实现的版本的完整源码献出来,以满足喜爱 ...

  4. Google Optimization Tools介绍

    Google Optimization Tools(OR-Tools)是一款专门快速而便携地解决组合优化问题的套件.它包含了: 约束编程求解器. 简单而统一的接口,用于多种线性规划和混合整数规划求解, ...

  5. 详解 OneAlert 排班可以帮你做什么

    排班的存在,实质是通过有序安排,降低企业/团队人力成本,提升工作效率. 阅读导航(预计2min)   1. 详解排班功能 轮班机制 工作时间 双视图展示 灵活调整 2. 利用排班如何助力运维团队 排班 ...

  6. 使用SQL语句使数据从坚向排列转化成横向排列(排班表)

    知识重点: 1.extract(day from schedule01::timestamp)=13 Extract 属于 SQL 的 DML(即数据库管理语言)函数,同样,InterBase 也支持 ...

  7. Google PageSpeed Tools 性能测试分析

    今天给大家介绍下一个工具:Google PageSpeed Tools,根据官方的介绍,简单梳理如下: Page Speed Insights能针对移动设备和电脑设备衡量网页的性能.该工具会抓取网址两 ...

  8. c++实现医院检验科排班程序

    c++实现医院检验科排班程序 1.背景: 医院急诊检验科24h×7×365值班.工作人员固定.採取轮班制度.确保24h都有人值班. 本文就通过C++实现编敲代码自己主动排班,并能够转为Excel打印. ...

  9. Javascript:日期排班功能实现

     背景: 近期,公司的产品经常会遇到日期排班类似的功能: 需求的排班日期长短不一:有些是两周,有些是四周:要求选中的时候有一个active的状态区分,另外要提供钩子获取选中日期的形如:[2018-04 ...

随机推荐

  1. 微信小程序之基础入门

    微信小程序有几个基础的文件:js(JavaScript逻辑代码),json(页面配置),wxml(类似hthml布局),wxss(css样式) 我们使用app.json文件来对微信小程序进行全局配置, ...

  2. ckeditor粘贴上传图片

    公司做的项目需要用到文本上传功能. 网上找了很久,大部分都有一些不成熟的问题,皇天不负有心人终于让我找到了一个成熟的项目. 接下来就看一下吧 1.打开工程: 对于文档的上传我们需要知道这个项目的逻辑是 ...

  3. TCP报文首部详解

    首部固定部分各字段的意义如下: 1.源端口和目的端口,各占2个字节. 2.序号:占4个字节,序号范围为0到2的32次方-1,序号增加到2的32次方-1之后,下一个序号变为0,在一个TCP连接中传送的字 ...

  4. 1111 Online Map (30 分)

    1111. Online Map (30)Input our current position and a destination, an online map can recommend sever ...

  5. day32(表单校验js和jquery表单校验)

    校验用户名.密码.密码一直性. <style> .error { color: red } .success { color: green } </style> <scr ...

  6. Properties类、序列化流与反序列化流、打印流、commons-IO

    Properties类 特点: 1.Hashtable的子类,map集合中的方法都可以用: 2.该集合没有泛型,键值都是字符串: 3.是一个可以持久化的属性集,键值可以存到集合中,也可存到持久化的设备 ...

  7. mac版win10装eclipse图标太小了,解决办法(2k显示屏+win10)

    安装了Eclipse并且打开之后,发现图标显示极其细小,肉眼几乎无法看清了.这是由于Eclipse对高分屏没有作适配导致的. Windows 10本身对于高分屏的支持已是相当不错,苏菲4的屏幕分辨率为 ...

  8. python模块补充

    一.模块补充 configparser 1.基本的读取配置文件 -read(filename) 直接读取ini文件内容 -sections() 得到所有的section,并以列表的形式返回 -opti ...

  9. iOS笔记之UIKit_UINavigationController

    //设置导航条的样式 self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent; //默认是白色  B ...

  10. SpringMVC源码分析(3)DispatcherServlet的请求处理流程

    <springmvc源码分析(2)dispatcherservlet的初始化>初始化DispatcherServlet的多个组件. 本文继续分析DispatcherServlet解析请求的 ...