【算法】基于优先级的排班算法实现

员工到岗排班算法实现 1、需求描述 每周5个工作日,每个工作日只要求全员的部分员工到岗,实现公平下的自动排班,给出一个月的排班明细。 2、代码实现 /** * 自动排班 **/ public class ScheduleAutoJob { public static void main(String[] args) { //员工数组 String[] employeeArray = {"张三", "李四", "王五", "李丽", "孙萌", "张凯", "李炜", "赵明" 阅读详情

场景:在大学的里,有不少社团组织会要组织中的成员值班,当然这个值班时间是学生无课的时间才会被安排值班。

假设现有如下需求:一天中有3个时间段要有人值班,每周周一到周五都要值班,就是共有15个值班段,每个时间段值班的人都不一样,现有40个学生,要求根据这些学生的无课表情况安排值班,要求每个值班段必须有两个人,每个人一周只值班一次(如果某一值班段只有一人无课,那该值班段就只能一人值班)。

 

小插一题,做一排列组合题:

有10个相同的糖果,颁给3个小人,要求每个人至少有2个糖果,问共有多少种分法?

(自行解答,2014年阿里实习生招有个这样的题:有10个相同的糖果,颁给3个小人,要求每个人至少有1个糖果,问共有多少种分法?)

 

排班算法设计的难点主要在于每个人的无课表都不一样,如果像上面的题那样的,不用根据每个人的无课表,每个人在任意一值班段都能值班,那就简单啦。

以下讲讲个人算法的设计:

1.  基于回溯法的遍历:(实现思路:当安排到第N个值班段时,发现没有满足条件的可以选,就回溯到第N-1个值班段重新安排,如果第N-1个值班段的人都试过但第N个值班段还是没有满足条件的可以选,就回溯到第N-2个值班段,以此类推不断回溯)

现将上面的问题数据量缩小下来分析下这个问题:

假设有三个值班段,三个人,根据这三个人的无课表情况给值班段安排人值班。

思路:

先在第一个值班段无课的人中选择一个人安排到该值班段值班,被安排过的人就被标志为被安排值班(flag为0表示未被安排,flag为1表示已被安排),就不能再被安排到其他值班段值班了,以此类推,安排完一个值班段就安排下一个值班段。

最好情况:

最好情况下就是安排到每个值班段都有人未被安排过值班的人,这样一次性所有就排完了,如下图:


(1、2、3表示值班段,每个值班段里的字母表示该值班段无课的人,如上面第1个值班段有A和B两个人无课,可以安排在该值班段值班)

A被安排到1值班段,

B被安排到2值班段,

C被安排到3值班段。

 

最坏情况:

如下图所示:


安排到第三个值班段时因为A已经被安排过值班,所以要回溯到第二个值班段重新安排,就给第二个值班段安排C值班,但此时第三个值班段还是没人可以值班,而第二个值班段的人也都遍历过了,所以此时就要回溯到第一个值班段重新安排,此时:

B被安排到1值班段,

C被安排到2值班段,

A被安排到3值班段。

 

上面的是基本思路,但如果对15个值班段,40个人来排班,考虑下最坏情况,如果刚好到第十五个值班段时没人可以值班,而最后回溯到第一个值班段重新遍历,那查找比较次数都会大大增多,所以最后还是没有采取这种方法。不过个人也没能递归实现这个算法,有空再研究研究。

 

2.  基于优先级的选择:(实现思路:安排值班时不是从第一个值班段顺序地安排到第十五个值班段,因为在15个值班段中,有些值班段无课的人比较多,此时的选择就比较多,而有此值班段无课的人很少,那么这个值班就要优先安排人值班,比如有个值班段只有两人无课,那就要先安排这两个人在该值班段值班,这是第一个优先级;每个人一周内无课的次数都不一样,有些人一周只有一两次无课的时间,而有些人一周有五六次无课的时间,在一个值班段选择谁在该值班段值班时优先选择无课次数少的,这是第二个优先级)

<span style="font-family:SimSun;font-size:14px;">// 值班段类
public class DutyTime {
	private String time;  // 值班时间
	private List<User> freeUsers = new ArrayList<User>();  // 该时间段无课的人
	private List<User> dutyUsers = new ArrayList<User>();  // 该时间段值班的人员	
	public DutyTime(){}
	
	public DutyTime(String time) {
		super();
		this.time = time;
	}
	// 省略get set
}
</span>


<span style="font-family:SimSun;font-size:14px;">// 人员
public class User {
	private String name;
	private int num;  // 该人一周无课时间段数
	
	public User(){}
	public User(String name) {
		super();
		this.name = name;
	}
<span style="white-space:pre">	</span>// 省略get set
}
</span>

<span style="font-family:SimSun;font-size:14px;">/**
 * 值班安排:
 * 	先为每个值班段安排一名人员值班(第一轮),安排一轮后再进行第二轮、第三轮
 * 按优先级安排值班:
 *  1.各个值班段可值班人员数少的优先安排值班
 *  2.在一个值班段选择人员时,优先选择总无课次数少的人
 *  	注:人员在被安排后就会从该值班段中的无课人员集合中删除,这样之后就不用再遍历到;在一轮安排后开始下一轮时,每个值班段的排人顺序会重新调整(因为去掉了已被安排的人)
 *
 */
public class Schedule3 {
	public static void main(String[] args) {
		
		User A = new User("A", 4);  // A一周有4个时间段无课
		...
		
		DutyTime time1 = new DutyTime("1");  // 第一个值班段
		...
		
		time1.getFreeUsers().add(A);
		...
		
		List<DutyTime> dutyTimeList = new ArrayList<>();
		dutyTimeList.add(time1);
		...
		
		for (int w = 0; w < 3; w++) {
			// 排序,可用于值班的人数少的值班段排在前面,下面安排值班是可用于值班的人数少的值班段优先安排
			dutyTimeList = dutyTimeSort(dutyTimeList);
			// 遍历已排好序的值班段,为每个值班段安排值班人员
			for (int i = 0; i < dutyTimeList.size(); i++) {
				// 如果该值班段有无课的人才安排值班
				if (dutyTimeList.get(i).getFreeUsers().size() > 0) {
					// 得到的都是未被安排过值班的人,并排好序,总无课次数少的人排前面
					List<User> freeUserList = freeUserSort(dutyTimeList.get(i).getFreeUsers());
					
					// 将可在该值班段值班的人安排到该值班段值班
					dutyTimeList.get(i).getDutyUsers().add(freeUserList.get(0));
					System.out.println(freeUserList.get(0).getName() + " 被安排到" + dutyTimeList.get(i).getTime() + "值班;该值班段现有"+dutyTimeList.get(i).getDutyUsers().size()+"人值班,"+freeUserList.get(0).getName()+"一周总无课次数为:"+freeUserList.get(0).getNum());
					
					// 将被安排的人从各个值班段(有该人的值班段)中删除,下次不用再遍历
					User delUser = freeUserList.get(0);
					for (int j = 0; j < dutyTimeList.size(); j++) {
						if (dutyTimeList.get(j).getFreeUsers().contains(delUser)) {
							dutyTimeList.get(j).getFreeUsers().remove(delUser);
							System.out.println("---"+delUser.getName()+"已从"+dutyTimeList.get(j).getTime()+"值班段删除,目前该值班段剩余未被安排人数有:"+dutyTimeList.get(j).getFreeUsers().size());
						}
					}
					
				}else {
					System.out.println(dutyTimeList.get(i).getTime()+"该值班段已无人可安排值班");
				}
			}
			
			System.out.println("---------------------安排了一轮--------------------");
		}
	}
	
	// 对某一值班段中无课的人进行排序(一周总无课次数少的人排在前面)
	public static List<User> freeUserSort(List<User> freeUserList);
	
	// 对值班段排序(可用于值班的人数少的值班段排在前面)
	public static List<DutyTime> dutyTimeSort(List<DutyTime> dutyTimeList);
}</span>

使用这种方法实现排班只能生成一张值班表,但现实中根据总的无课表是可以排出不同方案的值班表的,以上的算法小编只是在满足个人项目需求的情况下设计的,并不是通用的,小编查过许多高校的教授发表的关于排课算法实现的论文,那些情况就更加复杂了,各种回溯各种优先级。

排课问题在70年代就证明是一个NP完全问题,即算法的计算时间是呈指数增长的,这一论断确立了排课问题的理论深度。对于NP问题完全问题目前在数学上是没有一个通用的算法能够很好地解决。



Author:顾故

Sign:别输给曾经的自己








排班算法 java_【算法】基于优先级的排班算法实现 场景:在大学的里,有不少社团组织会要组织中的成员值班,当然这个值班时间是学生无课的时间才会被安排值班。假设现有如下需求:一天中有3个时间段要有人值班,每周周一到周五都要值班,就是共有15个值班段,每个时间段值班的人都不一样,现有40个学生,要求根据这些学生的无课表情况安排值班,要求每个值班段必须有两个人,每个人一周只值班一次(如果某一值班段只有一人无课,那该值班段就只能一人值班)。小插一题,做一排... 阅读详情

相关推荐

java排班算法-几班几倒

System.out.println(i + 1 + "号排班:"+ dutyArr[(j+a)-dutyNum]);System.out.println(i + 1 + "号排班:"+ dutyArr[j+a]);String[] classArr = {"早班","中班","晚班","休息","休息"};String[] dutyArr = {"A组","B组","C组","D组","E组"};* 获取某个月的天数。

半人玖 2753

医院排班算法 护士排班法

护士是医院日常运营的基础,科学合理地安排护士工作时间不仅能够缓解其压力,提高护理质量,而且能够降低医院的人力资源运营成本,因此护士排班已成为医院管理工作的重要内容之一。 一、周排班法   排班以周为周期的方法为周排班法。一般由病房护士长根据病房护理工作情况进行安排。周排班的特点是对护理人员的值班安排周期短,有一定灵活性,护士长可根据具体需要对护理人员进行动态

书写人生 3万+

iOS集成TensorFlow Lite配置教程

公司最近的项目本地计算评估PWV 总算告一段落,对于目前的解决方案TensorFlow for iOS,整个过程之长、坑之多,让我发际线提高了2cm。。。之后应该会有一篇技术总结,正在准备。下一步的计划是,TensorFlow 转到 TensorFlow Lite,在mobile上用TF,简单的模型还好,复杂的模型感觉跑起来有点力不从心,目前TF lite预览版,支持的model貌似不多,正在做些尝

Dr的专栏 6481

干货 | 10分钟给上万客服排好班,携程大规模客服排班算法实践

作者简介博天,携程高级研发经理,关注大规模约束优化问题的建模和算法设计。一、背景客户服务部门是携程以服务质量赢得客户信赖的基石,其拥有上万名一线的客服,每天进线量巨大;且伴随着业务量的起...

携程技术 3174

ASP值班资源调度插件开发与实战

报警系统的核心在于准确识别报警源并分类处理。报警源可以是系统日志、监控工具、硬件设备或外部接口调用等。在ASP环境下,报警源通常通过HTTP请求、数据库写入或文件读取的方式传入系统。以下是一个典型的报警事件结构定义:<%' 报警事件结构定义EventType = Request.Form("type") ' 事件类型SourceIP = Request.ServerVariables("REMOTE_ADDR") ' 触发源IPTriggerTime = Now() ' 触发时间。

weixin_42515340的博客 1022

RWEQ土壤风蚀模型的估算与变化归因分析

本次以介绍RWEQ模型的基本原理及数据需求,再结合案例讲解RWEQ模型中区域地理空间数据库构建的方法和各个参量提取的原理与方法,最后结合典型案例进行综合讲解风蚀模数估算、制图及归因分析。空间分析与制图:提取分析、局部分析、邻域分析、区域分析、插值分析、平滑处理、像元提取、采样与重采样。以某实际应用为案例,掌握RWEQ模型进行当地土壤风蚀量空间分布分析整体流程。地图服务器、在线地图、范围指示器、格网、表格、基础地图服务使用规则介绍。掌握土壤风蚀模型的原理、优势点及因子组成。

2301_77413856的博客 1193

3分钟学会明日方舟智能排班系统,告别手操基建管理

还在为《明日方舟》基建排班耗费大量时间吗?每天需要手动安排干员上班、下班、宿舍休息,还要监控心情值、赤金产量、无人机使用时机?GitHub加速计划中的arknights-mower项目为你提供了一套完整的自动化解决方案,让你彻底告别繁琐的手动操作。 ## 🚀 项目核心价值与痛点解决 这款智能排班系统专门针对《明日方舟》基建管理中的核心痛点设计: **解决的主要问题**: - 干员心情管理混

gitblog_01107的博客 1200

用UltraISO制作镜像以RAW格式刻录系统到U盘后,在Windows上无法识别的解决办法

在这篇文章中,用UltraISO制作镜像后,会使得U盘无法识别!!!那么,如何抹掉U盘的数据,格式化U盘呢?

拥抱具身智能,昇腾Ascend C 2730

解决日程矛盾的核心技术:FullCalendar事件冲突检测算法

日程安排中最令人头疼的问题莫过于事件冲突——当两个会议安排在同一时间段,或预约重叠时,传统日历工具往往只能被动提示,却无法智能化解。FullCalendar作为一款功能全面的JavaScript日历组件,其内置的事件冲突检测算法通过约束验证、时间区间计算和智能重叠判断,为开发者提供了高效解决日程矛盾的底层技术支持。本文将从应用场景出发,解析其核心实现原理,帮助运营和开发人员快速掌握冲突处理技巧。 ...

gitblog_00351的博客 603

STM32CUBEMX+STM32H750VB+LWIP+LAN8720A+FREERTOS TCP服务器、UDP数据接收发送、网线热插拔、IAR-8.32开发

STM32CUBEMX+STM32H750VB+LWIP+LAN8720A+FREERTOS TCP服务器、UDP数据接收发送、网线热插拔、IAR-8.32开发STM32H750VB使用STM32CUBEMX生成工程IAR+J-LINK调试准备工作CUBEMX生成的代码问题所在如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章U

qq_37433166的博客 5344

关于卷积过程中通道数如何变化问题

对卷积操作前后通道数问题进行解释,输出通道数=卷积核的个数。

你好,明天,,的博客 4316

Arknights-Mower智能基建调度系统深度解析

《明日方舟》作为一款深受玩家喜爱的塔防游戏,其复杂的基建系统既是游戏乐趣所在,也是玩家时间投入的重头戏。Arknights-Mower项目正是为了解决这一痛点而生,它通过智能算法和自动化技术,让玩家从繁琐的基建管理中解放出来。 ## 系统架构概览 Arknights-Mower的任务调度系统采用分层架构设计,通过模块化组件实现复杂的基建管理逻辑。核心架构分为五层: - **数据采集层**:负

gitblog_01038的博客 953

重磅!AI实时读取总结微信聊天记录,附MCP协议+智能体配置教程!

【摘要】本文介绍了一套AI实时分析微信聊天记录的解决方案,通过Chatlog+Trae+MCP协议实现智能整理群聊信息。Chatlog作为开源工具本地解析微信数据,确保隐私安全;Trae提供AI分析能力,支持自然语言处理。操作步骤包括:1)下载运行Chatlog并启动HTTP服务;2)安装Trae配置MCP协议;3)创建智能体设置提示词。该方案虽需初始配置,但能有效解决群聊信息过载问题,自动提炼关键内容,避免有价值信息被淹没。文中提供了详细教程链接和网盘资源。

