《数值分析》实验报告-线性方程组求解

news2024/11/24 13:31:58

文章目录

    • 1. 实验目标
    • 2. 实验内容
      • 2.1 设计界面
      • 2.2 实现解法
        • 2.2.1 高斯消元法
        • 2.2.2 克劳斯消元法
        • 2.2.3 列主元素法
      • 2.3 结果展示
    • 3. 实现过程
      • 3.1 选择并设计算法
        • 3.1.1 高斯消元法
        • 3.1.2 克劳斯消元法
        • 3.1.3 列主元素法
      • 3.2 设计 Tkinter 界面
      • 3.3 编写代码实现
      • 3.4 结果显示
    • 4. 输入
    • 5. 输出
    • 6. 实验分析
    • 7. 实验结论
    • 8. 实验截图
    • 9. 附录:矩阵求解部分源代码
  • 完整代码:

1. 实验目标

本次实验的目标是使用 Python 编程语言设计并实现一个简易的线性方程组求解器。通过此实验,我们将实现三种不同的线性方程求解方法,并通过图形界面(GUI)展示各个步骤及求解结果。通过该实验,将加深对线性代数中矩阵变换和方程组求解的理解,并提升使用 Python 进行科学计算和图形界面设计的能力。


2. 实验内容

2.1 设计界面

使用 Tkinter 实现输入方程组的图形界面,包括输入增广矩阵的行数和列数的选项,动态生成矩阵的输入框,并展示求解的结果。

2.2 实现解法

2.2.1 高斯消元法
  • 采用上三角化消元步骤并回代求解。
  • 过程公式:
    [ A[k] = A[k] - \frac{A[k][i]}{A[i][i]} A[i], \quad (k > i) ]
    以及回代:
    [ x_i = \frac{b_i - \sum_{j=i+1}^{n} A[i][j] \cdot x_j}{A[i][i]} ]
2.2.2 克劳斯消元法
  • 对矩阵每一行进行归一化处理,逐行消元。
  • 过程公式:
    [ A[i][j] = \frac{A[i][j]}{A[i][i]}, \quad (j \in [0, n]) ]
    并消元:
    [ A[k][j] = A[k][j] - A[k][i] \cdot A[i][j], \quad (k \neq i) ]
2.2.3 列主元素法
  • 每次选取列主元素进行消元。
  • 过程公式:
    [ \text{选择 } p = \max_{k \in [i, n]} |A[k][i]| ]
    交换行:
    [ A[i], A[max_row] = A[max_row], A[i] ]
    然后进行消元:
    [ A[k][j] = A[k][j] - \frac{A[k][i]}{A[i][i]} A[i], \quad (k > i) ]

2.3 结果展示

将三种方法的求解结果在界面中展示出来,并支持清空结果重新输入。


3. 实现过程

3.1 选择并设计算法

本实验选择了高斯消元法、克劳斯消元法和列主元素法来解线性方程组,均基于矩阵操作实现:

3.1.1 高斯消元法

先将矩阵通过行变换转化为上三角矩阵,然后从底至顶进行回代求解。

3.1.2 克劳斯消元法

直接对每行进行归一化,并将其它行中相应列清零,以确保仅有对角元素非零。

3.1.3 列主元素法

基于列主元素,即选取当前列的最大值作为主元,进行行交换以减小数值误差,提高稳定性。

3.2 设计 Tkinter 界面

使用 Tkinter 生成主窗口,包括行列数输入框、矩阵输入框、求解按钮及显示求解结果的区域。当用户点击求解按钮后,系统将获取用户输入的矩阵数据,调用相应算法进行计算,并显示结果。

3.3 编写代码实现

实现 gaosi(A)kelaosi(A)liezhu(A) 三个方法用于高斯消元法、克劳斯消元法和列主元素法的具体操作。为每个方法设置处理异常输入的功能,以确保程序在用户输入不合规矩阵时能够显示错误提示。

3.4 结果显示

使用 Label 在 result_frame 区域动态生成三种算法的求解结果,并以变量值的形式展示,如 x1=5.00, x2=-3.00 等


4. 输入

