我正试图用numpy来解决一个超定的线性方程组。目前,我正在做这样的事情(作为一个简单的例子):
a = np.array([[1,0], [0,1], [-1,1]])
b = np.array([1,1,0])
print np.linalg.lstsq(a,b)[0]
[ 1. 1.]
这可行,但使用浮点数。有没有办法只用整数解决系统?
我尝试了一些东西print map(int, np.linalg.lstsq(a,b)[0])
[0, 1]
为了将解决方案转换为整数数组,期待[1, 1]
,但显然我错过了一些东西。有人能指出我正确的方向吗?
答案 0 :(得分:6)
您应该使用专门的整数问题求解器(请注意整数问题甚至不易解决)。 openopt
是一个包,例如应该为整数二次优化提供良好的包装,就像你正在做的那样。尝试使用线性代数根本无法直接为您提供正确的解决方案。
您的问题可以用quadratic program编写,但它是integer,因此请使用openopt
或其他模块。由于它是一个非常简单,不受约束的,也许还有其他方法。但对于初学者来说,它起初并不是一个简单的问题,而且openopt等程序已经准备就绪,可以有效地解决这类问题。
答案 1 :(得分:4)
您正在查看线性diophantine equations系统。一个快速的谷歌搜索出现 费利克斯·拉泽布尼克Systems of Linear Diophantine Equations。在该论文中,作者考虑了以下问题:
给定线性方程组Ax = b,其中A = a(i,j)是m×n矩阵 具有整数条目,并且b是具有整数分量的m×1列向量,是系统 具有整数解,即具有整数分量的n×1解向量x
答案 2 :(得分:2)
转换为int
时,元素的小数部分会被截断,因此会向下舍入。
a = np.array([[1,0], [0,1], [-1,1]])
b = np.array([1,1,0])
x = np.linalg.lstsq(a,b)[0]
结果:
>>> x
array([ 1., 1.])
>>> x[0]
0.99999999999999967
>>> x[1]
1.0000000000000002
>>> x.astype(int)
array([0, 1])
>>> map(int, x)
[0, 1]
>>> np.array([1.,1.]).astype(int) # works fine here
array([1, 1])
答案 3 :(得分:1)
我可能误解了您的问题,但我认为您只需要round
然后astype(int)
的组合?
E.g。
a = np.array([[1,0], [0,1], [-1,1]])
b = np.array([1,1,0])
x = np.linalg.lstsq(a,b)[0]
print x.round().astype(int)
答案 4 :(得分:1)
+1 to seberg,这是一个反例,说明你不应该映射:
(对不起,它是matlab风格,但你很容易pythonize)
a =
3 0
0 3
1 1
b =
2.71
11.7
0.5
x = a\b =
0.5121
3.5088
round(x) =
1
4
norm(a*round(x)-b) = 4.5193
norm(a*[0;4]-b) = 4.4367
norm(a*[1;3]-b) = 4.4299
答案 5 :(得分:1)
我的方法是先找到非整数解,然后放大到整数一
from fractions import Fraction, gcd
from functools import reduce
def lcm(a, b):
return a * b // gcd(a, b)
def common_int(*numbers):
fractions = [Fraction(n).limit_denominator() for n in numbers[0]]
multiple = reduce(lcm, [f.denominator for f in fractions])
ints = [f * multiple for f in fractions]
divisor = reduce(gcd, ints)
return [int(n / divisor) for n in ints]
sol = np.linalg.solve(np.array([[1, 2, 3], [2, 1, 0], [2, 1, 4]]), np.array([1., 1., 1.])) # system of equation
# [0.3333333, 0.3333333, 0.]
common_int(sol)
# [1., 1., 0.]
答案 6 :(得分:0)
我需要这样做并最终将由Keith Matthews编写的PHP程序(可以在http://www.numbertheory.org/php/php.html上找到)移植到Python中。我最初使用Numpy数组但遇到了整数溢出的问题,因此切换到使用任意精度数值表示的Sympy矩阵。
代码在GITHub上的https://github.com/tclose/Diophantine根据MIT许可证发布,所以请随意使用它,如果您遇到任何问题请告诉我(抱歉没有更好的文档记录)。主分支使用Sympy但您可以在'numpy'分支中访问原始的Numpy实现,这对于合理稀疏的系统似乎没有用。
如果您最终将其用于科学出版物,请引用Keith的论文(并可能添加指向GitHub回购的链接)。
答案 7 :(得分:0)
有一种名为block lanczos.的方法。这可以通过有限的字段来回答。您可以找到针对此特定问题的块lanczos解算器。