我需要找一个算法来找到最佳的会面时间让我们说一个研究小组。系统包含有关一组学生及其课程表的信息。系统应该为聚会提供时间,在这里不会与任何人的班级时间表发生冲突。什么是攻击这个问题的最佳方法。我一直在寻找任何调度算法,但没有找到合适的人。
提前致谢
答案 0 :(得分:16)
有趣的问题。
这就是我要做的事情:
然后看起来像这样,例如:
Student A: 11100000111111100000
Student B: 00000011111000010001
Student C: 00000000111111110001
_______________________________+
11100022333222220002
^^^ ^^^
然后你需要通过一个跟踪当前零长度的简单循环找到数组中的所有间隙(带零的区域)。记住开始和结束索引并将其翻译回来(步骤1的反向)到时间区域。
答案 1 :(得分:5)
这是匹配问题,可以通过maximum flow algorithm
解决每个学生和学习小组是方向图上的节点并输入 每个学生都有一个流量单位作为输入,并连接到所有研究组节点。 每个研究节点组都有无限的输出容量,当网络中的流量最大时,你就有了正确的组合
另见Introduction to Algorithms(流动网络章节)
答案 2 :(得分:0)
我记得这个问题的最佳解决方案是遗传算法生成的解决方案
请参阅此链接http://www.codeproject.com/KB/recipes/GaClassSchedule.aspx
答案 3 :(得分:0)
每天24*60 = 1440
分钟。因此,您可以轻松地强制它,因为您不需要获得超过一分钟的准确度。但是我要描述一个简单的DP。
您可以创建一个布尔数组,用于存储该分组中的某个学生是否在该分钟中有一个类。你还有第二个数组。此数组存储此块中和左侧的空白数。所以你可以做的是从右到左遍历布尔数组,如果块中有一个类,你将数字设为0,否则你将它设为1加上前一分钟的数字。
但是,我觉得我的解释不足,所以这里是伪代码:
blocked = <boolean array>;
numtoleft = <array containing the counts>;
if blocked[0]:
numtoleft[0] = 0;
else:
numtoleft[0] = 1;
for i = 1 to 1440-1:
if blocked[i]:
numtoleft[i] = 0;
else:
numtoleft[i] = numtoleft[i-1];
然后,您可以通过查找'numtoleft'数组中的最大数字轻松找到最大的开放广告位,并且可以对您正在查看的时间添加限制。
编辑:
这是python中的算法:
def largestslot(blocked, startminute, endminute):
numtoleft = [0]*1440
numtoleft[startminute] = 0 if blocked[startminute] else 1
for i in xrange(startminute+1, endminute+1):
numtoleft[i] = 0 if blocked[i] else 1
ansmax = max(numtoleft[startminute:endminute+1)
ansi = numtoleft.index(ansmax)
return (ansi-ansmax, ansi)
答案 4 :(得分:0)
我将从一个非常简单的方法开始:
现在,您的列表包含所有群组成员都有其他活动的时间段。因此,您需要检查列表中的空闲时间段,并检查插槽是否足够大,以便进行所需的会议。
答案 5 :(得分:0)
每个学生都有一系列的可用时间。每个人都必须见面(意味着至少有一个小时它们都是免费的)。您只需从第一个学生开始,并将其可用时间范围与下一个学生相交,并为每个学生完成(继续缩小原始范围),您应该留下适合每个学生的范围。
答案 6 :(得分:0)
我会设置会议的持续时间和会议可以发生的有效时间范围,即从上午8:00开始或之后开始的45分钟持续时间,但不是在晚上9:30之后。然后,应该是一个简单的问题,即交叉小组成员的空闲时间并找到适合的块。你想要包含重叠的容差,即如果75%的小组能够满足那么它是可行的。
您可能还希望包含开始/结束时间的缓冲区以允许旅行等,并在搜索条件中包含这些缓冲区。我讨厌大多数会议的一件事是,他们没有考虑旅行/设置时间,而是将一个会议预定在另一个会议之上。