我目前正在开发一个网站,该网站将允许我大学的学生根据他们想参加的课程自动生成有效的时间表。
在网站本身工作之前,我决定解决如何有效安排课程的问题。
一些澄清:
我们大学的每门课程(我假设在其他每所大学)都包含一个或多个部分。因此,例如,微积分 I 目前有 4 个部分可用。这意味着,根据部分的数量,以及课程是否有实验室,这会极大地影响调度过程。
我们大学的课程使用学科缩写和课程代码的组合来表示。在微积分 I 的情况下:数学 1110。
CRN 是一个部分的唯一代码。
我就读的大学不是混合的,这意味着男性和女性在(几乎)不同的校区学习。我的意思几乎是校园一分为二。
datetimes 和 timeranges 字典旨在减少对 datetime.datetime.strptime() 的调用,这是一个真正的瓶颈。
我的第一次尝试包括算法不断循环,直到找到 30 个时间表。通过从输入的课程中随机选择一个部分,然后尝试从其余课程中放置部分以尝试构建有效的时间表来创建时间表。如果不是所有的课程都符合时间表,即存在冲突,则时间表被取消,循环继续。
显然,上述解决方案是有缺陷的。该算法运行时间过长,并且过于依赖随机性。
第二种算法与旧算法完全相反。首先,它使用 itertools.product() 生成所有可能的计划组合的集合。然后它遍历时间表,划掉任何无效的。为了确保分类的部分,计划组合在被验证之前会被打乱(random.shuffle())。同样,涉及到一些随机性。
经过一些优化,我能够让调度程序在 1 秒内运行,平均安排由 5 门课程组成。这很好,但是一旦您开始添加更多课程,问题就开始了。
给你一个想法,当我提供一组输入时,可能的组合数量非常大,以至于 itertools.product()不会在合理的时间内终止,并在此过程中占用 1GB 的 RAM。
显然,如果我要将此作为一项服务,我将需要一个更快、更有效的算法。在网上和 IRC 中出现了两个:动态编程和遗传算法。
动态规划不能应用于这个问题,因为如果我正确理解这个概念,它涉及将问题分解成更小的部分,单独解决这些部分,然后将这些部分的解决方案组合在一起形成一个完整的解决方案。据我所知,这不适用于这里。
至于遗传算法,我不太了解,甚至无法开始理解如何在这种情况下应用它。我也明白,对于一个非常大的问题空间,GA 会更有效,而这并不是那么大。
我有什么选择?我可以采取一种相对容易理解的方法来解决这个问题吗?还是我应该坚持我所拥有的,并希望没有多少人决定下学期选修 8 门课程?
我不是一个伟大的作家,所以对于问题中的任何含糊之处,我深表歉意。请随时要求澄清,我会尽力提供帮助。
这是完整的代码。
http://bpaste.net/show/ZY36uvAgcb1ujjUGKA1d/
注意:很抱歉使用了误导性标签(调度)。