我想提取一个数据框的最小行数以覆盖某些列的所有元素。 这是示例:
条件: 新数据框的清单1封面(a,b,c);新数据框的清单2封面(alpha,beta,delta,gamma);新数据框的project_id封面(proj1,proj2,proj3);
解决方案:
我试图通过枚举解决此问题。最后,我放弃了这种方法进行大量计算。
答案 0 :(得分:0)
此问题是众所周知的set cover problem的变体。
由于此问题是NP完全问题,因此,如果输入不是很小,则找到最佳解决方案(意味着最小的元素数量,在您的情况下为行,它将覆盖所有值)可能会花费大量时间。换句话说,关于输入大小(O(2^n)
,行n
,行数或多或少),此问题的复杂度是指数级的。
但是不要失去希望,有一些方法可以让您在输入很小的情况下找到最佳解决方案,或者在输入很大的情况下找到令人满意的近似值。所谓小输入,是指行数量大约在100左右的行数。
Branch and bound:该算法或多或少是蛮力的“灵巧”方式,其运行速度比蛮力算法快得多。它可以找到一个最佳解决方案(给定足够的时间,如果输入很大,那么足够的时间可能意味着一百万年),或者可以停止并返回到目前为止找到的最佳解决方案。我不建议您采用这种方法,但是您一定要阅读它,它是一种非常有效且用途广泛的算法,必须知道。
Integer Linear Programming:恕我直言,这是解决此问题的最佳方法。 ILP允许您将程序编写为整数线性程序,然后将其馈送到ILP求解器(市场上有很多产品,无论有无免费,您都可以找到列表here)。如果您从未听说过线性编程,可以看看here进行一些解释。
这种方法有两个BIG优点:
总是有可能使用贪婪算法,但是集合覆盖问题不能通过多项式时间算法来近似(这是对事实的过度简化,但是在我们的情况下,我们想解决一个问题设定封面的实例,不能证明P = NP或无法处理唯一的游戏猜想)。因此,贪婪算法的结果可能会比最佳解决方案无限差。而且,它的运行速度仅比令人难以置信的更好的ILP求解器快。