【多目标优化算法应用】新高考模式下遗传算法在排课问题中的应用

2023-10-17 08:40

本文主要是介绍【多目标优化算法应用】新高考模式下遗传算法在排课问题中的应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

新高考模式下遗传算法在排课问题中的应用

背景: 随着新高考改革在各个省份的推行,提出了“3+3模式”,即高中阶段的学生,不再区分文理科目,学生可以自主的从政治、历史、地理、物理、化学、生物和技术这7门课程里任选3门作为高考的考试科目。
  学校将班级分为行政班教学班两类,行政班则于传统教学模式的班级相同,教学班是为不同行政班学生上选修课程组成的临时班级。一个学生的课程由行政班课程和选修课程组成,行政班课程由其所在的行政班开设,教学班课程则需要不同的行政班学生走到特定教室上课,此种上课方式在本文中统称为“走班制”,本文重点讨论排课问题,走班制的分班策略不在这里进行讨论。

需要解决的问题:

  • 硬约束
    1. 学生上课不能冲突:即行政班与教学班课程上课时间不能重合
    2. 教师上课不能冲突:教师不能在同时段给不同的班带课
    3. 教室分配不能冲突:行政班在本班上课,主要针对教学班和特殊课程(如技术)不同班使用不能冲突,且不能超出教室容量上限。

  • 软约束
    1. 课程连堂:同一天同一个午别(上午/下午)一个班的n个相邻课安排为相同的科目
    2. 上下午不能连续上课:以老师的角度观察,每天上午最后一节课和下午第一节不能同时有课

基于二维染色体的遗传算法解决排课问题
二维实数编码

  本文遗传算法的染色体由一个二维数组表示,其行数和列数分别代表班级总数和教学课时总数,染色体C++语言定义如下:

class individual
{
public:vector<vector<int>> chromo;      //二维编码double fitness;                  //适应度double cal_fitness;               //累积适应度,用于轮盘赌int generation;                  //进化代数
}

  每个单元格(基因)构成一个课程单元,课程单元记录了年级ID、班级ID、班级类型、课程ID、教室ID、教室容量、教师ID等信息,染色体和课程单元C++语言定义如下:

struct course_elem
{int grade_id;        //年级IDint class_id;        //班级IDint class_type;      //1-教学班,2-走班int course_id;       //课程IDint teacher_id;      //老师IDint room_id;        //教室IDint capacity;        //教室容量int period_B;		 //两节连堂数int period_C;		 //三节连堂数
};

  染色体中填充为每个单元格的序号,故算法使用二维实数编码方式,这样的编码方式则可以很好的将设计应用到时间维上,将时间维划分为几个区块,如上午、下午等,可以更好的实施课程对时间段的要求,假设一天为上午5节课、下午4节课、一周5天,如下表所示。

12345674445
行政1班
行政2班
行政3班
行政N班
教学1班
教学2班
教学N班
适应度函数

f i f_i fi表示个体 i i i的硬约束条件冲突数,个体在当前排课方案中每违背一次约束条件, f i f_i fi值就加1。 g i g_i gi表示个体 i i i软约束的冲突数。对于一个可行的排课方案,硬约束条件必须得到满足,而软约束条件可以满足,也可以不满足。因此硬约束的在适应度函数中所占权重要远大于软约束的权重。则适应度函数可以表示为:
F i = f i 2 + g i , i = 1 , 2 , 3...... , p o p s i z e F_i = f_i^2 + g_i , i = 1,2,3......,popsize Fi=fi2+gi,i=1,2,3......,popsize

选择

轮盘赌,又称为比例选择方法,其基本思想是:各个个体被选中的概率与其适应度大小成正比。

  1. 计算每个个体的适应度F;
  2. 计算每个个体的遗传概率;
    P ( x i ) = f ( x i ) ∑ j = 1 N f ( x j ) P(x_i) =\frac {f(x_i)} { \sum_{j=1}^Nf(x_j)} P(xi)=j=1Nf(xj)f(xi)
  3. 计算每个个体的累积概率;
    q i = ∑ j = 1 i P ( x j ) q_i= \sum_{j=1}^iP(x_j) qi=j=1iP(xj)
  4. 在[0,1]区间内产生一个均匀分布的伪随机数r;
  5. 若r<q[1],则选择个体1,否则,选择个体k,使得:q[k-1]<r≤q[k] 成立;
  6. 重复(4)、(5)共N次。

