美文网首页
高斯消元法(约当消元法)

高斯消元法(约当消元法)

作者: Anxdada | 来源:发表于2017-03-02 20:16 被阅读0次

    这个真的烦了我好久啊,可能是我太笨了,最后看了几个模板,和写了好久,终于让我弄懂了.具体看代码咯
    这个是直接判断是否为0的,精度几乎没有.

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    double a[128][128];
    int m,n;
    int cmp(double x, double y)
    {
        double v=fabs(x-y);
        if(v>1e-6)  return 1;
        else return 0;
    }
    void pf()
    {
        int i,j;
        printf("-----------------------\n");
        for(i=1; i<=m; i++) {
            for(j=1; j<=n; j++){
                printf("%5.1f ",a[i][j]);
            }
            printf("\n");
        }
    }
    void solve()
    {
        int i,j,k;
        for(i=1; i<=m; i++){
            if(cmp(a[i][i],0)==0){
                for(j=i+1; j<=m; j++){
                    if(cmp(a[j][i],0)==1)
                        break;
                }
                for(k=1; k<=n; k++)
                    swap(a[i][k],a[j][k]);
            }
            for(j=n; j>=i; j--){//这里一定要倒着减,因为是减到i之后的,前面的是不能减掉的.
                for(k=1; k<=m; k++) {
                    if(k!=i){
                        a[k][j]-=(a[k][i]/a[i][i]*a[i][j]);//懂了!//精华啊,下次没看懂时就写出来,不要干想.
                    }
                }
            }
        }
        for(i=1; i<=m; i++)
        {
             for(j=n;j>=i;j--) {
                    a[i][j]/=a[i][i];//让最后一列的元素单位化
               }
        }
    }
    int main()
    {
        int i,j;
        scanf("%d%d",&m,&n);
        for(i=1; i<=m; i++)
        {
            for(j=1; j<=n; j++)
            {
                scanf("%lf",&a[i][j]);
            }
        }
        solve();
        //pf();//可以自己自行选择是否打出来看看
    }
    

    这个精度就有要求了,尽量选择该列中较大的那个数,而且新增的判断0的那个还可以根据题目修改变为求矩阵的秩.好好想一想(写出来嘛)

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<set>
    #include<queue>
    #include<stack>
    #include<cstdlib>
    #define CLR(x) memset(x,0,sizeof(x))
    #define ll long long int
    #define db double
    using namespace std;
    const int maxn=205;
    const ll inf=1e15+5;
    const int INF = 1e8 + 5;
    const int mod=1e9 + 7;
    const db EPS=1e-2;
    double a[205][205];
    int vis[205];//记录全为0的那一行.
    int m,n,cnt=0;
    int cmp(db x, db y)
    {
        db v;
        v=abs(x-y);
        if(v>=EPS)return 1;
        return 0;
    }
    
    void debug()
    {
        printf("-----------------------\n");
        for(int i=1; i<=m; i++){
            for(int j=1; j<=n; j++){
                printf("%5.1f ",a[i][j]);
            }
            printf("\n");
        }
    }
    
    void solve()
    {
        int sj,flag;
        db maxx;
        CLR(vis);
        for(int i=1; i<=m; i++){
            flag=0;
            maxx=-inf;
            for(int j=i; j<=m; j++){
                if(a[j][i]>maxx&&cmp(a[j][i],0)){
                    sj=j;//用于交换的行数
                    maxx=a[j][i];
                    flag=1;
                }
            }
            if(!flag){
               vis[i]=1;//好好想想,用于判断(写出来就可以知道了).
                cnt++;//判断
                continue;
            }
            for(int k=1; k<=n; k++)
                    swap(a[i][k],a[sj][k]);
            for(int j=n; j>=i; j--){//这里一定要倒着减,因为是减到i之后的,前面的是不能减掉的.
                if(vis[j])
                    continue;//因为a[i]][i]是不能除的数.
                for(int k=1; k<=m; k++) {
                    if(k!=i){
                        a[k][j]-=(a[k][i]/a[i][i]*a[i][j]);//懂了!//精华啊,下次没看懂时就写出来,不要干想.
                    }
                }
            }
        }
        for(int i=1; i<=m; i++){
            if(!allzero[i]){
                for(int j=n;j>=0;j--){
                    a[i][j]/=a[i][i];
                }
            }
        }
    }
    int main()
    {
        int i,j;
        scanf("%d%d",&m,&n);
        for(i=1; i<=m; i++){
            for(j=1; j<=n; j++){
                scanf("%lf",&a[i][j]);
            }
        }
        solve();
        //debug();
        int p=m-cnt;
        if(p>=0)
            printf("%d\n",p);
        else
            printf("-1\n");
    }
    

    相关文章

      网友评论

          本文标题:高斯消元法(约当消元法)

          本文链接:https://www.haomeiwen.com/subject/ifxiwttx.html