初等变换法求解线性方程组

简介: 初等变换法求解线性方程组

初等变换:通过初等行(列同理)变换把增广矩阵变为简化阶梯型矩阵的线性方程组求解算法

具体步骤:
枚举每一列,找到枚举的当前列绝对值最大数的所在行
将该行换到最上面一行(第r行)
将该行第一个数(该行第c列元素)消成1
将该行第一个元素(该行第c列元素)下面的所有非零元素消成0
重复上面的操作,直到枚举到最后一列,把矩阵消成简化阶梯型矩阵
目录

1.初等变换基本操作

2.具体函数实现

枚举每一列

找到枚举当前列绝对值最大的数的所在行 (ps:fabs函数:求绝对值函数)

将绝对值最大的所在行换到最上面一行(第r行)

将该行第一个数消成1

将该行第一个元素(该行第c列元素)下面的所有非零元素消成0

整体代码

1.初等变换基本操作

   复习:

用一个非零的数乘某一行
把其中一行的若干倍加到另一行上
交换两行的位置
在函数实现的时候无形之中会用到如上的三条操作,以下就不再证明。

2.具体函数实现
枚举每一列
for (c = 0, r = 0; c < n; c++)
找到枚举当前列绝对值最大的数的所在行 (ps:fabs函数:求绝对值函数)
int t = r;

for (int i = r + 1; i < n; i++)
    if (fabs(a[t][c]) < fabs(a[i][c]))
        t = i;

如果该列全为0,continue直接让c++(跳过这一列,开始处理下一列)

ps:由于浮点数加减乘除时候会有精度问题,所以这里认定:如果浮点数 < eps(eps是一个很小的数,其值为1e-6),就认为该浮点数的值为0

< eps 代表 == 0 ,> eps 代表 非零

if (fabs(at) < eps) continue;
将绝对值最大的所在行换到最上面一行(第r行)
for (int i = c; i <= n; i++) swap(at, ar);
将该行第一个数消成1
注意:这里需要倒着消,最后在处理第一个数 (如果先处理第一个数,后面的数就都是除1)

for (int i = n; i >= c; i--) ar /= ar;
将该行第一个元素(该行第c列元素)下面的所有非零元素消成0
for (int i = r + 1; i < n; i++)

if (fabs(a[i][c]) > eps) // 保证消的都是非零元素
    for (int j = n; j >= c; j--)
        a[i][j] -= a[i][c] * a[r][j];

最后让r++,代表这一行已经处理完了,不再参与后面的运算(非常重要)

r++;
进行完如上操作之后,该矩阵就变成了阶梯型矩阵(共有如下几种情况)

1.完美的阶梯型矩阵

例如:

最右侧一列为常数列

由最后一行可以直接得出x3 == 1

将x3往上代入就可以依次求解出x2和x1

可以将向上代入得过程等价于把矩阵化成简化阶梯型矩阵(类对角形矩阵)

此时常数列的值对应的就是x1 x2 x3的值(如图 x1 == 3 ,x2 == 1, x3 == 1)

for (int i = n - 1; i >= 0; i--)

    for (int j = i + 1; j < n; j++)
        a[i][n] -= a[i][j] * a[j][n];

此处代码非常抽象,下面用图解的方法帮助理解

从下往上消,将阶梯型矩阵消成简化阶梯型矩阵(类对角型矩阵)

由于x3的系数是1,所以1上面的2(ai)就是要乘的倍数

ai -= ai * aj

以此类推

2.不完美的阶梯型矩阵

x的取值一共有两种情况:0或非0

在讨论之前先了解一个概念:

方程个数 < 未知数的个数 -> 此方程有无穷多组解

方程个数 = 未知数的个数 -> 此方程有唯一解

矩阵化简得过程出现了等式左右不相等的情况 -> 此方程无解

若x == 0 ,最后一行相当于是一个恒等式0 == 0 ,此时方程个数 < 未知数的个数,方程有无穷多组解

若x != 0, 最后一行出现了等式左右不相等的情况,此方程无解

if (r < n)//不完美的阶梯型矩阵

{
    for (int i = r; i < n; i++)
        if (fabs(a[i][n]) > eps)
            return 2; // 无解
    return 1; // 无穷多组解
}

//r == n 的情况 往上代入把矩阵化为简化阶梯型矩阵

for (int i = n - 1; i >= 0; i--)
    for (int j = i + 1; j < n; j++)
        a[i][n] -= a[i][j] * a[j][n];
return 0;//唯一解

返回2代表无解,返回1代表无穷多组解,返回0代表唯一解

整体代码

include

include

include

