上一篇介绍了《使用.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. char类型

    1.JAVA中,char占2字节,16位.可在存放汉字 2.char赋值 char a='a';  //任意单个字符,加单引号. char a='中';//任意单个中文字,加单引号. char a=1 ...

  2. WEB版一次选择多个文件进行批量上传(swfupload)的解决方案

    说明:功能完全支持ie和firefox浏览器! 一般的WEB方式文件上传只能使用FileUpload控件进行一个文件一个文件的进行上传,就算是批量上传,也要把文件一个一个的添加到页面,无法如windo ...

  3. Eclipse sysout 和 fore 不起作用

    Content Assist ↑ 这是主角,可以快速生成语句. sysout 快捷键之后生成了 System.out.println(); fore 快捷键之后生成了 for(String arg : ...

  4. ssh+注解开发 pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  5. day29(对象转xml(使用java))

    通常使用xStream工具. 将集合,数组,对象转成XML. 导入两个包: xpp3_min-1.1.4c.jar xstream-1.4.4.jar 自定义一个类 package com.baidu ...

  6. 【repost】Javascript操作DOM常用API总结

    Javascript操作DOM常用API总结 文本整理了javascript操作DOM的一些常用的api,根据其作用整理成为创建,修改,查询等多种类型的api,主要用于复习基础知识,加深对原生js的认 ...

  7. Java案例:超市库存管理系统

    案例介绍: 模拟真实的库存管理逻辑,完成超市管理系统的日常功能实现,见下图 案例需求分析: 根据案例介绍,我们进行分析,首先需要一个功能菜单,然后输入功能序号后,调用序号对应的功能方法,实现想要的操作 ...

  8. 区间DP POJ1160村庄邮局问题

    POJ1160 题目大意:一系列村庄在一维坐标系上有序的排列,建设p个邮局,问各个村庄到邮局的最短距离和. 线性区间DP问题 dp数组的值为最短/最优距离 村庄和邮局为限制 dp[i][j]表示前i个 ...

  9. Android-Java-同步方法-synchronized

    1.方法具有封装性: /** * 1.方法具有封装性: */ public void addMoney(double moneyAsset) { this.moneyAsset += moneyAss ...

  10. scrapy中Request中常用参数

    url: 就是需要请求,并进行下一步处理的url callback: 指定该请求返回的Response,由那个函数来处理. method: 一般不需要指定,使用默认GET方法请求即可 headers: ...