最小化检查以在列表中查找重复

时间:2011-09-26 21:38:32

标签: algorithm math repeat

给定一个序列(d1,d2,...,dn),我想评估所有i!= j的乘积(1-Dij),其中Dij = 1,如果di = dj,则为0。

我的代码只检查了Dij

prod = 1;
for (int i=1; i<n; ++i) {
    for (int j=i; j<=n; ++j) {
        prod *= (1 - Dij);
    }
}

我知道当我得到Dij = 1时我可以停止,但我想要做的是获得Dij的最小表达来检查。这样我有一个表达式然后我可以使用差异序列并对其进行评估。所以我知道我可以i<j代替i != j。所以我想扩展这个产品并得到类似的东西n = 3:

(1 - D12) (1 - D13) (1 - D23) = 1 - D12 - D13 - D23 + D12*D13 + D12*D23 + D13*D23 - D12*D13*D23

但我能做的更多。该表达式实际上总是等于

1 - D12 - D13 - D23 + 3 * D12*D13 - D12*D13*D23

我的问题是:

  1. 为什么D12 * D13 = D12 * D23?这总是正确的(意味着d序列是什么并不重要),但我真的不明白为什么因为在我看来这意味着D13 = D23并不总是正确的(这取决于d序列) 。这是有助于使表达更小的关系。

  2. 如何找到这样的所有关系并获得最小的表达式?上面的表达是否最小?我甚至都不知道。

3 个答案:

答案 0 :(得分:3)

您正在尝试确定D是否包含任何重复项。最终,这需要您将每个条目相互比较,这只是枚举两个元​​素的所有独特组合。最终成为N*(N-1)/2。您可以通过先排序D然后搜索重复的相邻对(O(N*log(N))来做得更好,或者,假设您坚持有界的整数范围,您可以使用位向量将其减少到线性时间,或者如果你喜欢冒险,那就是基数。

答案 1 :(得分:2)

我可以为你回答1。考虑这两种情况:

案例1:D13 = D23

您可以在这里乘以D12两侧以获得D12 * D13 = D12 * D23

案例2:D13 != D23

这意味着d1 = d3 XOR d2 = d3,但不是。因此,我们知道d1 != d2。这意味着D12 = 0。因此

D12 * D13 = 0 * D13 = 0 = 0 * D23 = D12 * D23

当您认为这意味着D13 = D23时,您的逻辑问题在于您不能除以0,而D12可能是0(总是在第二次出现)案件)。


你的第二个问题很有意思,我不知道答案,但这里有一些可能有用的观察结果。

连续绘制数字1, 2, ..., n

1  2  3 ... n

给定表达式D_(i1,j1) * D_(i2,j2) * ... * D_(ik,jk),从i1 to j1i2 to j2创建一个弧,依此类推。这会将该行转换为图形(顶点是数字,边是这些弧)。

该图表的每个连接组件代表数字1, 2, ..., n的一个子集,从整体上看,它为{1, 2, ..., n} D12 * D23 = D12 * D13 --------- | | 1 -- 2 -- 3 = 1 -- 2 3 提供了set partition

事实:具有相同对应设置分区的任何两个术语都是相同的。

示例:

D12 * D13 * D23

 ---------
|         |
1 -- 2 -- 3

有时这个事实意味着程度是相同的,就像上面的情况一样,有时程度会降低,如

\prod_{i<j} ( 1 - Dij ) = \sum_{P set partition of \{1,2,...,n\}} c_P * m_P

结果是,现在您可以将产品(1 - Dij)表示为设置分区的总和:

mP = mP1 * mP2 * ... * mPk

其中单项术语由

给出
P = P1 union P2 union ... union Pk

Pi = { a < b < c < ... < z }m_Pi = Dab * Dac * ... * Daz

c_P = \prod (#P1)! (#P2)! ... (#Pn)!

最后,系数项只是

{{1}}

解决了这个问题后,我现在确定这属于http://math.stackexchange.com,而不是在这里。

答案 2 :(得分:0)

我没有按照数学计算,但是如果你知道di的大小是有限的,你不会使用散列表编码,或者甚至可能是稀疏的位数组?只需遍历列表,在对应于di值的位置填入数据结构“1” - 如果已经为1,则返回0.如果完成(n步),则返回1.应该是O (n)的