puyihuan的博客 1万+

资源受限项目调度与人员排班优化:从数学建模到算法求解实战

资源调度与优化是运筹学和工业工程领域的核心问题,旨在通过数学方法对有限资源进行高效分配,以达成特定目标。其基本原理是将现实中的任务、资源、约束和目标抽象为决策变量、目标函数和约束条件构成的数学模型,如混合整数线性规划模型。该技术的核心价值在于解决NP-hard的组合优化难题,能显著提升资源利用率、缩短项目周期、降低成本,广泛应用于软件研发、生产制造、医疗排班等场景。本文聚焦于资源受限的项目调度与人员排班这一混合优化问题,深入剖析了如何将复杂的实际需求转化为可计算的数学模型,并探讨了结合精确求解器与启发式算法

weixin_32466193的博客 320

zemax 如何编译用户自定义DLL(含VS下载教程)

zemax 如何编译用户自定义DLL(含VS下载教程)

weixin_72050316的博客 491

C# 与华中数控设备通信:数控机床自动化控制与实时监测系统

华中数控系统与C#通信开发指南 核心要点 通信基础 支持串口(RS232/RS485)和以太网两种连接方式 协议选择:通用Modbus协议或华中自定义HNC协议 关键数据映射表明确各参数对应的寄存器地址和功能码 系统架构 四层架构:设备层→通信层→业务层→应用层 包含实时数据采集、指令下发、状态监控、异常处理全流程 支持Modbus和HNC协议动态切换 代码实现 串口通信使用NModbus库简化开发 提供连接管理、数据读取、指令下发完整示例 包含异常处理和超时重连机制 应用价值 实现数控机床远程监控和自动化

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 2018