在界面中用户需按以下步骤输入数据:

  1. 输入增广矩阵的行数和列数,行数即方程的数量,列数为未知数的数量加1(最后一列为常数项)。
  2. 点击“确定矩阵行列数”,程序将动态生成输入框用于填写每个变量的系数及常数项。
  3. 完成输入后,点击“求解矩阵”按钮,程序将自动调用三种方法求解并展示结果。

5. 输出

程序将以标签的形式分别展示三种解法的结果。例如,给定 3 个方程和 3 个变量,显示如下:

  • 高斯消元法解:x1=5.00, x2=-3.00, x3=4.50
  • 克劳斯消元法解:x1=5.00, x2=-3.00, x3=4.50
  • 列主元素法解:x1=5.00, x2=-3.00, x3=4.50

6. 实验分析

  1. 正确性:三种方法在处理一般方程组时,均能获得一致的解。对于简单系数矩阵(如无小数或负数项),三者表现基本相同。
  2. 数值稳定性:列主元素法在数值稳定性上优于其它两种方法,适合在系数矩阵中包含较大范围数值或小数项时使用,以降低误差。
  3. 计算效率:对于同一个方程组,克劳斯消元法步骤较为复杂(逐行归一化),执行时间略长;高斯消元法则最快,尤其在变量数较多时表现突出。
  4. 界面设计:Tkinter 能够提供一个简易的输入框生成和信息展示的界面。矩阵规模较大时(超过 4×4),界面易变得拥挤,可考虑滚动条以改善体验。

7. 实验结论

本次实验通过实现线性方程组求解器,验证了不同方法在求解方程组中的表现。高斯消元法、克劳斯消元法和列主元素法均能够正确求解方程,但在精度、计算时间等方面有所不同。该实验不仅强化了对矩阵求解算法的理解,也通过 Tkinter 编程实践了 Python 的 GUI 开发。总体来说,这些算法可应对较小规模的线性方程组求解任务,为更大规模的计算建议使用专门的数值库。


8. 实验截图

十分简陋的前端()

图1 - 界面初始状态,用户输入行数和列数。
在这里插入图片描述

图2 - 用户填写完系数矩阵后点击“求解矩阵”。
在这里插入图片描述

图3 - 结果显示区域,展示三种方法的求解结果。
在这里插入图片描述


9. 附录:矩阵求解部分源代码

# 高斯消元法
def gaosi(A):
    n = len(A)
    for i in range(n):
        for k in range(i + 1, n):
            factor = A[k][i] / A[i][i]
            for j in range(i, n + 1):
                A[k][j] -= factor * A[i][j]
    x = [0] * n
    for i in range(n - 1, -1, -1):
        x[i] = A[i][n]
        for j in range(i + 1, n):
            x[i] -= A[i][j] * x[j]
        x[i] /= A[i][i]
    return x


# 克劳斯消元法
def kelaosi(A):
    n = len(A)
    for i in range(n):
        pivot = A[i][i]
        for j in range(n + 1):
            A[i][j] /= pivot
        for k in range(n):
            if k != i:
                factor = A[k][i]
                for j in range(i, n + 1):
                    A[k][j] -= factor * A[i][j]
    return [A[i][n] for i in range(n)]


# 列主元素法
def liezhu(A):
    n = len(A)
    for i in range(n):
        max_row = max(range(i, n), key=lambda k: abs(A[k][i]))
        A[i], A[max_row] = A[max_row], A[i]
        for k in range(i + 1, n):
            factor = A[k][i] / A[i][i]
            for j in range(i, n + 1):
                A[k][j] -= factor * A[i][j]
    x = [0] * n
    for i in range(n - 1, -1, -1):
        x[i] = A[i][n]
        for j in range(i + 1, n):
            x[i] -= A[i][j] * x[j]
        x[i] /= A[i][i]
    return x

完整代码:

import numpy as np
import tkinter as tk
from tkinter import messagebox

# 高斯消元法
def gaosi(A):
    n = len(A)
    for i in range(n):
        for k in range(i + 1, n):
            factor = A[k][i] / A[i][i]
            for j in range(i, n + 1):
                A[k][j] -= factor * A[i][j]
    x = [0] * n
    for i in range(n - 1, -1, -1):
        x[i] = A[i][n]
        for j in range(i + 1, n):
            x[i] -= A[i][j] * x[j]
        x[i] /= A[i][i]
    return x


