我正在寻找一种算法,给定一组包含开始时间,结束时间,类型和ID的项目,它将返回一组适合的所有项目集合(没有重叠时间和所有类型在集合中表示。
S = [("8:00AM", "9:00AM", "Breakfast With Mindy", 234),
("11:40AM", "12:40PM", "Go to Gym", 219),
("12:00PM", "1:00PM", "Lunch With Steve", 079),
("12:40PM", "1:20PM", "Lunch With Steve", 189)]
Algorithm(S) => [[("8:00AM", "9:00AM", "Breakfast With Mindy", 234),
("11:40AM", "12:40PM", "Go to Gym", 219),
("12:40PM", "1:20PM", "Lunch With Steve", 189)]]
谢谢!
答案 0 :(得分:25)
答案 1 :(得分:2)
这是一个贪婪的approuch .. 我会优化你的请求abit,告诉我,如果我错了.. Algorithem应该返回非碰撞任务的MAX子集(就总长度?或活动量而言?我猜总长度)
我首先按照完成时间(第一个最小完成时间,最后一个最大值)= O(nlogn)
来排序列表Find_set(A):
G<-Empty set;
S<-A
f<-0
while S!='Empty set' do
i<-index of activity with earliest finish time(**O(1)**)
if S(i).finish_time>=f
G.insert(S(i)) \\add this to result set
f=S(i).finish_time
S.removeAt(i) \\remove the activity from the original set
od
return G
运行时分析: 初始排序:nlogn 每次迭代O(1)* n = O(n)
总O(nlogn)+ O(n)~O(nlogn)(好吧,考虑到O符号弱点代表小数字上的真实复杂性......但随着规模的增长,这是一个很好的算法)
享受。
<强>更新强>
好吧,好像我误读了帖子,你可以选择使用动态编程来缩短运行时间,{7}页第7-19页有一个解决方案。
你需要稍微调整算法,首先你应该建立表格,然后你可以很容易地得到它的所有变化。
答案 2 :(得分:1)
我会使用Interval Tree。
构建数据结构后,您可以迭代每个事件并执行交集查询。如果没有找到交叉点,则会将其添加到您的日程表中。
答案 3 :(得分:1)
是穷举搜索可能是一种选择:
使用重叠的最早任务初始化部分时间表(例如9-9.30 和9.15-9.45)
到目前为止生成的foreach部分时间表生成一个新的部分时间表列表,附加到每个部分时间表中最早的任务不重叠(在关系的情况下生成多个)
重复使用新的部分时间表
在您的情况下,初始化只会产生(8-9 breakfast)
第一次迭代后:(8-9 brekkie, 11.40-12.40 gym)
(无关系)
第二次迭代后:(8-9 brekkie, 11.40-12.40 gym, 12.40-1.20 lunch)
(再没有关系)
这是树搜索,但它很贪心。它遗漏了跳过健身房和早午餐的可能性。
答案 4 :(得分:0)
由于您正在寻找所有可能的时间表,我认为您将找到的最佳解决方案将是一个简单的详尽搜索。
我唯一可以在算法上说的是你的字符串列表的数据结构非常糟糕。
实现非常依赖于语言,所以我甚至认为伪代码没有意义,但我会尝试给出基本算法的步骤。
弹出相同类型的前n项并将其列入清单。
对于列表中的每个项目,将该项目添加到计划集。
弹出下列n个相同类型的项目。
对于在第一个项目结束后开始的每个项目,列入清单。 (如果没有,则失败)
继续直到完成。
最难的部分是确定如何构建列表/递归,以便它最优雅。