等k子集算法

时间:2010-10-05 18:22:06

标签: algorithm subset-sum

有没有人知道一个优质高效的等k子集算法算法?优选地,c或c ++可以处理100个元素向量,可能具有复杂性和时间估计

离。 9元素向量

x = {2,4,5,6,8,9,11,13,14}

我需要生成所有k = 3个不相交的子集,其中sum = 24 算法应检查是否存在k个不相交的子集,每个子​​集具有元素24的总和,并按升序列出(在子集中和子集之间)或查看解是否存在

解决方案

解决方案1:{2 8 14} {4 9 11} {5 6 13}

解决方案2:{2 9 13} {4 6 14} {5 8 11}

由于

1 个答案:

答案 0 :(得分:1)

不幸的是,约束k-subset problem is a hard problem ...如果你想生成所有这样的k子集,你别无选择,只能evaluate many possible candidates

您可以执行一些优化以减少搜索空间。

给定域x保持整数值, 给定正整数目标M, 给定子集的正整数k大小,

  1. 当x只包含正整数并给出上限M时,删除大于或等于M的x中的所有项。这些不可能是子集的一部分。
  2. 类似地,对于k> 1,给定的M和包含正整数的x,从x中删除大于M + min0 + min1 ... minK的所有项。基本上,删除所有不可能成为子集一部分的大值,因为即使选择小值,它们也会产生超过M的总和。
  3. 您还可以使用偶数/奇数排除原则来削减搜索空间。例如,k是奇数而M是偶数,你知道总和将包含三个偶数或两个奇数和一个偶数。您可以通过从x中删除可能属于总和的候选值来使用此信息来减少搜索空间。
  4. 对向量x进行排序 - 这允许您快速排除不可能包含在总和中的值。
  5. 当向量x包含负值时,许多优化(偶数/奇数排除除外)不再有用/有效。在这种情况下,您几乎不得不进行详尽的搜索。

    正如Jilles De Wit指出,如果X包含负数,您可以将X中最小值的绝对值添加到X的每个成员中。这会将所有值重新转换回正范围 - 使我上面描述的一些优化再次成为可能。但是,这要求您能够在放大的范围内准确地表示正值。实现此目的的一种方法是在内部使用更宽的类型(比如long而不是int)来执行子集选择搜索。但是,如果执行此操作,请记住在返回结果时将结果子集向下缩放相同的偏移量。