【问题标题】:Algorithm to select sets with shared elements选择具有共享元素的集合的算法
【发布时间】:2016-02-24 00:40:03
【问题描述】:

我有一个二维数组。我需要从每一列中选择一个最佳集合。

最优集合是这样的,即所有这些最优集合中唯一项目的数量最少。

我正在使用 python,但我认为这应该与语言无关。

我当前的方法非常原始,搜索所有可能的选项,这会创建一个非常大的搜索空间。 (10^15 的顺序)

我正在寻找一种不那么天真的方式来查看数据,并减少搜索空间。

在下面的代码中,我知道我可以改进性能,但我对改进算法更感兴趣。

for comb in itertools.product(*value_options):
    comb_length = len(set(itertools.chain(*comb)))
    if comb_length < best_count:
        best = comb
        best_count = comb_length

关于数据的更多信息,集合很小,目前它们是两个值但我希望能够支持更多,一组集合中可以有任意数量的集合


我添加了一些测试数据。为了使文件更符合逻辑,文件中的每一行都是上面提到的列之一,每组都用括号括起来。

小套装 http://www.importsoul.net/static/testdata.csv

从这组数据我得到结果

 332000.000,348000.000
  95300.000,787000.000
  48700.000,332000.000
  31600.000,64900.000
  12700.000,64900.000
   5620.000,95300.000
  10000.000

我还有一组更大的输入数据,尚未完成运行。 http://www.importsoul.net/static/testdata-large.csv


为了方便导入,这里将测试数据作为 json 格式

【问题讨论】:

  • 这可能更适合代码审查 (codereview.stackexchange.com)
  • value_options 的样本数据会很有帮助。
  • 如果有可能发生,如果发现一个长度最小(0, 1, ?),您可以添加break 条件。
  • 集合的大小是否相等?集合中的数字是否限制在某个范围内?
  • 这听起来 NP-complete。不过,目前没有想到任何证据。

标签: python algorithm optimization set


【解决方案1】:

这个问题是NP完全的。你可以做得比现在更好,但你可以扩展的范围是有限的。

首先,您可以使用branch-and-bound 改进您的算法,以避免看到“明显”比您已经看到的解决方案更糟糕的解决方案。这个想法是跟踪迄今为止看到的最佳解决方案所涵盖的独特元素的数量,并通过一次从一列中选择集合来构建部分解决方案。如果在任何时候,您选择的集合包含比您见过的最佳解决方案更多的独特元素,您可以立即撤消最近的选择并尝试不同的选项,而无需探索所有可能的方法来构建完整的解决方案来自次优的部分解。


为了证明问题是 NP 完全的,我们为您的问题提供了从 boolean satisfiability 的多项式时间缩减。我们假设列可以有不同的长度;证明稍微有点尴尬,但仍然可以,列强制为等长。

假设我们有一个合取范式的布尔公式,例如:

(!A || B || C) && (!C || D || !E) && (A || !B || D)

我们想知道它是否可以满足。我们构建了您问题的相应实例。这个想法是使用 1 元素集合的列来强制我们为每个变量选择一个真值,看看我们是否可以选择集合,使得没有变量必须同时为真和假。

对于公式中的每个析取子句,我们构造一列强制我们选择析取的一个元素。例如,析取子句(!A || B || C) 会变成列

{!A}
{B}
{C}

迫使我们选择析取给出的选择之一。此外,我们添加了以下形式的列:

{A}  | {B}  | {C}  | {D}  | {E}
{!A} | {!B} | {!C} | {!D} | {!E}

对于每个变量,迫使我们选择变量或其否定。我们的示例公式的完整表格如下所示

{!A} | {!C} | {A}  | {A}  | {B}  | {C}  | {D}  | {E}
{B}  | {D}  | {!B} | {!A} | {!B} | {!C} | {!D} | {!E}
{C}  | {!E} | {D}

如果每列中的最优集合选择涵盖的唯一元素数量等于公式中变量的数量,则最优选择的元素为公式提供了令人满意的分配。如果集合的最优选择包含的元素多于该集合,则该公式是不可满足的。

【讨论】:

  • 我仍在尝试通过证明的方式工作,但是忽略明显错误的树部分的建议将速度提高了几个数量级,我将尝试获取代码示例整理并发布为其他偶然发现此问题的人的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-10
  • 2014-01-27
  • 1970-01-01
  • 2020-09-05
相关资源
最近更新 更多