医生预约系统开发:调度算法与高并发实践

医疗信息系统在现代医疗体系中扮演着关键角色,其核心在于通过数字化手段优化资源配置。以医生预约系统为例,采用B/S架构结合时间片轮转与优先级调度算法,能有效提升门诊效率40%以上。系统实现涉及Spring Boot后端开发、Vue前端组件化设计以及MySQL事务处理,其中乐观锁与分布式锁技术解决了高并发场景下的超卖问题。医疗系统特别强调数据安全,需符合等保2.0要求,采用PBKDF2WithHmacSHA1加密算法和动态脱敏技术保障患者隐私。这类系统典型应用于医院门诊管理、互联网医疗平台等场景,其技术方案对电

weixin_28716973的博客 313

交换机初始化配置详解

MGMT或称MGT(Management Port,管理端口)是一个可以连接计算机的三层主机端口,如下图所示。只需使用一条双绞线跳线,就可以将计算机的以太网端口与交换机的MGMT端口连接在一起,实现对交换机的配置与管理。也就是说,可以使用MGMT端口代替Console端口实现对交换机或交换机堆叠的网络管理。MGMT端口既可用于交换机的初始化,也可以在交换机初始化完成后,以Telnet、Web浏览器或Cisco CNA方式进行管理。当将计算机连接到独立的交换机时,连接方式如下图所示。

