贪心最大流量

时间:2016-07-28 05:55:41

标签: algorithm greedy max-flow

就餐问题
几个家庭一起出去吃饭。为了增加他们的社交互动,他们想坐在桌子旁,以便同一家庭中没有两个成员在同一张桌子上。假设晚餐队有p个家庭,i家庭有a(i)个成员。另外,假设有q个表可用,j表的容量为b(j)

问题是: 我们可以坐在桌子上的最大人数是多少?

编辑: 创建图表并运行最大流量算法可以解决此问题。但如果我们有D *算法的2 * 10 ^ 3个顶点,则全局复杂度为O(10 ^ 6 * 10 ^ 6)= O(10 ^ 12)。

如果我们只是以贪婪的方式首先坐在较大的群体中。复杂度为O(10 ^ 6)。

所以我的问题是:

1)此问题中的贪婪方法是否有效?

2)解决这个问题的最佳算法是什么?

2 个答案:

答案 0 :(得分:3)

是的,贪婪地安置最大的家庭是一个正确的解决方案。我们只需要证明,在我们安排下一个最大的家庭之后,有一种方法可以正确地安置剩下的家庭。

假设一个实例是可解的。我们通过归纳证明,在贪心算法占据k个最大家族之后,存在一个解决方案。基础k = 0是显而易见的,因为要证明的假设是存在解决方案。归纳地,假设存在一个扩展贪婪的第一个k - 1家族的部分分配的解决方案。现在,贪婪通过安置k家庭来扩展其部分任务。我们编辑已知的解决方案以恢复归纳假设。

虽然我们仍然可以,但找到一张桌子T1,其中贪婪已经安置了k家庭成员,但已知的解决方案却没有。如果T1处的已知解决方案中有空格,请从贪婪没有的表中移动k家庭成员。否则,已知解决方案的家庭成员不在位于k的{​​{1}}最大家庭中。由于该家庭小于T1最大的家庭,k最大的家庭成员占据了较小的家庭没有的表k。交换这些成员。

答案 1 :(得分:2)

很容易想出这样的座位根本不可能的例子,所以这里有一个伪代码来解决问题,假设问题是可以解决的:

Sort each family i by a(i) in decreasing order
Add each table j to a max-heap with b(j) as the key

For each family i from the sorted list:
    Pop a(i) tables from max-heap
    Add one member of i to each table
    Add each table j back into the max-heap with b(j) = b(j) - 1

n = a(1) + a(2) + ... + a(p)(即总人数)

假设二进制堆用于最大堆,时间复杂度为:

  • 对家庭进行排序:O(plog(p))
  • 初始化表格的最大堆:O(qlog(q))
  • 所有弹出和推送到/来自max-heap:O(nlog(q))

给出O(plog(p) + qlog(q) + nlog(q))的总时间复杂度,其中O(nlog(q))可能占主导地位。

由于我们正在处理整数,如果我们为最大堆使用1D桶系统,c是最大b(j),那么我们最终将只使用O(n + c) (假设最大堆操作占主导地位),这可能更快。

最后,请向大卫的答案进行投票,因为证据是必需的并且非常棒。