尝试理解工作调度贪心算法

3
我有以下情况:(因为我不知道如何显示LaTeX,所以这里是截图)
我在理解这里发生了一些问题。如果我要编写程序,我可能会尝试将其结构化为某种堆,其中每个节点表示一个工人,从早期到最新,然后在其上运行Prim / Kruskal算法。我不知道我是否在正确的轨道上,但我需要充实我对这个问题的理解,以便我可以做到以下几点:
- 详细描述贪心选择 - 显示如果存在最优解,而没有进行贪心选择,则可以进行交换以符合贪心选择 - 知道如何实现贪心算法解决方案及其运行时间
那么我应该用这个想法去哪里?

你能详细描述一下这个图吗?Prim算法似乎不正确。 - Pham Trung
将文本内容翻译为中文:图像化的文本会导致问题难以搜索。虽然 [so] 不支持 LaTeX,但您可以使用 <sub></sub> 来使下标正常工作,并且您可以在这里找到您需要的两个符号。除此之外,您可以使用 <code></code>(普通行内代码格式不适用于 sub)来突出显示符号等(这样可以使问题更易读 - 相信我)。此外,您可以将该部分放在块引用中,以便轻松区分您正在询问的部分。 - Bernhard Barker
1个回答

3
这个问题与“值班表调度问题”非常相似。可以把委员会看作一组“监督员”,你想要在每个工人出现时都有一个监督员在场。在这种情况下,监督员来自与工人相同的集合。
以下是一些建模思路和整数规划公式。
时间切片思想
这听起来一开始可能不是很好的想法,但在实践中效果非常好。我们将从第一个班次的开始时间到最后一个班次的结束时间创建许多“时间点”T_i。有时候把T1、T2、T3…TN看作时间点(例如相隔五分钟)会有所帮助。对于每个Ti,至少有一个工人在上班。因此,那个时间点必须被覆盖(覆盖意味着委员会中也必须有至少一个成员在Ti时上班)。
我们只需要考虑2n个时间点:n个工人的起始和结束时间。
覆盖属性要求
对于每个时间点Ti,我们希望委员会中有一个工人在场。
设w1、w2...wn为工人,按照其开始时间si进行排序(工人w1开始最早的班次,工人wn开始最后的班次)。
引入一个新的指示变量(布尔型):
Y_i = 1 if worker i is part of the committeee
Y_i = 0 otherwise.

可视化

现在想象一个0-1矩阵,其中行是排序后的工人,列是时间瞬间...

构建时间工作矩阵(0/1)

    t1 t2 t3 t4 t5 t6 ...          tN
------------------------------------------- 
w1   1  1
w2   1  1
w3      1  1  1
w4         1  1  1  
...
...
wn                               1 1 1 1
------------------------------------------- 
Total 2 4 3 ...              ... 1 2 4 5

问题在于确保每一列至少选择1个工作人员成为委员会的一部分。总数显示每个时间点委员会候选人的数量。

基于整数规划的公式化

Objective: Minimize Sum(Y_i)

Subject to:

Y1 + Y2       >= 1 # coverage for time t1
Y1 + Y2 + Y3  >= 1 # coverage for time t2
...

更普遍地说,这些限制条件包括:
# Set Covering constraint for time T_i
Sum over all worker i's that are working at time t_i (Y_i) >= 1 

Y_i Binary for all i's

预处理

如果不进行预处理,这个整数规划问题会非常困难,最终可能会使求解器崩溃。但实际上,有许多预处理的想法可以极大地帮助。

  1. 进行任何强制分配。(如果在某个时间点只有一个工人在工作,则该工人必须在委员会中)
  2. 将其分为好的子问题。查看时间-工人矩阵。如果有美好的“矩形”,可以将其切出而不影响任何其他时间点,则这是一个完全独立的子问题。可以使求解器快得多。
  3. 相同的班次 - 如果很多工人具有完全相同的开始和结束时间,则可以简单地选择其中的任何一个(例如,按字典顺序第一个工人),并从考虑中删除所有其他工人。(在现实生活中,这会产生很大的差异。)
  4. 支配性班次:如果一个工人比其他任何工人都早开始并且工作时间更长,则“支配”工人可以留下,所有“被支配”的工人都可以从考虑中移除。
  5. 时间-工人矩阵中所有相同的行(和列)都可以合并。您只需要保留其中一个即可。(去重)

如果问题规模不是问题,您可以将其放入IP求解器(CPLEX、Excel、lp_solve等),并获得解决方案。

希望这些想法中的一些能够帮到您。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接