用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
用来获取此问题的确切答案。中的Matrix
类sympy
提供了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])