如何找到位域的哪个子集xor到另一个位域?

时间:2010-10-04 13:04:29

标签: math

我有一个有点数学问题。我有一堆位域,想要计算它们的哪个子集,以实现某个其他位域,或者如果没有办法,则发现不存在这样的子集。

我想使用免费库而不是原始代码来实现这一点,我非常喜欢使用Python绑定的东西(使用Python的内置数学库也是可以接受的,但是我想要移植它最终到多种语言)。同样最好不要将每个位扩展到它自己的字节。

进一步澄清:我只需要一个解决方案。我的矩阵与稀疏相反。我非常有兴趣将运行时保持在绝对最小值,因此强烈建议使用算法级别的方法来反转矩阵。此外,特定的给定位域是输出的位域非常重要,因此只需找到xor到0的子集的技术就不会完全削减它。

我一般都知道高斯消除。我试图从头开始避免这样做!

交叉发布到mathoverflow,因为不清楚这个问题的正确位置是什么 - https://mathoverflow.net/questions/41036/how-to-find-which-subset-of-bitfields-xor-to-another-bitfield

4 个答案:

答案 0 :(得分:4)

从数学上讲,在F_2字段中可以将两位的XOR视为加法。

您想要在F_2字段中求解一组方程。对于具有位(a_0,a_1,... a_n),(b_0,b_1,...,b_n),(c_0,c_1,...,c_n),(r_0,r_1,...,r_n)的四个bitfiel ),你得到方程式:

x * a_0 + y * b_0 + z * c_0 = r_0
x * a_1 + y * b_1 + z * c_1 = r_1
...
x * a_n + y * b_n + z * c_n = r_n

(寻找x,y,z)。

您可以将此编程为glpk的简单整数线性问题,可能是lp_solve(但我不记得它是否合适)。这些可能会非常缓慢,因为他们正试图解决更普遍的问题。

谷歌搜索一段时间后,似乎这个page可能是寻找代码的良好开端。从描述中可以看出DixonLinBox非常合适。

无论如何,我认为在mathoverflow上提问可能会给你更准确的答案。如果您这样做,请在此处链接您的问题。

更新: Sagemath使用M4RI来解决此问题。这使(对我而言)是一个非常好的推荐。

答案 1 :(得分:3)

对于容易适合内存的小实例,这只是在F_2上求解线性系统,因此请尝试使用mod-2高斯消元法。对于非常大的稀疏实例,例如在因子分解(筛分)算法中出现的稀疏实例,请查看Wiedemann算法。

答案 2 :(得分:1)

可以将多个子集xor设置为相同的值;你喜欢找到所有子集吗?

一种可能是严厉的方法是过滤位域的幂。在哈斯克尔:

import Data.Bits

xorsTo :: Int -> [Int] -> [[Int]]
xorsTo target fields = filter xorsToTarget (powerset fields)
  where xorsToTarget f = (foldl xor 0 f) == target

powerset [] = [[]]
powerset (x:xs) = powerset xs ++ map (x:) (powerset xs)

不确定是否有办法在不生成powerset的情况下执行此操作。 (在最坏的情况下,解决方案实际上可能是整个powerset)。

答案 3 :(得分:0)

扩展liori的答案,我们有一个线性方程组(模2):

a0, b0, c0 ...| r0
a1, b1, c1 ...| r1
...           |
an, bn, cn ...| rn

高斯消元可用于解决系统问题。在模2中,添加行操作变为XOR操作。这样做比使用通用线性系统求解器要简单得多。

因此,如果a0为零,我们交换一个位置为1的行。然后在“a”位为1的任何其他行上执行XOR(使用第0行)。然后使用第1行和第b列,然后第2行col c等重复

如果在r列中得到一行非零且为子集DNE。