Making a Class Schedule Using a Genetic Algorithm 中的fitness函数的解析

2024-04-19 14:32

本文主要是介绍Making a Class Schedule Using a Genetic Algorithm 中的fitness函数的解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

genetic algotithm 排课

排课过程中的一些硬条件:

  • A class can be placed only in a spare classroom
  • No professor or student group can have more then one class at a time.
  • A classroom must have enough seats to accommodate all students.
  • To place a class in a classroom, the classroom must have laboratory equipment (computers, in our case) if the class requires it。

Fitness函数积分规则:

  • Each class can have 0 to 5 points
  • If a class uses a spare classroom, we increment its score.
  • If a class requires computers and it is located in the classroom with them, or it doesn't require them, we increment the score of the class.
  • If a class is located in a classroom with enough available seats, guess what, we increment its score.
  • If a professor has no other classes at the time, we increment the class's score once again.
  • The last thing that we check is if any of the student groups that attend the class has any other class at the same time, and if they don't, we increment the score of the class.
  • If a class breaks a rule at any time-space slot that it occupies, its score is not incremented for that rule.
  • The total score of a class schedule is the sum of points of all classes.
  • The fitness value is calculated as schedule_score/maximum_score, and maximum_score is number_of_classes*5.

这之间的联系可以这样:


这些限制条件关联了不同的对象,有课程对教室的要求,有学生或教授对课程的要求,有课程对课程表的要求(时间唯一性)。现在有个问题,有了这些限制条件,问题的解空间该怎么定义?怎么初始化一个初代的课程表?这分为两个步骤,一个是课程已经安排好了(一个课程指的是,确定好了上什么课,哪个老师上,哪些班级的学生去上,教室选在哪里),这时候上课的时间是不定的,也就是只有时间安排这一个变量,这时候把安排好的课程输入排课系统里进行优化排序。怎么安排课程呢?也就是统筹学生,老师,地点这些信息。上面这种思考方式有点偏离问题,教室和一周的时间都是可配置资源,应该是一起安排的,并不是先安排教室,然后在安排时间。

按照上面的资源分配来看,教师也可以看做一种分配资源,不过因为教师一般只教授一门课或者两门课,变化比较小,所以很多课表设计时,把这个部分是定死了。问题有点远了,后续在思考这部分问题,先解析下C++中的fitness源码。

Fitness源码部分c++

// Calculates fitness value of chromosome
void Schedule::CalculateFitness()
{// chromosome's scoreint score = 0;int numberOfRooms = Configuration::GetInstance().GetNumberOfRooms();int daySize = DAY_HOURS * numberOfRooms;int ci = 0;// check criterias and calculate scores for each class in schedulefor( hash_map<CourseClass*, int>::const_iterator it = _classes.begin(); it != _classes.end(); ++it, ci += 5 ){// coordinate of time-space slotint p = ( *it ).second;int day = p / daySize;int time = p % daySize;int room = time / DAY_HOURS;time = time % DAY_HOURS;int dur = ( *it ).first->GetDuration();// check for room overlapping of classesbool ro = false;for( int i = dur - 1; i >= 0; i-- ){if( _slots[ p + i ].size() > 1 ){ro = true;break;}}// on room overlapingif( !ro )score++;_criteria[ ci + 0 ] = !ro;CourseClass* cc = ( *it ).first;Room* r = Configuration::GetInstance().GetRoomById( room );// does current room have enough seats_criteria[ ci + 1 ] = r->GetNumberOfSeats() >= cc->GetNumberOfSeats();if( _criteria[ ci + 1 ] )score++;// does current room have computers if they are required_criteria[ ci + 2 ] = !cc->IsLabRequired() || ( cc->IsLabRequired() && r->IsLab() );if( _criteria[ ci + 2 ] )score++;bool po = false, go = false;// check overlapping of classes for professors and student groupsfor( int i = numberOfRooms, t = day * daySize + time; i > 0; i--, t += DAY_HOURS ){// for each hour of classfor( int i = dur - 1; i >= 0; i-- ){// check for overlapping with other classes at same timeconst list<CourseClass*>& cl = _slots[ t + i ];for( list<CourseClass*>::const_iterator it = cl.begin(); it != cl.end(); it++ ){if( cc != *it ){// professor overlaps?if( !po && cc->ProfessorOverlaps( **it ) )po = true;// student group overlaps?if( !go && cc->GroupsOverlap( **it ) )go = true;// both type of overlapping? no need to check moreif( po && go )goto total_overlap;}}}}total_overlap:// professors have no overlaping classes?if( !po )score++;_criteria[ ci + 3 ] = !po;// student groups has no overlaping classes?if( !go )score++;_criteria[ ci + 4 ] = !go;}// calculate fitess value based on score_fitness = (float)score / ( Configuration::GetInstance().GetNumberOfCourseClasses() * DAYS_NUM );
}


这篇关于Making a Class Schedule Using a Genetic Algorithm 中的fitness函数的解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

线上Java OOM问题定位与解决方案超详细解析

《线上JavaOOM问题定位与解决方案超详细解析》OOM是JVM抛出的错误,表示内存分配失败,:本文主要介绍线上JavaOOM问题定位与解决方案的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一、OOM问题核心认知1.1 OOM定义与技术定位1.2 OOM常见类型及技术特征二、OOM问题定位工具

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

深度解析Java @Serial 注解及常见错误案例

《深度解析Java@Serial注解及常见错误案例》Java14引入@Serial注解,用于编译时校验序列化成员,替代传统方式解决运行时错误,适用于Serializable类的方法/字段,需注意签... 目录Java @Serial 注解深度解析1. 注解本质2. 核心作用(1) 主要用途(2) 适用位置3

Java MCP 的鉴权深度解析

《JavaMCP的鉴权深度解析》文章介绍JavaMCP鉴权的实现方式,指出客户端可通过queryString、header或env传递鉴权信息,服务器端支持工具单独鉴权、过滤器集中鉴权及启动时鉴权... 目录一、MCP Client 侧(负责传递,比较简单)(1)常见的 mcpServers json 配置

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

Maven中生命周期深度解析与实战指南

《Maven中生命周期深度解析与实战指南》这篇文章主要为大家详细介绍了Maven生命周期实战指南,包含核心概念、阶段详解、SpringBoot特化场景及企业级实践建议,希望对大家有一定的帮助... 目录一、Maven 生命周期哲学二、default生命周期核心阶段详解(高频使用)三、clean生命周期核心阶

GO语言中函数命名返回值的使用

《GO语言中函数命名返回值的使用》在Go语言中,函数可以为其返回值指定名称,这被称为命名返回值或命名返回参数,这种特性可以使代码更清晰,特别是在返回多个值时,感兴趣的可以了解一下... 目录基本语法函数命名返回特点代码示例命名特点基本语法func functionName(parameters) (nam

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

Python Counter 函数使用案例

《PythonCounter函数使用案例》Counter是collections模块中的一个类,专门用于对可迭代对象中的元素进行计数,接下来通过本文给大家介绍PythonCounter函数使用案例... 目录一、Counter函数概述二、基本使用案例(一)列表元素计数(二)字符串字符计数(三)元组计数三、C