using namespace std;
const int N = 110;
double aN;
int n;
const double eps = 1e-6;
int gauss()
{

int c, r;
for (c = 0, r = 0; c < n; c++)
{
    int t = r;
    for (int i = r + 1; i < n; i++)
        if (fabs(a[t][c]) < fabs(a[i][c]))
            t = i;
    if (fabs(a[t][c]) < eps) continue;
    for (int i = c; i <= n; i++)    swap(a[t][i], a[r][i]);
    for (int i = n; i >= c; i--)    a[r][i] /= a[r][c];
    for (int i = r + 1; i < n; i++)
        if (fabs(a[i][c]) > eps)
            for (int j = n; j >= c; j--)
                a[i][j] -= a[i][c] * a[r][j];
    r++;
}
if (r < n)
{
    for (int i = r; i < n; i++)
        if (fabs(a[i][n]) > eps)
            return 2; // 无解
    return 1; // 无穷多组解
}
for (int i = n - 1; i >= 0; i--)
    for (int j = i + 1; j < n; j++)
        a[i][n] -= a[i][j] * a[j][n];
return 0;

}
int main()
{

cin >> n;
for (int i = 0; i < n; i++)
    for (int j = 0; j < n + 1; j++)
        cin >> a[i][j];
int t = gauss();

if (t == 0)
{
    for (int i = 0; i < n; i++)
    {
        if (fabs(a[i][n]) < eps) a[i][n] = 0;
        printf("%.2lf\n", a[i][n]);
    }
}
else if (t == 1) puts("Infinite group solutions"); // 无穷多组解
else puts("No solution");//无解
return 0;

}

示例:

结果x1 == 1,x2 == -2,x3 == 3

相关文章
|
机器学习/深度学习
智能体DS-Agent基于案例推理,让GPT-4数据科学任务接近100%
【4月更文挑战第20天】DS-Agent是结合案例推理(CBR)和大型语言模型的新研究,旨在提升自动化数据科学任务效率。通过自动迭代管道,它能理解任务、构建模型并优化性能。在开发阶段,成功率高达100%,部署阶段平均提高36%的一次通过率,降低成本,使开源LLMs也能高效处理数据科学任务。然而,LLMs的生成问题和资源限制仍是挑战。论文链接:https://arxiv.org/pdf/2402.17453.pdf
492 4
|
NoSQL Java Redis
Springboot从2.x升级到3.x以后redis默认配置调整
Springboot从2.x升级到3.x以后redis默认配置调整
1304 0
|
Java 数据库连接 容器
常见的几种内存泄漏情况和示例
常见的几种内存泄漏情况和示例
280 0
|
9月前
|
机器学习/深度学习 C++
强化学习:实践理解Markov决策过程(MDP)(干中学系列)——手把手教你入门强化学习(三)
本博客以实践为主,带领读者巩固上期关于“Markov决策过程”的核心概念。通过构建学生马尔可夫奖励模型、计算收获值与状态价值,进一步验证贝尔曼方程。详细介绍了转移概率、奖励值及策略概率的设置,并实现了均匀随机策略下的状态价值计算与最优策略的价值评估。结合代码实例,帮助读者深入理解强化学习理论。适合初学者实践与进阶学习。
377 63
|
8月前
|
机器学习/深度学习 人工智能 编解码
重定义数字人交互!OmniTalker:阿里推出实时多模态说话头像生成框架,音视频实现唇语级同步
阿里巴巴推出的OmniTalker框架通过Thinker-Talker架构实现文本驱动的实时说话头像生成,创新性采用TMRoPE技术确保音视频同步,支持流式多模态输入处理。
2790 2
重定义数字人交互!OmniTalker:阿里推出实时多模态说话头像生成框架,音视频实现唇语级同步
|
存储 自然语言处理 Java
Elasticsearch写入优化
【10月更文挑战第3天】Elasticsearch:从写入原理谈写入优化
422 2
|
Python
用python进行视频剪辑源码
这篇文章提供了一个使用Python进行视频剪辑的源码示例,通过结合moviepy和pydub库来实现视频的区间切割和音频合并。
385 2
|
11月前
|
机器学习/深度学习 人工智能 自然语言处理
《剖析Transformer架构:自然语言处理飞跃的幕后英雄》
Transformer架构自2017年提出以来,凭借自注意力机制革新了自然语言处理(NLP)。它摒弃传统RNN的顺序处理方式,实现全局并行计算,大幅提升训练效率。通过多头自注意力机制,Transformer能精准捕捉长距离依赖关系,多维度挖掘语义信息。位置编码赋予其序列顺序感知能力,而大规模预训练则使其具备强大的通用语言能力。Transformer已成为NLP领域的核心驱动力,推动智能语音助手、机器翻译等应用进入新时代。
451 2
|
Java 测试技术 开发者
springboot学习四:Spring Boot profile多环境配置、devtools热部署
这篇文章主要介绍了如何在Spring Boot中进行多环境配置以及如何整合DevTools实现热部署,以提高开发效率。
807 2
|
Ubuntu Docker 容器
docker容器保存和导入
docker容器保存和导入
301 0