找到唯一二进制向量数量的有效解决方案

Posted

技术标签:

【中文标题】找到唯一二进制向量数量的有效解决方案【英文标题】:Efficient solution to find the number of unique binary vectors 【发布时间】:2017-03-14 20:52:25 【问题描述】:

假设你有一个长度为 N 的二进制向量(每个元素可以是 0、1 或 X,分别对应 0 或 1)。

例如,给定 N = 4:

1001 是单个二进制向量 1XX1表示四个不同的二元向量1001, 1011, 1101, 1111

现在假设您有三种不同的描述,例如

X11X 1XX1 11XX

找到这组规范描述的唯一二进制向量的数量的有效解决方案是什么?

请注意,当 N 增长时,蛮力解决方案变得不切实际,因此列出每个可能的向量并删除重复项不是可行的解决方案。另请注意,我们只想知道唯一向量的数量,而不需要计算它们的确切值。

使用此示例的解决方案进行编辑:

X11X --> 0110 0111 1110 1111

1XX1 --> 1001 1011 1101 1111

11XX --> 1100 1101 1110 1111

在这 12 个向量中,我们只想计算唯一的,例如 8 个。

0110 0111 1110 1111 1001 1011 1101 1100

【问题讨论】:

您希望这组描述的数字是多少?您想单独计算它们,然后将它们的结果相加吗? 在上面的例子中,每个规范描述了 4 个不同的向量,所以它们总共有 12 个向量。但是它们之间会有重复。我只想计算一组规范生成的唯一向量的数量(如果我手动正确计算,它们应该是 8 个唯一向量) N 可以有多大? N 没有明确的限制,可以任意大。 "它可以像你想要的那么大" 我们在这里处理一个#P-complete 问题(比 NP 更糟糕;我们得到一个计数,而不是仅仅存在/不存在解决方案)。除非您想在文献中搜索复杂的算法,否则您应该更加具体。 【参考方案1】:

我会使用inclusion-exclusion principle。您想知道集合并集的基数。对于您的示例,您有:

N(X11X || 1XX1 || 11XX) = N(X11X) + N(1XX1) + N(11XX) - 
                          N(X11X && 1XX1) - N(X11X && 11XX) - N(1XX1 && 11XX) +
                          N(X11X && 1XX1 && 11XX)

“单个”元素的基数很容易计算(2^Nx,其中 Nx 是 X 元素的数量)。对于交集,您逐个元素进行比较。如果它们与 X 不同并且彼此不同,则为零。如果两者相等,则为 1。如果有 X 和数字,则为 1。如果你有 X 和 X 你有两个。然后你将这些数字相乘。一个例子:

N(X11X && 1XX1) = 1 * 1 * 1 * 1 = 1.

对应唯一的公共序列(1111)。这可以很容易地推广到任何 N 并且应该不难用任何语言实现。

【讨论】:

如果你有X和X,你应该有2,为什么是4? @ad3angel1s 哦,当然,你是对的,要编辑。谢谢。 只是为了确认,应用您的解决方案并将 2 用于 X 和 X,我得到了测试集的预期解决方案:12 - (1*1*1*1) - (1*1* 2*1) - (1*1*1*2) + (1*1*1*1) = 8【参考方案2】:

如果模式的数量很少,那么您可以使用包含-排除类型的方法来解决这个问题。

每个单独模式的二进制向量的数量很容易计算:它只是 2 的适当幂。现在,模式的总数只是每个单独的模式的二进制向量的总和,减去二进制的数量每对模式的公共解决方案的向量,加上每个三元组的公共解决方案数量的总和,等等。

一组模式的公共解决方案同样是单个模式的解决方案:如果在某个位置,一个模式有 0 而另一个有 1,那么就没有公共解决方案。否则,如果其中一个模式在该位置有 0 或 1,我们通过在某个位置放置 0 或 1 来获得模式,如果所有模式在该位置都有 X,则通过 X 来获得。

【讨论】:

以上是关于找到唯一二进制向量数量的有效解决方案的主要内容,如果未能解决你的问题,请参考以下文章

以二进制表示计数1的数量

R - 查找按位二进制邻居(一次翻转一位)

支持向量的数量 libsvm

计算字符串中唯一字符的数量

C++ 将单个元素移动到向量中的新位置的最简单最有效的方法

最多有多少个连续子数组。 n 个唯一编号