我有点卡在这个问题上:
给出n个课程的列表,其中课程我从Si开始,到Fi结束, 找到适合课程的算法'安排在2个大厅里 每个大厅一次只能容纳一门课程。
我考虑过为每个大厅解决最佳解决方案,每次在大厅中放置最小的Fi然后移除在最小Fi之前开始的所有Si,递归保持直到课程结束。然后做最佳解决方案大厅二。 发现每个大厅的最佳解决方案并不能为两者提供最佳解决方案。
编辑:
最佳解决方案是一种适合两个大厅中大多数课程的解决方案,时间复杂度最低
例如:课程列表:
{(0,1),(0,5),(1,2),(2,3),(4,7),(5,6),(6,8)}
一个大厅应该包含:
第二个:{(0,1),(1,2),(2,3),(4,7)}
{(0,5),(5,6),(6,8)}
然而,我上面的算法开始适应第一个大厅; 当它到达
hall1 = {(0,1], (1,2], (2,3]}
courses = {(0,5], (4,7], (5,6], (6,8]}
算法选择最早的结束时间,添加(5,6]
;最佳解决方案需要(4,7)在hall1,其他三个课程在hall2。
答案 0 :(得分:1)
你的攻击很好,但是太狭隘了:你需要用所有大厅做到这一点,用最早的可用开始时间来填充,而不是在你开始另一个大厅之前完成一个大厅。
制作一个hall_list
,其中包含每个大厅的可用(开始,结束)时间以及已分配到该大厅的sched
课程。
place_class (hall_list, course_list)
start = earliest available start time of any hall
if no such time, return present solution
hall = the hall with that time
course_ok = filter course_list for classes where S(i) <= start
choose i from course_ok with the earliest F(i)
append i to hall.sched
remove i from course_list
hall.start = F(i)
place_course(hall_list, course_list)
这对您发布的示例不起作用;同样的缺陷正在等待,但它首先遇到一个碎片问题:(1,2)将是第一个进入2号厅的课程。
价值优化:
如上所述,在每次迭代时,选择每小时最高值的最早课程。 1小时课程的价值为1; 5小时课程的价值为1/5。
<强>问题:强>
这也失败了; (0,5)留待最后,到时候不合适。
最适合的改进:
选择最早开始时间的课程;如果出现平局,请选择最早的结束时间。
这适用于特定情况。实际上,如果已知存在适合所有类的解决方案,则可以在线性时间内找到解决方案。如果你遍历按开始时间排序的课程,那就更容易了。
然而,如果最佳解决方案不放置所有课程,那么这很容易失败。再添加两个类(1,2], (2,3]
,此算法将无法看到它们应该替换2号馆中的(0,5]
。
更深入的攻击
正如@Marcin已经在删除的答案中指出的那样,这个一般情况是不是一个简单的问题。要在任何情况下保证最佳解决方案,您需要深入搜索放置树。写一个递归例程来尝试所有可能性。使用动态编程:记住结果,这样就不会进行冗余计算。键入大厅的剩余开始时间(已排序)和剩余的班级列表。
你可以在预处理中做些可能有助于实际示例的事情。例如,可以将隔离的短类序列融合到具有更高值的公共分配中。在您的示例中,您将(0,1], (1,2], (2,3]
融合到(0,3]
中。 (4,7)中的结束时间阻止您(通常)使用(5, 6], (6, 8]
执行此操作。
这有助于您找到解决方案吗?