# 克劳斯消元法
def kelaosi(A):
    n = len(A)
    for i in range(n):
        pivot = A[i][i]
        for j in range(n + 1):
            A[i][j] /= pivot
        for k in range(n):
            if k != i:
                factor = A[k][i]
                for j in range(i, n + 1):
                    A[k][j] -= factor * A[i][j]
    return [A[i][n] for i in range(n)]


# 列主元素法
def liezhu(A):
    n = len(A)
    for i in range(n):
        max_row = max(range(i, n), key=lambda k: abs(A[k][i]))
        A[i], A[max_row] = A[max_row], A[i]
        for k in range(i + 1, n):
            factor = A[k][i] / A[i][i]
            for j in range(i, n + 1):
                A[k][j] -= factor * A[i][j]
    x = [0] * n
    for i in range(n - 1, -1, -1):
        x[i] = A[i][n]
        for j in range(i + 1, n):
            x[i] -= A[i][j] * x[j]
        x[i] /= A[i][i]
    return x


# 主界面类
class MatrixSolverApp:
    def __init__(self, root):
        self.root = root
        self.root.title("线性方程组求解器")

        # 初始输入行数和列数
        self.label_size = tk.Label(root, text="请输入增广矩阵的行数和列数:")
        self.label_size.pack()

        self.entry_n = tk.Entry(root, width=5)
        self.entry_n.pack()
        self.entry_m = tk.Entry(root, width=5)
        self.entry_m.pack()

        self.size_button = tk.Button(root, text="确定矩阵行列数", command=self.create_matrix_entries)
        self.size_button.pack()

        # 存放系数矩阵的框架
        self.matrix_frame = tk.Frame(root)
        self.matrix_frame.pack()

        # 存放解的框架
        self.result_frame = tk.Frame(root)
        self.result_frame.pack()

    # 生成矩阵输入框
    def create_matrix_entries(self):
        try:
            # 获取行数和列数
            self.n = int(self.entry_n.get())
            self.m = int(self.entry_m.get()) - 1  # 系数和常数项分开

            # 清空以前的输入框
            for widget in self.matrix_frame.winfo_children():
                widget.destroy()

            # 生成方程输入框
            self.entries = []
            for i in range(self.n):
                row_entries = []
                for j in range(self.m + 1):
                    # 系数项
                    if j < self.m:
                        entry = tk.Entry(self.matrix_frame, width=5)
                        entry.grid(row=i, column=2 * j)
                        row_entries.append(entry)
                        label_x = tk.Label(self.matrix_frame, text=f"x{j + 1} + " if j < self.m - 1 else f"x{j + 1} = ")
                        label_x.grid(row=i, column=2 * j + 1)
                    # 常数项
                    else:
                        entry = tk.Entry(self.matrix_frame, width=5)
                        entry.grid(row=i, column=2 * j)
                        row_entries.append(entry)
                self.entries.append(row_entries)

            # 添加确认按钮
            self.solve_button = tk.Button(self.matrix_frame, text="求解矩阵", command=self.solve)
            self.solve_button.grid(row=self.n + 1, columnspan=self.m + 2)

        except ValueError:
            messagebox.showerror("错误", "请输入有效的整数行数和列数")

    # 处理并求解
    def solve(self):
        try:
            # 读取系数矩阵
            A = []
            for i in range(self.n):
                row = [float(entry.get()) for entry in self.entries[i]]
                A.append(row)

            # 复制矩阵并进行三种求解
            self.display_results(A)

        except ValueError:
            messagebox.showerror("错误", "请确保所有系数和常数项均已填写且为数字")

    # 显示解结果
    def display_results(self, A):
        # 清空以前的结果
        for widget in self.result_frame.winfo_children():
            widget.destroy()

        # 三种解法
        A1 = [row[:] for row in A]
        A2 = [row[:] for row in A]
        A3 = [row[:] for row in A]

        result_gaosi = gaosi(A1)
        result_kelaosi = kelaosi(A2)
        result_liezhu = liezhu(A3)

        # 显示结果
        tk.Label(self.result_frame, text="高斯消元法解:").pack()
        tk.Label(self.result_frame,
                 text=", ".join([f"x{i + 1}={result_gaosi[i]:.2f}" for i in range(len(result_gaosi))])).pack()

        tk.Label(self.result_frame, text="克劳斯消元法解:").pack()
        tk.Label(self.result_frame,
                 text=", ".join([f"x{i + 1}={result_kelaosi[i]:.2f}" for i in range(len(result_kelaosi))])).pack()

        tk.Label(self.result_frame, text="列主元素法解:").pack()
        tk.Label(self.result_frame,
                 text=", ".join([f"x{i + 1}={result_liezhu[i]:.2f}" for i in range(len(result_liezhu))])).pack()


