高斯消元之乱搞矩阵
前言
今日,冰红茶同志跑过来问我高斯消元。他说看了我的博客没有看懂。好吧,这篇博客确实太水了,什么也没讲好,今天重打一发。
—————————————分割线—————————————
2022.3.26 更新:今天又把高斯消元考古了一遍emmm
1.引言
作为一名经常与小学数学打交道的OIER,大家应该都会解多元一次方程组吧~~~
小学老师都讲解过,要想解出包含有多个未知数的方程组,最重要的就是一个个的去消元,在回带。
最后解出方程组的正解。
今天蒟蒻就为大家讲解一下,在遭遇大量的多元一次方程组时的解决方法:
高斯-约旦消元法!!!
要想学会高斯-约旦消元法,就要先了解矩阵;
在列出 ,
这样的方程组时,我们可以把它转换为一个矩阵:
这样一来,我们就可以利用高斯三板斧:
将其转化为:
就得到了方程的解了~~
2.计算机实现
更:
高斯消元在我们平常的计算中很少运用,但是在计算机求解方程上却非常有用。
因为高斯消元的本质就是三种操作,计算机很好模拟这样的过程。
先讲一下计算机高斯消元的流程:
1:枚举每一列,也就是枚举每一个未知数:
2:先找到这个未知数的主元,我们一般把系数最大的作为主元,因为可以减小误差:
3.将当前的行与主元交换,因为我们必须在当前行进行操作,并求出未知数;
4.在与当前行交换后,从后往前,该未知数后面的所用未知数的系数除以当前主元的系数,这样就对当前行进行了消元。
5.当前行消元后,再从上到下倒着依次消元,注意是倒着消元,而且不是当前行。
6.每一行最后的就是答案了。
3.代码实现
接下来就看代码的实现了:
1.先来一道模板:P3389高斯消元
总体比较简单;
这道题不要求我们考虑无解的情况,所以较为简单。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e4;
double A[N][N];
int n;
int main()
{
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<=n;j++){
cin>>A[i][j];
}
}
for(int j=0;j<n;j++){//枚举每一列消元
int i;
for(i=j;i<n;i++){//找主元
if(A[i][j]){
break;
}
}
if(A[i][j]==0){
puts("No Solution");
return 0;
}
for(int k=0;k<=n;k++){
swap(A[i][k],A[j][k]);//与当前行交换
}
for(int k=n;k>=j;k--){
A[j][k]/=A[j][j];//消元
}
for(int i=0;i<n;i++)
if(i!=j)
for(int k=n;k>=j;k--)
A[i][k]-=A[j][k]*A[i][j];//消去后面每一行的元
}
for(int i=0;i<n;i++)
printf("%.2lf\n",A[i][n]);
return 0;
}
点击查看代码
void gauss(){
for(int i=1;i<=n;i++){
int max=i;
for(int j=i+1;j<=n;j++){
if(fabs(a[j][i])>fabs(a[max][i])) swap(max,j);
}
if(max!=i){
for(int j=1;j<=n+1;j++){
swap(a[i][j],a[max][j]);
}
}
if(fabs(a[i][i])<eps) continue;
for(int j=1;j<=n;j++){
if(j!=i){
double tmp=a[j][i]/a[i][i];
for(int k=i+1;k<=n+1;k++){
a[j][k]-=a[i][k]*tmp;
}
}
}
}
for(int i=1;i<=n;i++){
a[i][n+1]/=a[i][i];
}
}
同学们,你们应该都懂了吧~~~
4.例题
[JSOI2008]球形空间产生器
点击查看代码
#include<bits/stdc++.h>
using namespace std;
double a[20][20],A[20][20];
int n;
int main(){
cin>>n;
for(int i=0;i<=n;i++){
for(int j=0;j<n;j++){
cin>>a[i][j];
}
}
for(int i=0;i<=n;i++){
for(int j=0;j<n;j++){
A[i][j]=2*(a[i][j]-a[i+1][j]);
A[i][n]+=a[i][j]*a[i][j]-a[i+1][j]*a[i+1][j];
}
}
for(int j=0;j<n;j++){
int i;
for(i=j;i<=n;i++){
if(A[i][j]){
break;
}
}
for(int k=0;k<=n;k++){
swap(A[i][k],A[j][k]);
}
for(int k=n;k>=j;k--){
A[j][k]/=A[j][j];
}
for(int i=0;i<=n;i++){
if(i!=j){
for(int k=n;k>=j;k--){
A[i][k]-=A[j][k]*A[i][j];
}
}
}
}
for(int i=0;i<n;i++){
printf("%.3lf ",A[i][n]);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】