我正在尝试编写一个函数来解决线性系统使用高斯消除和旋转。我也不允许使用任何模块。 有人可以帮帮我吗?我不知道我做错了什么。在此先感谢:) :) :)
首先我设置了增强矩阵M,然后我进行了旋转和行操作,最后我进行了后置替换
def linearsolver(A,b):
n = len(A)
M = A
i = 0
for x in M:
x.append(b[i])
i += 1
for k in range(n):
for i in range(k,n):
if abs(M[i][k]) > abs(M[k][k]):
M[k], M[i] = M[i],M[k]
else:
pass
for j in range(k+1,n):
q = M[j][k] / M[k][k]
for m in range(k, n+1):
M[j][m] += q * M[k][m]
x = [0 for i in range(n)]
x[n] =float(M[n][n+1])/M[n][n]
for i in range (n-1,-1,-1):
z = 0
for j in range(i+1,n):
z = z + float(M[i][j])*x[j]
x[i] = float(M[i][n+1] - z)/M[i][i]
print x
答案 0 :(得分:17)
让它变得有教育意义,因为它显然是你的功课,并解释代码中的错误,不是吗?也许你可以在这个过程中学到一些东西。
假设有以下矩阵要解决:
A = [[3, 2, -4], [2, 3, 3], [5, -3, 1]]
b = [3, 15, 14]
您的初始代码:
def linearsolver(A,b):
n = len(A)
M = A
i = 0
for x in M:
x.append(b[i])
i += 1
for k in range(n):
for i in range(k,n):
if abs(M[i][k]) > abs(M[k][k]):
M[k], M[i] = M[i],M[k]
else:
pass
for j in range(k+1,n):
q = M[j][k] / M[k][k]
for m in range(k, n+1):
M[j][m] += q * M[k][m]
x = [0 for i in range(n)]
x[n] =float(M[n][n+1])/M[n][n]
for i in range (n-1,-1,-1):
z = 0
for j in range(i+1,n):
z = z + float(M[i][j])*x[j]
x[i] = float(M[i][n+1] - z)/M[i][i]
print x
首先你得到一个错误,关于索引超出范围的东西
Traceback (most recent call last):
File "solver.py", line 32, in <module>
print linearsolver([[3, 2, -4], [2, 3, 3], [5, -3, 1]], [3, 15, 14])
File "solver.py", line 24, in linearsolver
x[n] =float(M[n][n+1])/M[n][n]
IndexError: list index out of range
你如何调试这个?打印当前的计算状态:
x = [0 for i in range(n)]
print "n = ", n
print "x = ", x
for row in M:
print row
x[n] =float(M[n][n+1])/M[n][n]
您将获得输出:
n = 3
x = [0, 0, 0]
[5, -3, 1, 14]
[2, 3, 3, 15]
[3, 2, -4, 3]
Traceback (most recent call last):
File "solver.py", line 37, in <module>
print linearsolver([[3, 2, -4], [2, 3, 3], [5, -3, 1]], [3, 15, 14])
File "solver.py", line 29, in linearsolver
x[n] =float(M[n][n+1])/M[n][n]
IndexError: list index out of range
如果算错,请尝试写信至x[3]
并访问M[3][4]
和M[3][3]
。但是,python从0开始计数,这意味着最后一个元素比预期的小-1。最后一个元素是x[2]
和M[2][3]
。这可以通过对所有索引应用-1来解决:
x[n-1] =float(M[n-1][n])/M[n-1][n-1]
运行它......
n = 3
x = [0, 0, 0]
[5, -3, 1, 14]
[2, 3, 3, 15]
[3, 2, -4, 3]
Traceback (most recent call last):
File "solver.py", line 37, in <module>
print linearsolver([[3, 2, -4], [2, 3, 3], [5, -3, 1]], [3, 15, 14])
File "solver.py", line 34, in linearsolver
x[i] = float(M[i][n+1] - z)/M[i][i]
IndexError: list index out of range
该死的,另一个追溯!但是,我们正在取得进展,现在它在更高的线上!当您仔细观察时,再次使用n+1
。最初A
有n
行和n
列。由于您将b
附加到矩阵,因此有n+1
列。由于从0开始索引,最后一个元素是总列数的-1:n+1-1 = n
我们修复它并且有代码:
def linearsolver(A,b):
n = len(A)
M = A
i = 0
for x in M:
x.append(b[i])
i += 1
for k in range(n):
for i in range(k,n):
if abs(M[i][k]) > abs(M[k][k]):
M[k], M[i] = M[i],M[k]
else:
pass
for j in range(k+1,n):
q = M[j][k] / M[k][k]·
for m in range(k, n+1):
M[j][m] += q * M[k][m]
x = [0 for i in range(n)]
print "n = ", n
print "x = ", x
for row in M:
print row
x[n-1] =float(M[n-1][n])/M[n-1][n-1]
for i in range (n-1,-1,-1):·
z = 0·
for j in range(i+1,n):
z = z + float(M[i][j])*x[j]·
x[i] = float(M[i][n] - z)/M[i][i]
print x
当我们运行它时,我们得到结果!!! 1!
n = 3
x = [0, 0, 0]
[5, -3, 1, 14]
[2, 3, 3, 15]
[3, 2, -4, 3]
[6.4, 5.75, -0.75]
只需检查它是否有效:
3 * 6.4 + 2 * 5.75 - 4 * -0.75 = 33.7 (not 3)
2 * 6.4 + 3 * 5.75 + 3 * -0.75 = 27.8 (not 15)
5 * 6.4 - 3 * 5.75 + 1 * -0.75 = 14.0 (correct)
嗯......我们的矩阵没有解决,但至少我们有一行正确解决了。该算法要求最后一步具有特定格式的矩阵,其中大多数行以0开头。但是,你可以看到并非如此。让我们在计算矩阵时添加额外的打印件来显示矩阵:
def linearsolver(A,b):
n = len(A)
M = A
i = 0
for x in M:
x.append(b[i])
i += 1
for k in range(n):
print "Iteration ", k
for i in range(k,n):
if abs(M[i][k]) > abs(M[k][k]):
M[k], M[i] = M[i],M[k]
else:
pass
# Show the matrix after swapping rows
for row in M:
print row
print
for j in range(k+1,n):
q = M[j][k] / M[k][k]
for m in range(k, n+1):
M[j][m] += q * M[k][m]
# Show matrix after multiplying rows
for row in M:
print row
print
x = [0 for i in range(n)]
print "n = ", n
print "x = ", x
for row in M:
print row
x[n-1] =float(M[n-1][n])/M[n-1][n-1]
for i in range (n-1,-1,-1):
z = 0
for j in range(i+1,n):
z = z + float(M[i][j])*x[j]
x[i] = float(M[i][n] - z)/M[i][i]
print x
运行它:
Iteration 0
[5, -3, 1, 14]
[2, 3, 3, 15]
[3, 2, -4, 3]
[5, -3, 1, 14]
[2, 3, 3, 15]
[3, 2, -4, 3]
Iteration 1
[5, -3, 1, 14]
[2, 3, 3, 15]
[3, 2, -4, 3]
[5, -3, 1, 14]
[2, 3, 3, 15]
[3, 2, -4, 3]
Iteration 2
[5, -3, 1, 14]
[2, 3, 3, 15]
[3, 2, -4, 3]
[5, -3, 1, 14]
[2, 3, 3, 15]
[3, 2, -4, 3]
n = 3
x = [0, 0, 0]
[5, -3, 1, 14]
[2, 3, 3, 15]
[3, 2, -4, 3]
[6.4, 5.75, -0.75]
正如您所看到的,行乘法并没有发生!让我们检查一下状态:
for j in range(k+1,n):
q = M[j][k] / M[k][k]·
print "j=", j, "q=", q
print "M[j][k]=", M[j][k], "M[k][k]=", M[k][k]
for m in range(k, n+1):
M[j][m] += q * M[k][m]
对于迭代0,我们得到:
Iteration 0
[5, -3, 1, 14]
[2, 3, 3, 15]
[3, 2, -4, 3]
j= 1 q= 0
M[j][k]= 2 M[k][k]= 5
j= 2 q= 0
M[j][k]= 3 M[k][k]= 5
[5, -3, 1, 14]
[2, 3, 3, 15]
[3, 2, -4, 3]
等一下,q
不应该是0!它应该是0.4和0.6!发生这种情况是因为两个数字都是整数,而python提供的结果是整数而不是浮点数。要解决此问题,请将其更改为float()
:
for j in range(k+1,n):
q = float(M[j][k]) / M[k][k]·
print "j=", j, "q=", q
print "M[j][k]=", M[j][k], "M[k][k]=", M[k][k]
for m in range(k, n+1):
M[j][m] += q * M[k][m]
现在我们得到结果:
Iteration 0
[5, -3, 1, 14]
[2, 3, 3, 15]
[3, 2, -4, 3]
j= 1 q= 0.4
M[j][k]= 2 M[k][k]= 5
j= 2 q= 0.6
M[j][k]= 3 M[k][k]= 5
[5, -3, 1, 14]
[4.0, 1.7999999999999998, 3.4, 20.6]
[6.0, 0.20000000000000018, -3.4, 11.4]
虽然它有不同的输出,但我们在第一列中缺少零。为什么?代替2,有4而不是0,代替3,有6而不是0.我知道!你应该减去而不是添加乘法行:
Iteration 0
[5, -3, 1, 14]
[2, 3, 3, 15]
[3, 2, -4, 3]
j= 1 q= 0.4
M[j][k]= 2 M[k][k]= 5
j= 2 q= 0.6
M[j][k]= 3 M[k][k]= 5
[5, -3, 1, 14]
[0.0, 4.2, 2.6, 9.399999999999999]
[0.0, 3.8, -4.6, -5.4]
Iteration 1
[5, -3, 1, 14]
[0.0, 4.2, 2.6, 9.399999999999999]
[0.0, 3.8, -4.6, -5.4]
j= 2 q= 0.904761904762
M[j][k]= 3.8 M[k][k]= 4.2
[5, -3, 1, 14]
[0.0, 4.2, 2.6, 9.399999999999999]
[0.0, 0.0, -6.952380952380952, -13.904761904761903]
Iteration 2
[5, -3, 1, 14]
[0.0, 4.2, 2.6, 9.399999999999999]
[0.0, 0.0, -6.952380952380952, -13.904761904761903]
[5, -3, 1, 14]
[0.0, 4.2, 2.6, 9.399999999999999]
[0.0, 0.0, -6.952380952380952, -13.904761904761903]
n = 3
x = [0, 0, 0]
[5, -3, 1, 14]
[0.0, 4.2, 2.6, 9.399999999999999]
[0.0, 0.0, -6.952380952380952, -13.904761904761903]
[2.9999999999999996, 0.9999999999999996, 2.0]
你能在大多数行的开头看到那些0.0吗?现在让我们检查一下:
3 * 2.9999999999999996 + 2 * 0.9999999999999996 - 4 * 2.0 = 2.9999999999999964 (almost 3)
2 * 2.9999999999999996 + 3 * 0.9999999999999996 + 3 * 2.0 = 14.999999999999998 (almost 15)
5 * 2.9999999999999996 - 3 * 0.9999999999999996 + 1 * 2.0 = 14.0 (correct)
计算机存在浮动数字问题,但算法使我们找到了正确的解决方案[3,1,2]
删除帮助程序打印后,有代码:
def linearsolver(A,b):
n = len(A)
M = A
i = 0
for x in M:
x.append(b[i])
i += 1
for k in range(n):
for i in range(k,n):
if abs(M[i][k]) > abs(M[k][k]):
M[k], M[i] = M[i],M[k]
else:
pass
for j in range(k+1,n):
q = float(M[j][k]) / M[k][k]
for m in range(k, n+1):
M[j][m] -= q * M[k][m]
x = [0 for i in range(n)]
x[n-1] =float(M[n-1][n])/M[n-1][n-1]
for i in range (n-1,-1,-1):
z = 0
for j in range(i+1,n):
z = z + float(M[i][j])*x[j]
x[i] = float(M[i][n] - z)/M[i][i]
print x
要带走的东西: