找到满足特定条件的子集

Posted

技术标签:

【中文标题】找到满足特定条件的子集【英文标题】:Finding a subset which satisfies a certain condition 【发布时间】:2012-01-22 08:32:32 【问题描述】:

我有几个这样的数字数组(数组的每个元素只能取0或1的值)

v1:1; 0; 0; 1个; 1个; v2:0; 1个; 0; 0; 1个; v3:1; 1个; 0; 1个; 0; v4:1; 0; 0; 1个; 0; v5:1; 1个; 0; 1个; 1个; v6:1; 1个; 0; 1个; 1个;

我希望找到这样的子集,以便在对数组求和时,生成的数组具有单独的元素,这些元素是 2 的倍数。例如,v1+v2+v3 给出的结果数组为 2、2、0、2, 2. 结果数组可以是 2 的倍数。

另一个例子:

v1:1、1、1、0、1、0 v2:0、0、1、0、0、0 v3:1、0、0、0、0、0 v4:0、0、0、1、0、0 v5:1、1、0、0、1、0 v6:0、0、1、1、0、0 v7:1、0、1、1、0、0

在本例中,v1+v2+v5 和 v3+v6+v7 是合适的答案。

我有一个蛮力解决方案,但我想检查是否有更有效的方法。这相当于子集和问题吗?

【问题讨论】:

你能详细说明一下:1.) 集合有多长 2.) 你需要结果和数组吗? 每个数组的元素个数和数组的个数在程序开始时是未知的。我实际上并不需要 sum 数组。只是数组的数量。所以如果结果是 v1+v2+v5,我需要 1、2、5。 @Banthar wow.. 高斯消除似乎是正确的做法。我只需要找到 Vx=0 的所有可能解决方案,其中 V 是我所有数组的矩阵。我想 x 会给我相应的行号。 关于 gauss-Jordan:记住 x 在每个维度上都被限制为 0/1;并且您在每个维度中再次寻找“=0 mod 2”,而不是“=0”(这与将其视为适用于 Vx 的任何规范的“=0 mod2”不同,例如。 @Neo,高斯消除对你有用吗?如果是这样,您可以将其发布为答案并接受吗? 【参考方案1】:

您想找到所有解决方案还是一个?

这可以找到一种解决方案(而且我认为可以扩展它以找到所有解决方案)。

将每个数组表示为二进制数。

所以 v1 变成 10011,v2 变成 01001 等等。

让 * 表示按位 mod 2 加法。

例如

v1*v2*v3 = 00000

所以我们的目标是找到 mod 2 加法全为零的数组。 令 u 和 v 为任意二进制数。 那么 u*v = 0 当且仅当 u = v。

例如

(v1*v2)*v3 = 0
v1*v2 = 11010 = v3.

如果 u*v = w 那么

u*v*v = w*v, so
u*0 = w*v,
u = w*v

所以我们可以从 0 开始进行反向搜索。假设最后一组数组包含 v。那么 v*T = 0,其中 T 是某个二进制数。我们有 T = 0*v。如果 T 是给定数组之一,那么我们就完成了。否则我们从 T 开始继续搜索。

这在下面正式描述。

每个状态都是一个二进制数。

设 0 为初始状态。

给定的数组是状态空间的某个子集,比如 S。

我们的目标状态是 S 中的任何元素。

令 T 为总和为 0 的数组的所需子集。

在每个状态下,让可能的动作为 * 任何不在 T 中的状态。

在每个动作之后将使用的数组放入T中。

如果 S = T 在任何非目标阶段,则无解。

现在我们可以在这个空间上运行 DFS 来寻找解决方案。

【讨论】:

以上是关于找到满足特定条件的子集的主要内容,如果未能解决你的问题,请参考以下文章

如何在Python中对满足某些条件的行进行子集[重复]

如何在条件满足之前用 N 行中的一些对条件行进行子集化,比我的代码更快?

找到一组肯定包含至少一个具有特定属性值的子集的节点

找到根据矩阵中特定列中的行之间的绝对差排序的子集

有哪些算法/优化可用于计算数组中元素的条件子集?

如何从给定数组中找到子集的最大和。 (子集不能没有大于任何两个元素之和的元素)