用Python解决线性整数方程组


问题内容

我正在寻找一种方法来解决Python中的线性方程组。特别是,我正在寻找大于所有零的最小整数向量并求解给定方程。例如,我有以下等式:

在此处输入图片说明

并想解决
在此处输入图片说明

在这种情况下,求解该方程的最小整数向量为
在此处输入图片说明

但是,如何自动确定此解决方案?如果我使用scipy.optimize.nnls,喜欢

A = np.array([[1,-1,0],[0,2,-1],[2,0,-1]])
b = np.array([0,0,0])
nnls(A,b)

结果是(array([ 0., 0., 0.]), 0.0)。这也是正确的,但不是所需的解决方案…

编辑:对于某些方面的不精确,我深表歉意。如果有人对此细节感兴趣,则问题来自论文“用于数字信号处理的同步数据流程序的静态调度”,Edward A.
Lee和David G. Messerschmitt,IEEE Transactions on
Computers,第1卷。C-36,第1号,第24-35页,1987年1月。

定理2说

对于具有s个节点和拓扑矩阵A且rank(A)= s-2的连接SDF图,我们可以找到一个正整数矢量b!= 0,使得Ab = 0,其中0是零矢量。

在定理2证明之后,他们说

可能需要求解 零空间中最小的正整数向量。 为此,请减少u’中的每个有理条目,以使其分子和分母相对质数。Euclid的算法将对此起作用。


问题答案:

要找到所需的确切解决方案,numpy和scipy可能不是最佳工具。他们的算法通常在浮点中工作,并且不能保证给出 确切的 答案。

您可以sympy用来获取此问题的确切答案。中的Matrixsympy提供了nullspace()返回空空间基向量列表的方法。这是一个例子:

In [20]: from sympy import Matrix, lcm

In [21]: A = Matrix([[1, -1, 0], [0, 2, -1], [2, 0, -1]])

获取空空间中的向量。 nullspace()返回列表;此代码假定A的等级为2,因此列表的长度为1:

In [22]: v = A.nullspace()[0]

In [23]: v
Out[23]: 
Matrix([
[1/2],
[1/2],
[  1]])

在中找到值的分母的最小公倍数,v以便我们可以将结果缩放为最小整数:

In [24]: m = lcm([val.q for val in v])

In [25]: m
Out[25]: 2

x 持有整数答案:

In [26]: x = m*v

In [27]: x
Out[27]: 
Matrix([
[1],
[1],
[2]])

要将结果转换为整数的numpy数组,可以执行以下操作:

In [52]: np.array([int(val) for val in x])
Out[52]: array([1, 1, 2])