使用Django开发一个小型的调度Web应用程序,在这个应用程序中,人们被分配到某些时间与上级会面。员工被存储为模型,与表示时间范围的模型的OneToMany关系以及它们空闲的星期几。例如:
Bob: (W 9:00, 9:15), (W 9:15, 9:30), ... (W 15:00, 15:20)
Sarah: (Th 9:05, 9:20), (F 9:20, 9:30), ... (Th 16:00, 16:05)
...
Mary: (W 8:55, 9:00), (F 13:00, 13:35), ... etc
我的计划允许基本的时间表设置,雇主可以选择查看前N个可能的时间表,会议之间的差距最小,条件是他们在该周内至少与所有员工见面一次。我目前正在生成所有可能的会议排列,并过滤出会议时间重叠的时间表。有没有办法从M个可能的计划中生成前N个计划,而不是通过所有M个可能性?
澄清:我们正在努力获得任何特定日期的最小差额总和,总计为所有日子。
答案 0 :(得分:0)
我会使用像A-star之类的搜索算法来执行此操作。图中的每个节点代表一个人的可用时隙,从一个节点到另一个节点的路径意味着node_a
和node_b
在部分时间表中。
另一种解决方案是创建一个图表,其中节点是每个人的可用时间,并且如果与node_a关联的人与与node_b关联的人员不同,则从node_a到node_b存在边缘。每个节点的权重是与两个节点关联的时间之间的时间量。
创建此图表后,您可以从图表中生成minimum spanning tree的变体。该变体与MST的不同之处在于:
生成的最小生成树将代表单个计划。
要生成其他计划,请从图表中删除刚刚创建的计划中的所有边,然后从图中创建一个新的最小生成树,并删除边缘。
答案 1 :(得分:0)
一般来说,调度问题是NP难的,虽然我无法弄清楚这个问题的减少来证明这一点,但它与许多其他well-known NP-complete problems非常相似。可能有一个多项式时间解决方案,用于找到一天的最小间隙(虽然我也不知道它,但我对需要解决它多天的希望较少)。不幸的是,这是一个复杂的问题,可能没有一个非常优雅的答案。 (或者,当有人稍后发帖时,我会踢自己。)
首先,我要说如果你的数据集相当小并且你已经能够相当快地计算所有可能的时间表,你可能只想坚持使用该解决方案,因为所有其他的都是近似值,并且可能如果运行时间的常数因子很大,可能最终运行得更慢。 (这意味着它不会随着数据集的大小而增长,因此对于大型数据集来说它会相对较小。)
最简单的近似就是使用贪婪的启发式算法。它几乎肯定没有找到最佳的时间表,如果大多数时间表重叠,可能需要很长时间才能找到解决方案,并且只有少数甚至是有效的解决方案 - 但我会假设这是不是雇员时间的情况。
从任意计划开始,随机为每位员工选择一个时间段。对于每次迭代,选择一名员工并将其时间段更改为最佳时间,相对于当前计划的其余时间。重复这个过程,直到你对结果满意为止 - 当它没有足够快速地改善或者花费太长时间。您可能不想重复,直到您无法进行任何更改以改善计划,因为此过程可能会循环大多数数据。
这不是一个很好的启发式,但它应该产生一些合理的时间表,并有很大的调整空间。您可能希望始终首先尝试将重叠时间切换到其他任何时间之前,或者您可能想要尝试翻转当前有助于最大差距的员工,或者可能会删除您已经尝试过的某些插槽。您可能希望有时允许转移到不太理想的解决方案,希望您处于局部最小值并希望摆脱它 - 一些随机性也可以帮助解决这个问题。确保始终跟踪到目前为止看到的最佳解决方案。
要生成更多计划,最明显的事情就是使用不同的随机计划启动流程。或者,也许从您找到的上一个解决方案中翻转几次,然后从那里重复。
修改:这与genetic algorithms完全相关,您可能想要使用我在GA中提供的一些想法。