轮盘赌的特点是,数值大的扇区,其被选中的概率大。可以实现种群中个体被选中的概率与个体适应值成正比。
在遗传操作的过程中,适应度值大的个体有较大的几率被选中,适应度低的个体则可能被淘汰。在种群的进化中,这样的选择算法保留了适应度好的接近目标解的个体。

交叉

  交叉操作采用分块小基因交叉算法,即每个班的课程单元只能在相同的班级进行交叉操作,而不能跨班(行)进行交叉。例如两个个体进行交叉时,只能个体1的1班行基因与个体2的1班行基因进行交换。这样的操作不会破坏班级对课程和课时的要求。
  为保证交换后各班的基因(课程单元)不重复,使用TSP实数编码的染色体交叉方法。下面举例说明交叉运算的过程。

  1. 任意选择一对染色体i,j作为父代的个体1和父代个体2;
  2. 生成一个随机数p,与交叉概率 进行比较,若p小于 则进行交叉操作(3),否则直接将父代1与父代2直接复制到自带种群中;
  3. 随机产生两个随机数 与 , 为该班基因编号的左边界, 为右边界。 与 中间的部分即为要交换的基因段。假设 =3, =5如下图所示。

父代个体1

2-130145-2-6-7

父代个体2

013257-2-1-46
4. 将两个个体中选出的基因段进行交换,交换后父代个体1中编号2与编号5的基因重复,父代个体2中编号为0与1的基因重复。为保证控制每个班的课程课时,必须保证每个班的基因段编号不重复,可将父代个体1与2中的未选择部分的重复基因进行交换。

父代个体1

0-132541-2-6-7

父代个体2

253017-2-146
变异

变异的过程是针对每个染色体个体内部的,为保证每个班级的既定的课程课时所以同交叉相同,变异操作限制在每个班级的基因段中。下图是变异前的染色体块,生成一个随机数p,与变异概率 p m p_m pm比较,若p< p m p_m pm则对该染色体个体进行变异操作。

变异前染色体块

24-12523202422-2-321
随机产生两个随机数 与 ,分别表示待交换染色体段的位置信息,设 =4, =8,交换结果如下图所示

变异后染色体块

24-125-220242223-321
算法流程
YES
NO
开始
输入数据
初始化课程单元
初始化个体和种群
选择
交叉
变异
gen<0
输出数据
结束
软硬约束冲突检测

代码皆为matlab伪代码

  1. 检测学生上课冲突
算法 1: 检测学生上课冲突
输入:stu(学生选课信息);stu_num:学生人数popsize:种群大小;length:个体一周的课时数;Adm_num:行政班数量;Edu_num:教学班数量;
输出:Stu_conflict:学生上课冲突数;
t←1;
while (t < popsize) dofor i=1 to stu_num do得到学生教学班班号Edu_ClassCode得到学生教学班班号Adm_ClassCodefor j=1 to Edu_num doif(教学班班号 == ClassCode) thenfor k=1 to Adm_num doif(行政班班号 == Adm_ClassCode) then判断该列对应行政班的课程单元编号是否为负if(课程单元编号 > -1)Stu_conflict++;end if;end if;k←k+1;end for;end if;j←j+1;end for;i←i+1;end for;t←t+1;
end while.
  1. 教师上课冲突
算法 2: 教师上课冲突
输入:Individual(个体信息);popsize:种群大小;length:个体一周的课时数;All_num:全部班数量;
输出:Tesc_conflict: 教师上课冲突数;
t←1;
while (t < popsize) dofor i=1 to length dofor j=1 to All_num do将所有的班级及其对应的课程ID存入新的二维矩阵record中j←j+1;end for;将每个record的重复内容进行统计并赋值给NumTesc_conflict = Tesc_conflict + Numi←i+1;end for;t←t+1;
end while.
  1. 教室使用冲突
