人员排班【数学规划的应用(含代码)】阿里达摩院MindOpt

本文主要讲述使用MindOpt工具优化人员排班的数学规划问题。
视频讲解👈👈👈👈👈👈👈👈👈

image.png

一、案例场景

随着现在产业的发展,7*24小时服务的需要,人员排班的问题,逐渐成为了企业管理中的重要环节。人员排班在许多行业都具有广泛的应用价值,主要包括但不限于以下几个方面:

  • 制造业:生产车间的人员分配、班次安排和轮班计划等,需要根据产线的工作要求和员工的技能特点进行合理的排班。
  • 医疗行业:医院、诊所等机构需要对医生、护士等员工进行排班。
  • 餐饮业:餐厅、咖啡馆等服务场所需要根据客流高峰期和低谷期合理安排员工的工作时间。
  • 零售业:商场、超市等零售场所需要根据营业时间、客流量和节假日等因素进行人员排班。
  • 客服中心:呼叫中心、在线客服等服务机构需要根据客户咨询需求进行员工排班。

那么如何合理高效的进行人员排班呢,运筹学中的数学规划方法是计算人员排班问题的一个好方案。人员排班问题在建模时需要考虑多种约束条件,比如:

  • 用工需求约束:根据各岗位的工作任务和生产要求,保证每个岗位在每个时间段内有足够的员工进行工作。
  • 员工能力约束:不同岗位可能需要不同的技能和经验,需要确保安排到相应岗位的员工具备相关的能力和资质。
  • 工作时间约束:员工的工作时间需要遵守相关法律法规,比如每天工作时间上限、休息时间要求等。此外,还需要考虑员工的工作时间偏好,如部分员工可能只能接受特定时间段的工作安排。
  • 连续工作天数约束:为保证员工的工作质量和身体健康,通常要求连续工作天数不超过一定限制。以及员工在一定时间周期内有休假要求,需要确保他们的休假安排得到满足。
  • 公平性约束:为保障员工的权益,要求在满足以上约束的前提下,尽量平衡各员工的工作时间和任务分配,避免出现工作负担不均衡的情况。

下面我们将通过一个简单的例子,讲解如何使用数学规划的方法来做人员排班。

二、问题描述

image.png
一个公司有客户岗位工作需要安排,不同的时间段有不同的用户需求。公司安排员工上班的班次有三种,分别是早班、晚班和夜班。工作时间的规则是一周最多安排五天上班。怎么排班才能使总共排的班次最少?这个问题主要考虑以下两点因素:一是工作需求,就是每天需安排多少员工值班;二是排班规则和约束,对工作时间、连续工作天数、以及员工休息的时间进行合理安排。

请问怎么安排总上班的班次最少,此时的班表是什么样的?

三、代码解析

vcg_VCG41N597675000_RF.jpg
在案例中,我们对这个问题进行数学建模和代码转化,用到MindOpt云上建模求解平台(一个页面版的线上开发环境,可在线的开发调试代码)、以及达摩院研发的建模语言MindOpt APL,与学公式非常贴近。
工具:


声明集合

image.png
在这个案例中,我们使用的是读取CSV数据的方式说明集合,所以我们需要先讲述简单讲述读取数据表格的语法。比如第一个集合schedule,是我们读取的班次名称,先是读取班次表格,以及as后面跟着1s和skip1,s和n是读取表格中数据的两种类型,s是字符串的类型,n是数值类型。
image.pngimage.png
在班次表中,1s代表表格中第一列的字符串,即早班、晚班和夜班;skip1即忽略表头班次,读取班次名称
需求人数表中,1n是表格中第一列的数值即1—7,读取排班日期

声明参数

image.png
参数totalSlots
每天每个班次的人员需求;在d这个日期,三个班次分别需要多少员工上班;

max employee参数ceil 是mapl语法中的运算符,含义为向上取整
七天内总共的待排班次除以5,向上取整是20,为了符合我们的例题,进行加一为21,让排班更公平;

声明变量

image.png
其中day表示每一天,schedule是班次(早班、晚班和夜班),employee是每个员工,binary表示x为0,1变量,“0”表示没有值班,“1”代表值班。

声明约束

image.png
第一个约束是循环日期day和班次schedule,员工e在d日期的s班次需要大于等于在d日期s班次的人员需求,不等式左侧为每天所有班次的员工总人数,右侧为七天值班总的需求人数
image.png
第二个约束是循环日期和员工的集合employee。每个员工每天值班状态的总和需小于等于一,即每人每天只安排一个班次。
image.png
第三个约束是定义了新的集合,利用without差分运算,让去掉最后一天(最后一天不会安排第二天的值班情况),这里循环的是每个员工和新的日期,也就是e员工在d这天,他的夜班状态是一的话,加上第二天早班的状态之和需小于等于一,即前一天是晚班,第二天不会排早班。
image.png
最后一条约束是一周工作时间不能超过五天,这里循环的是每个员工。不等式的左边为七天内每个员工所有值班的状态之和。
image.png
最后是声明的目标最小化每天每个班次的人数,在这里建模过程就已经结束了,然后就可调用解指令求解、打印指令。
image.png

结果

将结果输入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";

部分结果如下:
image.png
即,1号早班安排了编号4、7、10、14、15员工上早班。

四、内容回顾

本期主要讲述的是人员排班问题,满足每天的用工需求和排班规则,尽可能的将人工成本最小化。
求解问题使用的工具,是使用的是阿里巴巴达摩院的MindOpt,可以在opt.aliyun.com平台上编写代码,编程代码的语言MAPL。
获取源代码
image.png
人员排班问题-MindOpt Studio

  • 26
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
背包算法通常是用来解决“装满背包”这类问题的,但是也可以应用排班问题中。以下是实现巡检线路排班数学模型的详细步骤: 1. 首先,将巡检线路划分成若干个巡检点,每个巡检点包一定的巡检任务。将每个巡检点的巡检任务量作为背包中的一个物品,将所有巡检点作为背包中的物品集合。 2. 然后,将所有可用的巡检人员作为背包的容量限制,即背包的最大承重。 3. 接下来,使用0/1背包算法求解背包问题,得到一个最优的巡检任务分配方案。 4. 最后,根据巡检任务分配方案,将巡检人员分配到各个巡检点,完成排班问题的求解。 以下是用 Python 实现巡检线路排班数学模型代码: ```python def schedule(patrol_points, patrol_staff): n = len(patrol_points) # 巡检点数量 m = len(patrol_staff) # 巡检人员数量 dp = [[0] * (m+1) for _ in range(n+1)] # 初始化动态规划表 # 计算巡检任务量 patrol_tasks = [sum(p) for p in patrol_points] # 0/1背包算法 for i in range(1, n+1): for j in range(1, m+1): if patrol_tasks[i-1] <= patrol_staff[j-1]: dp[i][j] = max(dp[i-1][j], dp[i-1][j-1] + patrol_tasks[i-1]) else: dp[i][j] = dp[i-1][j] # 回溯得到最优巡检任务分配方案 schedule = [0] * n j = m for i in range(n, 0, -1): if dp[i][j] > dp[i-1][j]: schedule[i-1] = 1 j -= 1 # 返回最优巡检任务分配方案 return schedule ``` 其中,`patrol_points` 是一个二维列表,表示每个巡检点的巡检任务量;`patrol_staff` 是一个一维列表,表示可用的巡检人员数量。函数返回一个一维列表,表示最优的巡检任务分配方案。如果 `schedule[i] == 1`,则表示第 `i+1` 个巡检点被分配了巡检任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值