Google Optimization Tools实现员工排班计划Scheduling【Python版】
上一篇介绍了《使用.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版】的更多相关文章
- 使用.NET Core与Google Optimization Tools实现员工排班计划Scheduling
上一篇说完<Google Optimization Tools介绍>,让大家初步了解了Google Optimization Tools是一款约束求解(CP)的高效套件.那么我们用.NET ...
- 使用.NET Core与Google Optimization Tools实现加工车间任务规划
前一篇文章<使用.NET Core与Google Optimization Tools实现员工排班计划Scheduling>算是一种针对内容的规划,而针对时间顺序任务规划,加工车间的工活儿 ...
- Google Optimization Tools实现加工车间任务规划【Python版】
上一篇介绍了<使用.NET Core与Google Optimization Tools实现加工车间任务规划>,这次将Google官方文档python实现的版本的完整源码献出来,以满足喜爱 ...
- Google Optimization Tools介绍
Google Optimization Tools(OR-Tools)是一款专门快速而便携地解决组合优化问题的套件.它包含了: 约束编程求解器. 简单而统一的接口,用于多种线性规划和混合整数规划求解, ...
- 详解 OneAlert 排班可以帮你做什么
排班的存在,实质是通过有序安排,降低企业/团队人力成本,提升工作效率. 阅读导航(预计2min) 1. 详解排班功能 轮班机制 工作时间 双视图展示 灵活调整 2. 利用排班如何助力运维团队 排班 ...
- 使用SQL语句使数据从坚向排列转化成横向排列(排班表)
知识重点: 1.extract(day from schedule01::timestamp)=13 Extract 属于 SQL 的 DML(即数据库管理语言)函数,同样,InterBase 也支持 ...
- Google PageSpeed Tools 性能测试分析
今天给大家介绍下一个工具:Google PageSpeed Tools,根据官方的介绍,简单梳理如下: Page Speed Insights能针对移动设备和电脑设备衡量网页的性能.该工具会抓取网址两 ...
- c++实现医院检验科排班程序
c++实现医院检验科排班程序 1.背景: 医院急诊检验科24h×7×365值班.工作人员固定.採取轮班制度.确保24h都有人值班. 本文就通过C++实现编敲代码自己主动排班,并能够转为Excel打印. ...
- Javascript:日期排班功能实现
背景: 近期,公司的产品经常会遇到日期排班类似的功能: 需求的排班日期长短不一:有些是两周,有些是四周:要求选中的时候有一个active的状态区分,另外要提供钩子获取选中日期的形如:[2018-04 ...
随机推荐
- IDEA插件开发总结
一:前置步骤 1.添加开发插件所需的SDK: 1.1先添加JDK 1.2打开Project Structure-Platform Settings-SDKs 1.3添加IntelliJ Platfor ...
- JDK线程池的使用
转载自:https://my.oschina.net/hosee/blog/614319: 摘要: 本系列基于炼数成金课程,为了更好的学习,做了系列的记录. 本文主要介绍: 1. 线程池的基本使用 2 ...
- Java学习第1天:序言,基础及配置tomcat
所谓是福不是祸,是祸躲不过,到底还是回到java的阵地上来.既然它这么热,那就学学它,现在这件事已经提上议事日程,也已经开始. 今天做的事: 泛泛的翻了几本书,敲了一些练习代码,比如字符串操作,接口等 ...
- NSUserDefaults 添加与删除
//NSUserDefaults会创建一个plist文件,内部存放一个字典 NSUserDefaults *userDefaults = [NSUserDefaults standardUser ...
- POJ2385--Apple Catching(动态规划)
It is a little known fact that cows love apples. Farmer John has two apple trees (which are convenie ...
- Android 批量打包利器
因为添加了渠道号,对应不同的渠道包,此时,动不动就几十个包,实在让人头疼,此时,需要引入自动打包功能. 首先,列举出援引的博客内容 美团Android自动化之旅—生成渠道包 http://tech.m ...
- hdu 4704 Sum 【费马小定理】
题目 题意:将N拆分成1-n个数,问有多少种组成方法. 例如:N=4,将N拆分成1个数,结果就是4:将N拆分成2个数,结果就是3(即:1+3,2+2,3+1)--1+3和3+1这个算两个,则这个就是组 ...
- hdu 5074 相邻数和最大dp
http://acm.hdu.edu.cn/showproblem.php?pid=5074 给定一个序列 有些位数未知,给你所有两个数连续所得到的能量,问你怎么安排数字使得总能量最大 二维dp,dp ...
- nodeclub models
之前看过keystone的结构,所以现在看nodeclub时,总会和keystone进行比较. nodeclub models会有一个index来作为facade,通过它连接mongodb,expor ...
- Android-Java-类与对象的关系
类class 例如:class Student {},很多人把class Student {}称为对象或实体,其实这样并不合理,应该称为描述实体/描述对象: 因为被称为对象或实体的是,new Stud ...