if __name__ == "__main__":
    root = tk.Tk()
    app = MatrixSolverApp(root)
    root.mainloop()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2229763.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot接入星火认知大模型

文章目录 准备工作整体思路接入大模型服务端和大模型连接客户端和服务端的连接测试 准备工作 到讯飞星火大模型上根据官方的提示申请tokens 申请成功后可以获得对应的secret&#xff0c;key还有之前创建的应用的appId&#xff0c;这些就是我们要用到的信息 搭建项目 整体思…

使用OpenAI控制大模型的输出(免费)——response_format

免费第三方api-key(硅基流动)使用OpenAI格式&#xff0c;还能控制大模型的输出格式&#xff0c;不能说真香&#xff0c;只能说 真香Plus&#xff01; API-Key领取方法看这篇教程 【1024送福利】硅基流动送2000万token啦&#xff01;撒花✿✿ 附使用教程 支持十几个免费的大模…

Databend 产品月报(2024年10月)

很高兴为您带来 Databend 2024 年 10 月的最新更新、新功能和改进&#xff01;我们希望这些增强功能对您有所帮助&#xff0c;并期待您的反馈。 Databend Cloud&#xff1a;多集群的计算集群 多集群的计算集群会根据工作负载需求自动调整计算资源&#xff0c;添加或移除集群。…

多线程编程与并发控制缓存策略负载均衡数据库优化