悦分享 1993

【员工排班优化调度】基于多目标遗传算法的多技能员工排班调度(Matlab代码实现)

班组(Crew)以j作为其序号,每个班组具有特定的任务能力(如能做某类任务,不能做某类任务);针对其能力所及的任务﹐班组因其人员组成的能力或配置的设备能力不同,具有不同的作业效率(效率采用完成该任务的小时数来表示)。对班组根据其任务能力和作业效率进行班组类别(Crew_Type)划分,即相同类别的班组完成同一任务的作业效率相等。对于企业管理者来说,如何合理的分配员工去完成任务,是降低企业运行费用,提升企业产品开发的重要手段。现代化企业需要制定一套科学的方法对员工进行任务分配,以达到最大的效益。

m0_64583023的博客 1142

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

基于Java的门诊医生排班管理系统的设计与实现

本研究旨在开发门诊医生排班管理系统,以提升医疗效率和服务质量。系统通过自动化排班优化资源配置,减少人工干预和临时调度,降低运营成本。研究采用智能算法实现医生工作合理分配,避免过度劳累,同时缩短患者等待时间。系统提供数据分析和实时信息共享功能,增强管理透明度和决策科学性。实践层面可提升资源利用率20%以上,改善患者满意度,并为智慧医院建设奠定基础。系统包含管理员、医生和护士三大角色,分别实现排班管理、考勤统计和个人信息维护等功能,促进医疗信息化发展。

xiongbatianxia的博客 1110

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

上一篇: 【HTML】Canvas(3)-绘制图片
下一篇: 【JSP】访问WEB-INF下的JSP页面
励志故事
博客等级 码龄12年 99粉丝 110原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值