线性方程组求解(高斯消元法、LU三角分解法)

一、实验内容

线性方程组求解(高斯消元法、LU三角分解法)_第1张图片

二、代码(python)

import numpy as np

'''
    列主元高斯消元法
    A:系数增广矩阵
    n:未知数个数
'''
def main_element_gauss(A,n):

    for i in range(0,n-1):
        if(np.max(A[i:,i])!=A[i,i]):    #如果当前系数不是最大值,则列主元
            temp_i=int(np.where(A==np.max(A[i:,i]))[0]) #temp_i为最大值所在的行索引
            A[[i,temp_i],:]=A[[temp_i,i],:] #交换
        for j in range(1,(n-i)):
            A[i+j,:]=A[i+j,:]-A[i,:]*(A[i+j,i]/A[i,i]) #消元
        print("第%d次消元系数矩阵为:\n"%(i+1),A)

    #回代得解
    X=np.zeros((n,1))
    for i in range(n-1,-1,-1):
        temp=0
        for j in range(0,n):
            temp+=A[i,j]*X[j,0]
        X[i,0]=(A[i,n]-temp)/A[i,i]
    print("方程组的解为:\n",X)

'''
    LU三角分解法
    A:系数增广矩阵
'''
def LU_break_down(A):

    #生成维度为(3,3)的矩阵,初值为0
    L=np.zeros((3,3))
    U=np.zeros((3,3))

    #根据公式得到L和U的具体值
    U[0,:]=A[0,:3]
    for i in range(3):
        L[i,i]=1.0
    L[1,0]=A[1,0]/U[0,0]
    L[2,0]=A[2,0]/U[0,0]
    U[1,1]=A[1,1]-L[1,0]*U[0,1]
    U[1,2]=A[1,2]-L[1,0]*U[0,2]
    L[2,1]=(A[2,1]-L[2,0]*U[0,1])/U[1,1]
    U[2,2]=A[2,2]-(L[2,0]*U[0,2]+L[2,1]*U[1,2])
    print("L为:\n",L)
    print("U为:\n",U)

    #将b添加到L,使之变为增广矩阵
    L=np.hstack((L,A[:,3].reshape(3,1)))

    #回代得解
    Y=np.zeros((3,1))
    for i in range(0,3):
        temp=0
        for j in range(0,3):
            temp+=L[i,j]*Y[j,0]
        Y[i,0]=(L[i,3]-temp)/L[i,i]

    #将Y添加到U,使之变为增广矩阵
    U=np.hstack((U,Y))

    #回代得解
    X=np.zeros((3,1))
    for i in range(2,-1,-1):
        temp=0
        for j in range(0,3):
            temp+=U[i,j]*X[j,0]
        X[i,0]=(U[i,3]-temp)/U[i,i]
    print("方程组的解为:\n",X)

def main():
    #输入
    n=int(input("请输入未知数个数:"))
    temp=[]
    print("请输入系数的增广矩阵:\n")
    for i in range(n):
        temp.append([float(i) for i in  input().split()])
    A=np.array(temp).reshape(n,n+1)

    #只有n=3时,有两种方法。因为LU没有支持除3元以外的解法
    if(n==3):
        #菜单选择
        print("解方程组方法:\n\t1.列主元高斯消元法\n\t2.LU三角分解法")
        choice=int(input("请选择一种:"))

        if(choice==1):
            main_element_gauss(A,n)
        else:
            LU_break_down(A)
    else:
        main_element_gauss(A,n)

if __name__=='__main__':
    main()

三、实验结果

  1. (方程组一)列主元高斯消元法:
    线性方程组求解(高斯消元法、LU三角分解法)_第2张图片
  2. (方程组一)LU三角分解法:
    线性方程组求解(高斯消元法、LU三角分解法)_第3张图片
  3. (方程组二)列主元高斯消元法:
    线性方程组求解(高斯消元法、LU三角分解法)_第4张图片
  4. (方程组二)LU三角分解法:
    线性方程组求解(高斯消元法、LU三角分解法)_第5张图片
  5. (拓展)未知数为4时:
    线性方程组求解(高斯消元法、LU三角分解法)_第6张图片

四、感悟

  • 对于高斯消元法、列主元高斯消元法、LU三角分解法有了更深的认识。
  • 对于高斯消元法我实现了通用的算法实现,但是对于LU三角分解法,由于算法实现难度太高,因此我并未能完成LU三角分解法的通用实现,而只实现了3元的解法,有些可惜。
  • 不是程序没有bug,而是没有发现好的测试用例。列主元中有几个大坑,我调了好长时间才发现的:
    • 列主元比较的是绝对值
    • 列主元是从当前行数开始比较
  • 对于python的更深层次的理解,尤其是在切片的运用以及切片的浅拷贝还有深拷贝,最后意外学会了如何合并矩阵,运用np.hstack()和np.vstack()可实现水平和竖直方向的合并,很满足。
  • 将课堂是将的理论内容用代码实现,实在有一种数不出的欣喜。

你可能感兴趣的:(Python)