本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明来源(注明:作者:王文峰…

硅谷甄选(8)spu

Spu模块 SPU(Standard Product Unit)&#xff1a;标准化产品单元。是商品信息聚合的最小单位&#xff0c;是一组可复用、易检索的标准化信息的集合&#xff0c;该集合描述了一个产品的特性。通俗点讲&#xff0c;属性值、特性相同的商品就可以称为一个SPU。 7.1 Spu模块的静态…

【Three.js】SpriteMaterial 加载图片泛白,和原图片不一致

解决方法 如上图所示&#xff0c;整体泛白了&#xff0c;解决方法如下&#xff0c;添加 material.map.colorSpace srgb const imgTexture new THREE.TextureLoader().load(imgSrc)const material new THREE.SpriteMaterial({ map: imgTexture, transparent: true, opacity:…

【高阶数据结构】红黑树的插入

&#x1f921;博客主页&#xff1a;醉竺 &#x1f970;本文专栏&#xff1a;《高阶数据结构》 &#x1f63b;欢迎关注&#xff1a;感谢大家的点赞评论关注&#xff0c;祝您学有所成&#xff01; ✨✨&#x1f49c;&#x1f49b;想要学习更多《高阶数据结构》点击专栏链接查看&a…

CCNA对学历有要求吗?看看你是否有资格报考

思科认证网络助理工程师CCNA作为网络工程领域的权威认证之一&#xff0c;备受年轻人的青睐。然而&#xff0c;对于部分文化水平较低的年轻人来说&#xff0c;他们可能会有一个疑问&#xff1a;CCNA认证对学历有要求吗? 一、CCNA对学历有要求吗? 没有! 针对这一问题&#…

别再盲目选购随身WiFi了!一文教你精准挑选最适合自己的随身WiFi!随身wifi哪个牌子的最好用?

市面上随身WiFi种类繁多&#xff0c;4G/5G&#xff0c;单网设备/三网设备&#xff0c;电池款/USB款/充电宝款等难以抉择。本文旨在为你提供一份详尽的随身WiFi选购指南&#xff01; 首先&#xff0c;明确需求&#xff1a;4G还是5G&#xff1f; 日常用网&#xff0c;如浏览视频…

天锐绿盾加密软件与Ping32:信息安全领域的双子星,谁将引领加密新风尚?

在信息安全这片广袤的星空中&#xff0c;有两颗璀璨的明星格外引人注目&#xff0c;它们就是天锐绿盾加密软件和Ping32。这两款加密软件各自以其卓越的性能、全面的功能和深度的安全保障&#xff0c;赢得了众多企业的青睐。那么&#xff0c;在它们之间&#xff0c;谁将引领加密…

《探索 HarmonyOS NEXT(5.0):开启构建模块化项目架构奇幻之旅 —— 构建公共能力层》

上一篇大概说了 《探索 HarmonyOS NEXT(5.0)&#xff1a;开启构建模块化项目架构奇幻之旅 —— 构建基础特性层》&#xff0c;这一篇继续开发 构建公共能力层。 公共能力层 主要针对公共能力层的各子目录将被编译成HAR包&#xff0c;而他们只能被产品定制层和基础特性层所依赖…

开源 AI 智能名片 2+1 链动模式 S2B2C 商城小程序与私域流量圈层

摘要&#xff1a;本文探讨了私域流量圈层的特点以及其在当今时代的重要性&#xff0c;分析了开源 AI 智能名片 21 链动模式 S2B2C 商城小程序源码在私域流量圈层构建中的作用&#xff0c;阐述了产品在圈层时代被标签化的现象&#xff0c;并以实例展示了如何利用该小程序源码打造…

【网络】传输层协议TCP(中)

目录 四次挥手状态变化 流量控制 PSH标记位 URG标记位 四次挥手状态变化 之前我们讲了四次挥手的具体过程以及为什么要进行四次挥手&#xff0c;下面是四次挥手的状态变化 那么我们下面可以来验证一下CLOSE_WAIT这个状态&#xff0c;这个状态出现的条件是后调用close的一方…

11款PDF阅读器深度体验分享!你选哪一款?

不管是哪个行业还是哪个职位&#xff0c;每天处理的文件中&#xff0c;PDF格式的文档占据了相当大的比例。为了提高工作效率&#xff0c;我尝试了市面上几款流行的PDF阅读器&#xff0c;下面来和大家分享我用过的11款PDF阅读软件怎么样吧。 一、福昕PDF编辑器 直达通道&#…

Gradle篇(入门到精通)

目录 一、前言 1. 项目构建历史 1.1. 传统方式 1.2. 构建工具 1.3. Gradle 2. 初始 groovy 2.1. 什么是 Groovy 2.2. Groovy 安装环境 2.3. groovy 与 Java 对比 3. groovy 特性 3.1. 基础语法 3.2. 闭包 二、gradle 实战 1. Gradle 环境搭建 1.1. 安装 gradle …

8.FreeRTOS之软件定时器

什么是定时器&#xff1f; 简单可以理解为闹钟&#xff0c;到达指定一段时间后&#xff0c;就会响铃。 STM32 芯片自带硬件定时器&#xff0c;精度较高&#xff0c;达到定时时间后会触发中断&#xff0c;也可以生成 PWM 、输入 捕获、输出比较&#xff0c;等等&#xff0c;功…

MySQL 9从入门到性能优化-系统信息函数

【图书推荐】《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;》-CSDN博客 《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;&#xff08;数据库技术丛书&#xff09;》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) MySQL9数据库技术_夏天又到了…

人脸识别算法 - 专利1分析

专利CN117576758A中说明了一种人脸识别算法的整体识别流程&#xff0c;本文将对这篇文章进行详细讲解&#xff0c;并说明有创造性的算法部分。 前置知识&#xff1a;人脸识别 人脸识别技术是一种通过计算机技术和模式识别算法来识别和验证人脸的技术。它能够用于识别人脸的身份…

Linux之nfs服务器和dns服务器

NFS服务器 NFS&#xff08;Network File System&#xff0c;网络文件系统)&#xff0c;NFS服务器可以让PC将网络中的NFS服务器共享的目录挂载到本地端的文件系统中&#xff0c;而在本地端的系统 中看来&#xff0c;那个远程主机的目录就好像是自己的一个磁盘分区一样。 注&am…

第十八章 用于大型程序的工具

18.1 异常处理 异常处理机制允许程序中独立开发的部分能够在运行时就出现的问题进行通信并做出相应的处理。异常使得问题的检测与解决过程分离开来。 18.1.1 抛出异常 当执行一个throw时&#xff0c;跟在throw后面的语句将不再被执行。相反&#xff0c;程序的控制权从throw转…