输入:Individual(个体信息);popsize:种群大小;length:个体一周的课时数;All_num:全部班数量;
输出:Room_conflict: 教室使用冲突数;
t←1;
while (t < popsize) dofor i=1 to length dofor j=1 to All_num do将所有的班级及其对应的教室ID存入新的二维矩阵record中j←j+1;end for;将每个record的重复内容进行统计并赋值给NumRoom_conflict = Tesc_conflict + Numi←i+1;end for;t←t+1;
end while.
  1. 连堂设置冲突
算法 4: 连堂设置冲突
输入:Individual(个体信息);popsize:种群大小;Course_num:每个行政班包含的课程数量;Edu_num:教学班数量;Period_B:该课既定的二连堂数Period_C:该课既定的三连堂数
输出:Con_conflict: 连堂冲突数;
t←1;
while (t < popsize) dofor i=1 to Edu_num dofor j=1 to Course_num dotimes←1;p1←0;p2←0;period_Btimes←0;period_Ctimes←0;获取当前课程courseIDfor k=1 to length doif(course_id == courseID) thenif(times == 1)p1 = j; end if;times←times+1;elseif(times >1)p2=j;if(p2 – p1 >2)period_Btimes++;else if(p2-p1 > 2)period_Ctimes++;end if;times =1;end if;end if;k←k+1;end for;j←j+1;con_conflict +=abs(Period_B - period_Btimes)+abs(Period_B - period_Btimes);end for;i←i+1;end for;t←t+1;
end while.
  1. 上下午排课冲突
输入:Individual(个体信息);popsize:种群大小;Edu_num:教学班数量;Day_num:一周需要上课的天数;Up_num:上午需要上课数;Down_num:下午需要上课数;
输出:Uad_conflict: 上下午排课冲突数;
t←1;
while (t < popsize) dofor i=1 to Edu_num dofor j=1 to Day_num dofor k=1 to Up_num do获得上午当前的课程upcourse_id;for m=1 to Down_num do获得下午当前的课程downcourse_id;if(upcourse_id == downcourse_id) thenUad_num++;end if;m←m+1;end for;k←k+1;end for;j←j+1;end for;i←i+1;end for;t←t+1;
end while.
结果分析
  1. 二元锦标赛与轮盘赌选择对比
       二元锦标赛每次随机选择2个个体(放回的采样),从种群中随机选择2个个体,根据适应度值,选择适应度值最好的个体进入下一代种群。这使得适应值好的个体有更大的“生存机会”,而适应度差的被选中的机会很小,这样很容易产生超级个体,从而收敛速度比较快。
       轮盘赌选择利用各个个体适应度所占的比例大小决定其子孙保留的可能性,为了选择子代个体,需要进行多轮选择,每一轮产生一个[0,1]均匀随机数,将该随机数作为选择指针来确定被选个体。由于随机操作的原因,这种选择方法的选择误差也比较大,有时连适应度较高的个体也选择不上。
       本文使用了四个数据集基于遗传算法的排课问题,分别使用二元锦标赛和轮盘赌选择法进行对比,如图4.1所示,其中蓝色折线为轮盘赌选择算子,红色折线为二元锦标赛选择算子。

   可以看出二元锦标赛选择法是呈收敛趋势,轮盘赌选择算法效果较差,不呈现出收敛的趋势。其中该方法不能全局收敛的主要原因是由于存在统计误差,依据产生的随机数进行选择,有可能会出现不正确反应个体适应度的选择,可能导致适应度高的个体也被淘汰掉。
   Rudolph已经采用有限马尔可夫链理论证明了仅采用交叉、变异和选择(轮盘赌选择法)三个遗传算子的标准遗传算法(Canonical Genetic Algorithm CGA),不能收敛到全局最优值。由此需要算法需要引入一个重要的收敛策略-精英保留策略。
2. 个体精英保留策略与群体精英保留策略对比
  个体精英保留策略是将父代中适应度最好的个体,不经过变异与交叉操作直接进入子代中,替换子代中适应度最差的个体。
  群体精英保留策略是将父代种群和子代种群合并后,选择其中最优的N个(种群大小)个体构成下一代个体。下图为四个数据集基于轮盘赌选择方法采用不同的保留策略的测试结果。

  在这里插入图片描述图中蓝色折线为个体精英保留策略,红色折线为种群精英保留策略,可以看出, 种群的精英保留策略收敛速度更快,相比个体精英策略更易于收敛到全局最优

