本文主要讲述使用MindOpt工具优化人员排班的数学规划问题。
视频讲解👈👈👈👈👈👈👈👈👈
一、案例场景
随着现在产业的发展,7*24小时服务的需要,人员排班的问题,逐渐成为了企业管理中的重要环节。人员排班在许多行业都具有广泛的应用价值,主要包括但不限于以下几个方面:
- 制造业:生产车间的人员分配、班次安排和轮班计划等,需要根据产线的工作要求和员工的技能特点进行合理的排班。
- 医疗行业:医院、诊所等机构需要对医生、护士等员工进行排班。
- 餐饮业:餐厅、咖啡馆等服务场所需要根据客流高峰期和低谷期合理安排员工的工作时间。
- 零售业:商场、超市等零售场所需要根据营业时间、客流量和节假日等因素进行人员排班。
- 客服中心:呼叫中心、在线客服等服务机构需要根据客户咨询需求进行员工排班。
那么如何合理高效的进行人员排班呢,运筹学中的数学规划方法是计算人员排班问题的一个好方案。人员排班问题在建模时需要考虑多种约束条件,比如:
- 用工需求约束:根据各岗位的工作任务和生产要求,保证每个岗位在每个时间段内有足够的员工进行工作。
- 员工能力约束:不同岗位可能需要不同的技能和经验,需要确保安排到相应岗位的员工具备相关的能力和资质。
- 工作时间约束:员工的工作时间需要遵守相关法律法规,比如每天工作时间上限、休息时间要求等。此外,还需要考虑员工的工作时间偏好,如部分员工可能只能接受特定时间段的工作安排。
- 连续工作天数约束:为保证员工的工作质量和身体健康,通常要求连续工作天数不超过一定限制。以及员工在一定时间周期内有休假要求,需要确保他们的休假安排得到满足。
- 公平性约束:为保障员工的权益,要求在满足以上约束的前提下,尽量平衡各员工的工作时间和任务分配,避免出现工作负担不均衡的情况。
下面我们将通过一个简单的例子,讲解如何使用数学规划的方法来做人员排班。
二、问题描述
一个公司有客户岗位工作需要安排,不同的时间段有不同的用户需求。公司安排员工上班的班次有三种,分别是早班、晚班和夜班。工作时间的规则是一周最多安排五天上班。怎么排班才能使总共排的班次最少?这个问题主要考虑以下两点因素:一是工作需求,就是每天需安排多少员工值班;二是排班规则和约束,对工作时间、连续工作天数、以及员工休息的时间进行合理安排。
请问怎么安排总上班的班次最少,此时的班表是什么样的?
三、代码解析
在案例中,我们对这个问题进行数学建模和代码转化,用到MindOpt云上建模求解平台(一个页面版的线上开发环境,可在线的开发调试代码)、以及达摩院研发的建模语言MindOpt APL,与学公式非常贴近。
工具:
- MindOpt Studio 云建模平台,在线开发调试,免下载
- MindOpt APL(MAPL)建模语言编程,代数建模语言,语法与数学公式相近
- MindOpt优化求解器:帮我们求解大规模数据的数学规划问题。
声明集合
在这个案例中,我们使用的是读取CSV数据的方式说明集合,所以我们需要先讲述简单讲述读取数据表格的语法。比如第一个集合schedule,是我们读取的班次名称,先是读取班次表格,以及as后面跟着1s和skip1,s和n是读取表格中数据的两种类型,s是字符串的类型,n是数值类型。
在班次表中,1s代表表格中第一列的字符串,即早班、晚班和夜班;skip1即忽略表头班次,读取班次名称
需求人数表中,1n是表格中第一列的数值即1—7,读取排班日期
声明参数
参数totalSlots
每天每个班次的人员需求;在d这个日期,三个班次分别需要多少员工上班;
max employee参数ceil 是mapl语法中的运算符,含义为向上取整
七天内总共的待排班次除以5,向上取整是20,为了符合我们的例题,进行加一为21,让排班更公平;
声明变量
其中day表示每一天,schedule是班次(早班、晚班和夜班),employee是每个员工,binary表示x为0,1变量,“0”表示没有值班,“1”代表值班。
声明约束
第一个约束是循环日期day和班次schedule,员工e在d日期的s班次需要大于等于在d日期s班次的人员需求,不等式左侧为每天所有班次的员工总人数,右侧为七天值班总的需求人数
第二个约束是循环日期和员工的集合employee。每个员工每天值班状态的总和需小于等于一,即每人每天只安排一个班次。
第三个约束是定义了新的集合,利用without差分运算,让去掉最后一天(最后一天不会安排第二天的值班情况),这里循环的是每个员工和新的日期,也就是e员工在d这天,他的夜班状态是一的话,加上第二天早班的状态之和需小于等于一,即前一天是晚班,第二天不会排早班。
最后一条约束是一周工作时间不能超过五天,这里循环的是每个员工。不等式的左边为七天内每个员工所有值班的状态之和。
最后是声明的目标最小化每天每个班次的人数,在这里建模过程就已经结束了,然后就可调用解指令求解、打印指令。
结果
将结果输入csv表格
print "{}, {}, {}" % "日期", "班次", "员工" : "Schedule_Results.csv"; #打印表头 close "Schedule_Results.csv"; #关闭文件 # 遍历所有可能的日期d、班次s和员工e组合,并检查变量x[d,s,e]的值。如果该变量的值大于0, # 意味着在该日期d、班次s,员工e被安排了工作。然后将这些信息追加到文件中 forall {<d,s,e> in Day*Schedule*Employee with x[d,s,e] >0} print "{}, {}, {}" % d, s,e >> "Schedule_Results.csv"; close "Schedule_Results.csv";
部分结果如下:
即,1号早班安排了编号4、7、10、14、15员工上早班。
四、内容回顾
本期主要讲述的是人员排班问题,满足每天的用工需求和排班规则,尽可能的将人工成本最小化。
求解问题使用的工具,是使用的是阿里巴巴达摩院的MindOpt,可以在opt.aliyun.com平台上编写代码,编程代码的语言MAPL。
获取源代码