一、背景

线性方程组有很多种解法,可以最简单的直接代入消元计算,但是运算量较大,且过程复杂不直观。

高斯消元法目的是预处理方程组的系数矩阵,将系数矩阵变换为上三角矩阵,这样整个方程就变得清晰直观很多,即使不借助计算机,也是可以很简单的手算出结果。

原方程

高斯消元后的方程,这样最下行的方程只是一个简单的一元一次方程,倒数第二行是二元一次,依次倒着求解,整个过程变得清晰直观。(全部元素带撇“ ' ”, 是因为消元涉及大量的对换两行元素的运算,所以方程的书写顺序是在不断被改变的,只是为了保持美观和一致,仍采用下标1234n的写法)

列主元高斯消元法,是为了克服高斯消元法的”除法bug“的改进版本, 因为消元过程中用到了除法,对于计算机来说,如果一个很小的值作为分母,则其在迭代中产生的误差,在做除法后会被放大很多倍。如0.0001与0.0002的误差小,但是1/0.0001与1/0.0002的误差巨大。列主元思想,就顺应而生,在消元前,把列中最大的元素所在行放到矩阵的最上方,那么就可以让较大值做分母,从而避免了误差被除法放大的问题。


二、方法逻辑(function文件,完整代码在文末)

1.寻找一列中的最大元素,并返回其所在行数

def get_max_row_in_column(matrix_a, j):""" 获取第j列中最大元素的所在行数此方法将被反复调用,所以每次运算时,不是从整个系数矩阵a中找最大行数,而是从可能已经做过几次消元的系数矩阵a的(j, j)子矩阵(尚未进行消元操作的部分)中寻找最大行数 """max_item = abs(matrix_a[j][j])max_row = jfor i in list(range(j, matrix_a.shape[0])):if abs(matrix_a[i][j]) > abs(max_item):max_item = matrix_a[i][j]max_row = ireturn max_row

2.交换系数矩阵a的两行元素

def swap_row_in_matrix_a(matrix_a, max_row, i):""" 在系数矩阵a中交换某两行的元素 """for j in (list(range(i, matrix_a.shape[1]))):temp = matrix_a[i][j]matrix_a[i][j] = matrix_a[max_row][j]matrix_a[max_row][j] = temp

3.交换值矩阵b的两行元素

def swap_row_in_matrix_b(matrix_b, max_row, i):""" 在值矩阵b中交换某两行的元素 """temp = matrix_b[i][0]matrix_b[i][0] = matrix_b[max_row][0]matrix_b[max_row][0] = temp

4.高斯消元法主循环

def method_elimination_gauss(matrix_a, matrix_b):""" 高斯消元法主循环 """for i in list(range(0, matrix_a.shape[0])):  # 逐行处理矩阵数据max_row = get_max_row_in_column(matrix_a, i)  # 在当前系数矩阵的(i, i)子矩阵中获取第一列中最大元素所在行数,准备进行交换swap_row_in_matrix_a(matrix_a, max_row, i)  # 将最大元素所在行数交换至(i, i)子矩阵的第一行swap_row_in_matrix_b(matrix_b, max_row, i)  # 同时交换值矩阵b的元素,使方程的系数与值保持对应关系for k in list(range(i + 1, matrix_a.shape[0])):if matrix_a[i][i] != 0:  # 此时从系数矩阵的(i, i)子矩阵中获取的[i][i]元素已经是该列中绝对值最大的数,若为0,则奇异scale_factor = (-matrix_a[k][i]/matrix_a[i][i])  # 计算接下来消元需要用到的比例因子else:print('该矩阵奇异,无法求解方程组')sys.exit(0)for j in list(range(i, matrix_a.shape[1])):matrix_a[k][j] = scale_factor * matrix_a[i][j] + matrix_a[k][j]  # 消元,高斯消元法的核心之处matrix_b[k][0] = scale_factor * matrix_b[i] + matrix_b[k][0]  # 对b进行同样的”消元“

5.在上三角方程的基础上求解方程

def solve_equation(matrix_a, matrix_b):""" 求解消元后的上三角方程 """x = np.zeros((matrix_a.shape[0], 1))if matrix_a[-1][-1] != 0:x[-1] = matrix_b[-1] / matrix_a[-1][-1]else:  # 若此上三角方程的系数矩阵的最后一行最后一列元素为0,说明矩阵奇异,无数解print('该矩阵奇异,无法求解方程组')sys.exit(0)  # 强制退出for i in list(range(matrix_a.shape[0] - 2, -1, -1)):  # 从上三角方程最后一行开始解方程,倒着计算sum_a = 0for j in list(range(i + 1, matrix_a.shape[0])):sum_a += matrix_a[i][j] * x[j]x[i] = (matrix_b[i] - sum_a) / matrix_a[i][i]return x

三、最终实现(main文件,完整代码)

import numpy as np
import function as fun# 为保证程序的连续性,一下两个矩阵均采用numpy库的矩阵形式输入,而不以数组形式输入
# 方程的系数矩阵a
matrix_a = np.array([[0.4096, 0.1234, 0.3678, 0.2943],[0.2246, 0.3872, 0.4015, 0.1129],[0.3645, 0.1920, 0.3781, 0.0643],[0.1784, 0.4002, 0.2786, 0.3927]])
# 方程的值矩阵b
matrix_b = np.array([[1.1951],[1.1262],[0.9989],[1.2499]])# 输出结果
print("原系数矩阵a:")
print(matrix_a, "\n")
print("原值矩阵b:")
print(matrix_b, "\n")
fun.method_elimination_gauss(matrix_a, matrix_b)
print("消元后的系数矩阵a")
print(matrix_a, "\n")
print("消元后的值矩阵b")
print(matrix_b, "\n")
print("最终求解结果:")
print(fun.solve_equation(matrix_a, matrix_b))

测试结果:


function文件完整代码

import sys
import numpy as npdef get_max_row_in_column(matrix_a, j):""" 获取第j列中最大元素的所在行数此方法将被反复调用,所以每次运算时,不是从整个系数矩阵a中找最大行数,而是从可能已经做过几次消元的系数矩阵a的(j, j)子矩阵(尚未进行消元操作的部分)中寻找最大行数 """max_item = abs(matrix_a[j][j])max_row = jfor i in list(range(j, matrix_a.shape[0])):if abs(matrix_a[i][j]) > abs(max_item):max_item = matrix_a[i][j]max_row = ireturn max_rowdef swap_row_in_matrix_a(matrix_a, max_row, i):""" 在系数矩阵a中交换某两行的元素 """for j in (list(range(i, matrix_a.shape[1]))):temp = matrix_a[i][j]matrix_a[i][j] = matrix_a[max_row][j]matrix_a[max_row][j] = tempdef swap_row_in_matrix_b(matrix_b, max_row, i):""" 在值矩阵b中交换某两行的元素 """temp = matrix_b[i][0]matrix_b[i][0] = matrix_b[max_row][0]matrix_b[max_row][0] = tempdef method_elimination_gauss(matrix_a, matrix_b):""" 高斯消元法主循环 """for i in list(range(0, matrix_a.shape[0])):  # 逐行处理矩阵数据max_row = get_max_row_in_column(matrix_a, i)  # 在当前系数矩阵的(i, i)子矩阵中获取第一列中最大元素所在行数,准备进行交换swap_row_in_matrix_a(matrix_a, max_row, i)  # 将最大元素所在行数交换至(i, i)子矩阵的第一行swap_row_in_matrix_b(matrix_b, max_row, i)  # 同时交换值矩阵b的元素,使方程的系数与值保持对应关系for k in list(range(i + 1, matrix_a.shape[0])):if matrix_a[i][i] != 0:  # 此时从系数矩阵的(i, i)子矩阵中获取的[i][i]元素已经是该列中绝对值最大的数,若为0,则奇异scale_factor = (-matrix_a[k][i]/matrix_a[i][i])  # 计算接下来消元需要用到的比例因子else:print('该矩阵奇异,无法求解方程组')sys.exit(0)for j in list(range(i, matrix_a.shape[1])):matrix_a[k][j] = scale_factor * matrix_a[i][j] + matrix_a[k][j]  # 消元,高斯消元法的核心之处matrix_b[k][0] = scale_factor * matrix_b[i] + matrix_b[k][0]  # 对b进行同样的”消元“def solve_equation(matrix_a, matrix_b):""" 求解消元后的上三角方程 """x = np.zeros((matrix_a.shape[0], 1))if matrix_a[-1][-1] != 0:x[-1] = matrix_b[-1] / matrix_a[-1][-1]else:  # 若此上三角方程的系数矩阵的最后一行最后一列元素为0,说明矩阵奇异,无数解print('该矩阵奇异,无法求解方程组')sys.exit(0)  # 强制退出for i in list(range(matrix_a.shape[0] - 2, -1, -1)):  # 从上三角方程最后一行开始解方程,倒着计算sum_a = 0for j in list(range(i + 1, matrix_a.shape[0])):sum_a += matrix_a[i][j] * x[j]x[i] = (matrix_b[i] - sum_a) / matrix_a[i][i]return x

demo源码链接如下

github地址:https://github.com/method_elimination_gauss

gitee地址:https://gitee.com/darlingxyz/method_elimination_gauss

【Python算法】数值分析—列主元高斯消元法——附源码相关推荐

  1. 7个惊艳众人的 Python 实用项目!【附源码】

    今天分享7个学妹看见都惊呆的 Python 小项目![附源码] 建议收藏 界面应用 1.计算器 1. 案例介绍 本例利用 Python 开发一个可以进行简单的四则运算的图形化计算器,会用到 Tkint ...

  2. 教你用python制作人脸卡通画(附源码)

    教你用python制作人脸卡通画(附源码) 效果展示: 让我们开始学习之路: 原理:利用第三方人脸接口将图像人脸化 第三方接口注册地址:https://ai.minivision.cn/#/login ...

  3. SHA224和SHA256哈希算法原理及实现(附源码)

    相关文章: SHA224和SHA256哈希算法原理及实现(附源码) 国密SM3哈希算法原理及实现(附源码) SHA1哈希算法原理及实现(附源码) MD5哈希算法原理及实现(附源码) MD4哈希算法原理 ...

  4. SHA3系列(KECCAK)哈希算法原理及实现(附源码)

    相关文章: (本文持续更新中) SHA3系列(KECCAK)哈希算法原理及实现(附源码) SHA512系列哈希算法原理及实现(附源码) SHA224和SHA256哈希算法原理及实现(附源码) 国密SM ...

  5. 国密SM3密码杂凑算法原理及实现(附源码)

    相关文章: 国密SM3哈希算法原理及实现(附源码) SHA1哈希算法原理及实现(附源码) MD5哈希算法原理及实现(附源码) MD4哈希算法原理及实现(附源码) MD2哈希算法原理及实现(附源码) M ...

  6. SHA512系列哈希算法原理及实现(附源码)

    相关文章: SHA512系列哈希算法原理及实现(附源码) SHA224和SHA256哈希算法原理及实现(附源码) 国密SM3哈希算法原理及实现(附源码) SHA1哈希算法原理及实现(附源码) MD5哈 ...

  7. python蒙特卡洛模拟抢红包(附源码),可用于课堂展示(presentation)

    本博客是复现b站毕导视频中描述的模拟论证过程,先上原视频链接(强烈建议先看原视频): 我给自己发了2亿个红包,才发现先抢和后抢差距这么大https://www.bilibili.com/video/B ...

  8. 66个Python练手项目,附源码

    前言: 不管学习哪门语言都希望能做出实际的东西来,这个实际的东西当然就是项目啦,不用多说大家都知道学编程语言一定要做项目才行. 这里整理了66个Python实战项目列表,都有完整且详细的教程,你可以从 ...

  9. Python开源软件大全(内附源码)

      写个web服务,可以用python;写个服务器脚本,可以用python;写个桌面客户端,可以用python;做机器学习数据挖掘,也可以用python--用处这么多,你是不是也想看看Python开源 ...

最新文章

  1. 安全行业中的event与incident区别
  2. 阿里广告技术最新突破:全链路联动-面向最终目标的全链路一致性建模
  3. Android新手之旅(15) Win7下配置遇到的问题
  4. centos 7 快速安装nginx
  5. java 下拉列表 枚举_「Java三分钟」精准而优雅——枚举类详解
  6. oracle set autocommit,Oracle Sqlplus SET AUTOCOMMIT
  7. 隐式连接时,windows下VS(包括2005、2008等)下配置OpenCV动态库的步骤
  8. HTML头标签使用-又一次定向,refresh
  9. 微信公众号发送小程序卡片_微信公众号里怎么添加小程序-如何在微信[[公众号]]添加小程序卡片-微信关联小程序...
  10. mtkwin10驱动_联发科MTK刷机驱动(支持WIN10)驱动
  11. matlab中indo是什么意思,Matlab软件电力系统仿真应用简介
  12. Python针对Excel数据的处理(部分)
  13. C语言中TC20是什么意思,c语言tc20下载
  14. ​Copyright到底是什么意思?
  15. w ndows10还原点,Windows10系统还原点设置
  16. 全面解析流式大数据实时处理技术、平台及应用
  17. IDEA中MAVEN项目Dependency not found 问题
  18. python嵌入式怎么学_怎么自学嵌入式?
  19. 【Flink实时数仓】数据仓库项目实战 《四》日志数据分流 【DWD】
  20. 签约大项目,展示新技术,寻找新商机——全球名企挤爆第二届进博会

热门文章

  1. Linux 下安装bcompare
  2. usb 驱动安装过程中对注册表的改动
  3. date parse java_Java LocalDate parse()用法及代码示例
  4. Nginx安装配置与SpringBoot项目整合
  5. javafx 多线程赛马设计
  6. 双机调试环境搭建 windbg + virtualkd
  7. 豪威尔咨询与众多企业家共度周年庆
  8. 《Linux那些事儿之我是USB》我是U盘(12)梦开始的地方
  9. [UE][虚幻]创建默认媒体打包资源路径
  10. Radmin远程控制软件