【问题标题】:Optimital algorithm for solving XOR equation systems求解异或方程组的最优算法
【发布时间】:2014-07-14 13:42:48
【问题描述】:

我正在尝试求解 XOR 方程组。例如:

A = [[1, 1, 1, 0, 0], [0, 1, 1, 1, 0], [0, 0, 1, 1, 1], [0, 1, 1, 0, 1], [0, 1, 0, 1, 1]]
s = [3, 14, 13, 5, 2]
m = 5 # len(s)
Ax = s => x = [12, 9, 6, 1, 10]

我尝试了两种方法:

  • 第一种方法是高斯消除(~2.5 秒),显示为here
  • 第二种反转模矩阵 A(模 2)然后与 A_invert 和 s 相乘的方法。 (约 7.5 秒)

能否请您告诉我有没有一种方法或 python 库可以加快速度。即使我尝试使用 gmpy2 库,但它不能减少太多。下面我描述了python代码,以便您轻松学习。

使用高斯消元法:

def SolveLinearSystem (A, B, N):
    for K in range (0, N):
        if (A[K][K] == 0):
            for i in range (K+1, N):
                if (A[i][K]!=0):
                    for L in range (0, N):
                        s = A[K][L]
                        A[K][L] = A[i][L]
                        A[i][L] = s
                    s = B[i]
                    B[i] = B[K]
                    B[K] = s
                    break
        for I in range (0, N):
            if (I!=K):
                if (A[I][K]):
                    #M = 0
                    for M in range (K, N):
                        A[I][M] = A[I][M] ^ A[K][M]
                    B[I] = B[I] ^ B[K]

SolveLinearSystem (A, s, 5)

使用反转

def identitymatrix(n):
    return [[long(x == y) for x in range(0, n)] for y in range(0, n)]

def multiply_vector_scalar (vector, scalar, q):
    kq = []
    for i in range (0, len(vector)):
        kq.append (vector[i] * scalar %q)
    return kq

def minus_vector_scalar(vector1, scalar, vector2, q):
    kq = []
    for i in range (0, len(vector1)):
        kq.append ((vector1[i] - scalar * vector2[i]) %q)
    return kq

def inversematrix(matrix, q):
    n = len(matrix)
    A =[]
    for j in range (0, n):
        temp = []
        for i in range (0, n):
            temp.append (matrix[j][i])
        A.append(temp)

    Ainv = identitymatrix(n)

    for i in range(0, n):
        factor = gmpy2.invert(A[i][i], q) #invert mod q
        A[i] = multiply_vector_scalar(A[i],factor,q)
        Ainv[i] = multiply_vector_scalar(Ainv[i],factor,q)
        for j in range(0, n):
            if (i != j):
                factor = A[j][i]
                A[j] = minus_vector_scalar(A[j], factor, A[i], q)
                Ainv[j] = minus_vector_scalar(Ainv[j], factor, Ainv[i], q)
    return Ainv

def solve_equation (A, y):
    result = []
    for i in range (0, m):
        temp = 0
        for j in range (0, m):
            temp = (temp ^ A[i][j]* y[j])
        result.append(temp)
    return result

A_invert = inversematrix(A, 2)
print solve_equation (A_invert, s)

【问题讨论】:

  • Block Lanczos 真的飞起来了。
  • 尝试使用 Pypy pypy.org
  • 布尔的 Numpy 数组将快 100 倍,很容易,尽管您应该使用向量运算而不是循环。您还可以在 scipy 中查找可能符合要求的求解器/优化器。

标签: python algorithm


【解决方案1】:

您介绍的这两种方法都可以让您进行立方数的位运算。有一些方法更快,无论是渐近还是在实践中。

第一步(这对您来说可能就足够了)是使用 32 位整数(我相信它们在 Python 中称为 numpy.int32)来存储一行的 32 个连续元素。这将在足够大的输入上将行减少速度加快近 32 倍,并且可能会显着减少在适度输入上的运行时间。

在您的特定代码中,您可以轻松地专门针对 mod-2 案例做一些事情。在您的代码中搜索%inversemodp 并处理所有这些;额外的、毫无意义的操作肯定不会帮助您的运行时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    • 1970-01-01
    • 2013-12-09
    • 2010-12-15
    • 2017-04-17
    相关资源
    最近更新 更多