我正在努力制定一个教学时间表,每周一次教师有一定数量的学生单独教授(例如音乐课)。学生必须轮换,即不要在一周一周的同一时间进行教学(在我称之为'轮换期'的同时,课程之间允许的最小间隙)。提出最简单的形式是微不足道的:
Week 1 Week 2 Week 3 Week 4 Week 5 Week 6
10.00 Alice Edgar David Charles Bertha Alice
10.30 Bertha Alice Edgar David Charles Bertha
11.00 Charles Bertha Alice Edgar David Charles
11.30 David Charles Bertha Alice Edgar David
12.00 Edgar David Charles Bertha Alice Edgar
但我希望用户能够添加规则,例如Alice在第3周不能制作10.30或11.00等。 我从一个简单的回溯循环开始,但很快意识到可能性的数量使得这是不可行的。我不是一个非常有经验的程序员,我意识到这可能会引导我进入高级编程技术。但如果有人能就如何处理这个问题给我一些想法,我将非常感激。我当然寻求帮助,但大多数讨论似乎是为了制定整个学校时间表这一更复杂的任务。遗传编程是否需要考虑这个问题?我正在使用php构建程序作为网页。
答案 0 :(得分:0)
IF 你假设每个学生必须每周来而从不在每周的同一时间,你会非常相似规则集为Sudoku。如果是这种情况,您可能需要考虑查找用于解决该问题的一些算法,因为就解决方案探索和规则而言,它们几乎相同。
我知道数独解算器可以用于 9乘9 并在几分之一秒内解决。根据课程/周的大小,可以在不进入启发式求解器(或遗传算法等)的情况下适用技术。我建议wiki并查看回溯,精确封面或(他们称之为)暴力。
如果这没有帮助。你能澄清一下你对最终时间表的预期规则吗?比如从“默认”时间表中减少掉期的数量,或者某些这样的?另外,你是否有任何理由将其视为多周问题?问题可以减少到每周问题,几周之间没有链接/连接吗?最后,您如何表示您的例外情况?你是如何指出哪些时间对哪些学生不好?
答案 1 :(得分:0)
在算法上进行此操作可能在计算上非常昂贵,但对于少数学生(如示例中的6)可能会这样做。
对你有利的一件事(与更常见的时间表问题相比)是学生必须每周在不同时间上课的约束。这显着减少了搜索空间。我认为我说的可能排列的数量是正确的:
n! * (n - 1)!
n
是学生人数,也是生成时间表的周数。
要解决此问题,请生成所有有效时间表的集合,并在执行此操作时,根据学生指定的约束集检查每个生成的时间表。
您可能不需要存储任何这些时间表:如果您生成的时间表不会因任何约束而失败,那么就将其发布;如果是,请跳到下一个时间表。
如果您没有很多约束,此方法应该快速生成有效的时间表。在另一方面,如果有足够的约束,使一个时间表,不可能再有一个巨大的,以确保没有时间表,需要检查的数量是有效的(在6名学生有86,400检查,但这种与学生的数量急剧上升。)< / p>
根据您的要求,您使用遗传计算来解决此问题的想法可能不起作用。 GC很擅长快速找到问题的良好解决方案(并且已成功用于时间表问题),但在证明解决方案不存在方面毫无用处。
答案 2 :(得分:0)
非常感谢各方面的建议。数独链接对可能使用的方法列表非常有帮助。我想我已经找到了解决问题的方法,所以这是一种答案:
我正在使用两个简单的简单回溯循环,每个列一个,每个列一个。每次计算最受约束的列,如果无法填充列,则清除该列,然后返回上一个填充的列。每个插槽都记住了它的可能性,所以我们可以从我们离开的地方继续前进。 第一个循环寻找一个整齐的瞳孔块,如上例所示。如果此操作失败,则类似的循环允许列开始并稍后完成,如果有更多的插槽而不是瞳孔。如果这仍然不起作用,第三个循环允许列中的间隙(对老师来说不太好)。 如果有人想到目前为止看到它,它就在这里: http://www.studio-soft.co.uk/timetables/
(目前只有第一个循环活动)。
gregston