【发布时间】:2015-06-26 23:04:19
【问题描述】:
我有一群用户,有给定的开始和结束时间,例如:
{ Name = "Peter", StartTime = "10:30", EndTime = "11:00" },
{ Name = "Dana", StartTime = "11:00", EndTime = "12:30" },
{ Name = "Raymond", StartTime = "10:30", EndTime = "14:00" },
{ Name = "Egon", StartTime = "12:00", EndTime = "13:00" },
{ Name = "Winston", StartTime = "10:00", EndTime = "12:00" }
我想根据它们重叠的时间(基于可配置的阈值,例如,它们至少需要重叠半小时)将它们放入存储桶中。我希望桶最好是 4 件大,但 2-5 的任何范围都是可以接受的。
在上面的示例中,没有 4 个人匹配,所以我有 3 个(Peter、Raymond、Winston)和 2 个中的一个(Dana、Egon)。
我设计了一个算法的原型,该算法似乎依赖于机会而不是科学:
- 按开始时间排序列表
- 创建一个空桶
- 从列表中选择第一个用户
- 对照存储桶中的所有用户检查该用户
- 如果该用户与存储桶中的每个人都重叠,则将该用户放入其中并将其从列表中删除
- 如果存储桶具有理想的大小 (4),或者如果我循环并检查同一用户超过 3 次,请关闭存储桶并创建一个新的空存储桶
这对于前几个存储桶很有效,但会导致只有 2 个人的存储桶可以更好地组合。
我可以更改算法以从列表中删除所有理想存储桶并重新洗牌并尝试更多,但我觉得这应该是一个常见问题 - 这就像工人的轮班分配,或者可能是 knapsack problem。
有人知道这类问题的标准算法吗?
(标记组合,因为我认为这是它适用的数学领域,如果有错误请纠正我)
【问题讨论】:
-
您希望您的存储桶仅根据 30 分钟(阈值)重叠还是根据重叠最多的人进行排序?
-
@OrrenRavid 任何重叠都可以。我们可能会调整最小重叠时间(例如,最少 60 分钟),但重叠 60 分钟的人与重叠 180 分钟的人一样好。
-
我认为区间树会很好地工作。 en.wikipedia.org/wiki/Interval_tree
-
我做了一个区间树程序。它绝对不如算法那么干净,但它基本上是我下面的答案。
标签: c# .net algorithm combinatorics