高斯消元法求解线性方程组(列主元消去法)

高斯消元法求解线性方程组(列主元消去法)

    和求解行列式的值类似,当某一列的常数项全为0时,方程组无解或有无穷多解,此时退出程序;否则将列主元下面的元素逐个消去,直至循环结束。要注意的是为了保持数值的稳定性(精度),每次选取的列主元的系数都是该列绝对值最大的那个。
#include  < cstdio >
#include 
< cmath >

#define  MAXN 100
#define  eps 1e-9

int  gauss_elimination( int  n, double  a[][MAXN], double  b[]) {
    
int i,j,k,row;
    
double maxp,t;
    
for(k=0;k<n;k++){//行标+列标
        for(maxp=0,i=k;i<n;i++)//行标
            if (fabs(a[i][k])>fabs(maxp))//选取绝对值最大的主元素,保持数值稳定性
                maxp=a[row=i][k];
        
if(fabs(maxp)<eps) return 0;
        
if(row!=k){
            
for(j=k;j<n;j++)
                t
=a[k][j],a[k][j]=a[row][j],a[row][j]=t;
            t
=b[k],b[k]=b[row],b[row]=t;
        }

        
for(j=k+1;j<n;j++)//列标
            for(a[k][j]/=maxp,i=k+1;i<n;i++)//行标
                a[i][j]-=a[i][k]*a[k][j];
        
for(b[k]/=maxp,i=k+1;i<n;i++)//行标
            b[i]-=b[k]*a[i][k];
    }

    
for(i=n-1;i>=0;i--)
        
for(j=i+1;j<n;j++)
            b[i]
-=a[i][j]*b[j];
    
return 1;
}

int  main() {
    
int i,j,n;
    
double a[MAXN][MAXN],b[MAXN];
    
while(scanf("%d",&n),n){
        
for(i=0;i<n;i++){
            
for(j=0;j<n;j++)
                scanf(
"%lf",&a[i][j]);
            scanf(
"%lf",&b[i]);
        }

        
if(gauss_elimination(n,a,b))
            
for(i=0;i<n;i++)
                printf(
"x%d : %.2lf\n",i+1,b[i]);
        
else
            puts(
"Uncertain");
    }

    
return 0;
}

你可能感兴趣的:(高斯消元法求解线性方程组(列主元消去法))