查找集合中最小子集的算法

时间:2019-06-18 08:41:10

标签: algorithm

我想提取一个数据框的最小行数以覆盖某些列的所有元素。 这是示例:

enter image description here

条件: 新数据框的清单1封面(a,b,c);新数据框的清单2封面(alpha,beta,delta,gamma);新数据框的project_id封面(proj1,proj2,proj3);

解决方案:

enter image description here

我试图通过枚举解决此问题。最后,我放弃了这种方法进行大量计算。

1 个答案:

答案 0 :(得分:0)

此问题是众所周知的set cover problem的变体。
由于此问题是NP完全问题,因此,如果输入不是很小,则找到最佳解决方案(意味着最小的元素数量,在您的情况下为行,它将覆盖所有值)可能会花费大量时间。换句话说,关于输入大小(O(2^n),行n,行数或多或少),此问题的复杂度是指数级的。

但是不要失去希望,有一些方法可以让您在输入很小的情况下找到最佳解决方案,或者在输入很大的情况下找到令人满意的近似值。所谓小输入,是指行数量大约在100左右的行数。

Branch and bound:该算法或多或少是蛮力的“灵巧”方式,其运行速度比蛮力算法快得多。它可以找到一个最佳解决方案(给定足够的时间,如果输入很大,那么足够的时间可能意味着一百万年),或者可以停止并返回到目前为止找到的最佳解决方案。我不建议您采用这种方法,但是您一定要阅读它,它是一种非常有效且用途广泛的算法,必须知道。

Integer Linear Programming:恕我直言,这是解决此问题的最佳方法。 ILP允许您将程序编写为整数线性程序,然后将其馈送到ILP求解器(市场上有很多产品,无论有无免费,您都可以找到列表here)。如果您从未听说过线性编程,可以看看here进行一些解释。
这种方法有两个BIG优点:

  • 编写一个可以解决设置覆盖问题的ILP程序非常容易,如您所见here(最多十二行)。
  • ILP求解器非常非常优化,专门针对解决此类问题而编写。如果您输入的内容少于1000行,则应该找到最佳解决方案。而且,无论如何,它将找到比几乎任何程序都更好的解决方案。至少比花不到一周的时间编写一个程序更好的解决方案。

总是有可能使用贪婪算法,但是集合覆盖问题不能通过多项式时间算法来近似(这是对事实的过度简化,但是在我们的情况下,我们想解决一个问题设定封面的实例,不能证明P = NP或无法处理唯一的游戏猜想)。因此,贪婪算法的结果可能会比最佳解决方案无限差。而且,它的运行速度仅比令人难以置信的更好的ILP求解器快。