这篇关于【多目标优化算法应用】新高考模式下遗传算法在排课问题中的应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/224251

相关文章

Kotlin Map映射转换问题小结

《KotlinMap映射转换问题小结》文章介绍了Kotlin集合转换的多种方法,包括map(一对一转换)、mapIndexed(带索引)、mapNotNull(过滤null)、mapKeys/map... 目录Kotlin 集合转换:map、mapIndexed、mapNotNull、mapKeys、map

nginx中端口无权限的问题解决

《nginx中端口无权限的问题解决》当Nginx日志报错bind()to80failed(13:Permissiondenied)时,这通常是由于权限不足导致Nginx无法绑定到80端口,下面就来... 目录一、问题原因分析二、解决方案1. 以 root 权限运行 Nginx(不推荐)2. 为 Nginx

解决1093 - You can‘t specify target table报错问题及原因分析

《解决1093-Youcan‘tspecifytargettable报错问题及原因分析》MySQL1093错误因UPDATE/DELETE语句的FROM子句直接引用目标表或嵌套子查询导致,... 目录报js错原因分析具体原因解决办法方法一:使用临时表方法二:使用JOIN方法三:使用EXISTS示例总结报错原

Windows环境下解决Matplotlib中文字体显示问题的详细教程

《Windows环境下解决Matplotlib中文字体显示问题的详细教程》本文详细介绍了在Windows下解决Matplotlib中文显示问题的方法,包括安装字体、更新缓存、配置文件设置及编码調整,并... 目录引言问题分析解决方案详解1. 检查系统已安装字体2. 手动添加中文字体(以SimHei为例)步骤

Redis中Stream详解及应用小结

《Redis中Stream详解及应用小结》RedisStreams是Redis5.0引入的新功能,提供了一种类似于传统消息队列的机制,但具有更高的灵活性和可扩展性,本文给大家介绍Redis中Strea... 目录1. Redis Stream 概述2. Redis Stream 的基本操作2.1. XADD

MySQL深分页进行性能优化的常见方法

《MySQL深分页进行性能优化的常见方法》在Web应用中,分页查询是数据库操作中的常见需求,然而,在面对大型数据集时,深分页(deeppagination)却成为了性能优化的一个挑战,在本文中,我们将... 目录引言:深分页,真的只是“翻页慢”那么简单吗?一、背景介绍二、深分页的性能问题三、业务场景分析四、

Linux进程CPU绑定优化与实践过程

《Linux进程CPU绑定优化与实践过程》Linux支持进程绑定至特定CPU核心,通过sched_setaffinity系统调用和taskset工具实现,优化缓存效率与上下文切换,提升多核计算性能,适... 目录1. 多核处理器及并行计算概念1.1 多核处理器架构概述1.2 并行计算的含义及重要性1.3 并

SpringSecurity整合redission序列化问题小结(最新整理)

《SpringSecurity整合redission序列化问题小结(最新整理)》文章详解SpringSecurity整合Redisson时的序列化问题,指出需排除官方Jackson依赖,通过自定义反序... 目录1. 前言2. Redission配置2.1 RedissonProperties2.2 Red

nginx 负载均衡配置及如何解决重复登录问题

《nginx负载均衡配置及如何解决重复登录问题》文章详解Nginx源码安装与Docker部署,介绍四层/七层代理区别及负载均衡策略,通过ip_hash解决重复登录问题,对nginx负载均衡配置及如何... 目录一:源码安装:1.配置编译参数2.编译3.编译安装 二,四层代理和七层代理区别1.二者混合使用举例

JSONArray在Java中的应用操作实例

《JSONArray在Java中的应用操作实例》JSONArray是org.json库用于处理JSON数组的类,可将Java对象(Map/List)转换为JSON格式,提供增删改查等操作,适用于前后端... 目录1. jsONArray定义与功能1.1 JSONArray概念阐释1.1.1 什么是JSONA