高斯消元法示例

Posted Beyond The API

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高斯消元法示例相关的知识,希望对你有一定的参考价值。

好的,以下是一个高斯消元法的示例:
假设我们想要求解以下线性方程组:

\\[\\beginaligned x + 2y - z &= 0 \\\\ 2x - y + z &= 8 \\\\ -3x + y + 2z &= -4 \\\\ \\endaligned \\]

我们可以将系数和常数放入一个增广矩阵中:

\\[\\left[ \\beginarrayccc|c 1 & 2 & -1 & 0 \\\\ 2 & -1 & 1 & 8 \\\\ -3 & 1 & 2 & -4 \\\\ \\endarray \\right]. \\]

接下来,使用高斯消元法将增广矩阵转换成行阶梯矩阵。具体步骤如下:

  1. 用第一行的第一个元素(即1)消去第二行的第一个元素(即2)和第三行的第一个元素(即-3):

\\[\\left[ \\beginarrayccc|c 1 & 2 & -1 & 0 \\\\ 0 & -5 & 3 & 8 \\\\ 0 & 7 & 5 & -4 \\\\ \\endarray \\right]. \\]

  1. 用第二行的第二个元素(即-5)消去第三行的第二个元素(即7):

\\[\\left[ \\beginarrayccc|c 1 & 2 & -1 & 0 \\\\ 0 & -5 & 3 & 8 \\\\ 0 & 0 & 16.4 & 40 \\\\ \\endarray \\right]. \\]

  1. 将最后一行除以16.4,得到:

\\[\\left[ \\beginarrayccc|c 1 & 2 & -1 & 0 \\\\ 0 & -5 & 3 & 8 \\\\ 0 & 0 & 1 & 2.44 \\\\ \\endarray \\right]. \\]

现在,这个增广矩阵就是一个行阶梯矩阵。接下来,我们可以使用回代法求解方程组的解。
从最后一行开始,我们可以得到第三个未知数 \\(z\\) 的值:

\\[z = 2.44. \\]

接下来,我们可以将这个值带入到第二个方程中,得到:

\\[-5y + 3z = 8 \\Rightarrow -5y + 3(2.44) = 8 \\Rightarrow y = -0.12. \\]

最后,我们可以将 \\(z\\)\\(y\\) 的值带入到第一个方程中,得到:

\\[x + 2y - z = 0 \\Rightarrow x + 2(-0.12) - 2.44 = 0 \\Rightarrow x = 2.68. \\]

因此,方程组的解为:

\\[x = 2.68, \\quad y = -0.12, \\quad z = 2.44. \\]

这就是使用高斯消元法求解线性方程组的基本过程。

题解 P3389 模板高斯消元法

题解 P3389 【【模板】高斯消元法】

看到大家都没有重载运算符,那我就重载一下运算符给大家娱乐一下

我使用的是高斯-约旦消元法,这种方法是精度最高的(相对地)

一句话解释高斯约旦消元法:

通过加减消元法,依次制定x0,并通过加减消元法消去其他方程的x0的系数。对于这样的系数矩阵我们只进行初等变幻保证了其正确性

看代码吧,主要是希望帮助大家可以学到一些重载的方法

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
inline int qr(void){
    char c=getchar();
    int x=0,q=1;
    while(c<48||c>57)
        q=c==45?-1:q,c=getchar();
    while(c>=48&&c<=57)
        x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return q*x;
}
#define RP(t,a,b)   for(int t=(a),edd=(b);t<=edd;t++)
typedef double db;
const double EPS=1e-20;//这是坑点,一点要小一点,这个EPS。 
int n;
const int maxn=105;
int ans[maxn];
inline db fabs(double x){
    return x>=0?x:-x;
}
struct node{
    db dat[maxn];
    double& operator [](const int &x){
        return dat[x];//重载运算符,返回引用 , 就算有dat有更多维,这样就好了,原理有关c++的“地址”系统 
    }
    node operator *(const db &x){
        node ans=(*this);//this是个指针,指向运算符左边的地址 
        for(int t=1;t<=n+1;t++)
            ans[t]*=x;
        return ans;
    }
    node operator /(const db &x){
        node ans=(*this);
        for(int t=1;t<=n+1;t++)
            ans[t]/=x;
        return ans; 
    }
    node operator -(node &x){
        node ans=(*this);
        for(int t=1;t<=n+1;t++)
            ans[t]-=x[t];
        return ans;
    }
    node operator *=(const db &x){
        return (*this)=(*this)*x;
    }
    node operator /=(const db &x){
        return (*this)=(*this)/x;
    }
    node operator -=( node &x){
        return (*this)=(*this)-x;
    }
}data[maxn];
bool vis[maxn];
inline int big(int x){
    db ans=0;
    int ret;
    for(int t=1;t<=n;t++)
        if(!vis[t]&&ans<fabs(data[t][x]))
            ret=t;
    vis[ret]=1;//根据数学原理,不可重复选择一个方程来消元 
    return ret;//为了避免乘一个过小的数字,选择一个对于该未知数绝对值最大的系数 
}
inline void kkk(void){
    RP(t0,1,n){
        int sttd=big(t0);
        const db a=data[sttd][t0];
        RP(t,1,n)
            if(t!=sttd){
                if(fabs(data[t][t0])<EPS){
                    cout<<"No Solution";//防止除0 
                    return;
                }
                data[t]*=(a/data[t][t0]),data[t]-=data[sttd];//将选定x0的系数和基准方程变为一致,在通过加减消元消掉,
                                                             //此后该未知数的系数就是0,不会再产生影响 
            }
        ans[t0]=sttd;//记录结果是哪个方程得出的 
    }
    RP(t,1,n)
        if(fabs(data[ans[t]][t])<EPS){
            cout<<"No Solution"<<endl;
            return;
        }
    RP(t,1,n){
        printf("%.2lf
",(data[ans[t]][n+1]/data[ans[t]][t]));
    }
    return;
}
int main(){
    n=qr();
    RP(t,1,n)
        RP(i,1,n+1)
            data[t][i]=qr();
    kkk();
    return 0;//功德圆满 
}

以上是关于高斯消元法示例的主要内容,如果未能解决你的问题,请参考以下文章

题解 P3389 模板高斯消元法

高斯消元法

高斯消元法

高斯消元法

C++ 数学与算法系列之高斯消元法求解线性方程组

高斯-约旦消元法