ガウスの消去法(GaussNoShoukyoHou.java) プログラムのダウンロード その2 解説 トップページへ戻る
 始めに対角要素より下の係数をまず消去する。これを前進消去という。その後、解の決まる最後の解を一つ手前の式に代入し、解を求める。これを順次手前に戻っていき、解を求める。これを後退代入という。対角要素の係数は0でないことが条件である。もし対角係数が0の場合は行を入れ替える。
/*
 * 
 *ガウスの消去法
 * (GaussNoShoukyoHou.java)
 *
 */

public class GaussNoShoukyoHou {

        //連立方程式の係数
        //a[N][N](係数行列)とb[1](定数)を一緒にしたもの
        double a[][]={{1.0,1.0,1.0,1.0,10,0},
                      {2.0,1.0,3.0,2.0,21.0},
                      {1.0,3.0,2.0,1.0,17.0},
                      {3.0,2.0,1.0,1.0,14.0}};
        int N=a.length;

        //Gaussの消去法で連立方程式を解く
        void gauss(){
       //前進消去
           double s;
           for(int k=0; k<N-1; k++){
                   for(int i=k+1; i<N; i++){
                       s=a[i][k]/a[k][k];
                       for(int j=k+1; j<=N; j++){
                           a[i][j] -= s * a[k][j];
                       }
                   }
           }
           //後退代入
           for(int i=N-1; i>=0; i--){
                   s=a[i][N];
                   for(int j=i+1; j<N; j++){
                           s -= a[i][j] * a[j][N];
                   }
                   a[i][N] = s/a[i][i];
           }
        }
        public static void main(String[] args) {
       GaussNoShoukyoHou gs= new GaussNoShoukyoHou();
       gs.gauss();
       //解の表示
       System.out.println("ガウスの消去法による連立1次方程式の解");
           for(int i=0; i<gs.N; i++){
                   System.out.println("x["+i+"] = "+gs.a[i][gs.N]);
           }
        }
}
/*
 * 
 *ガウスの消去法
 * (GaussNoSyoukyoHou2)
 *
 */

public class GaussNoSyoukyoHou2 {
        
        //連立方程式の係数
        //a[N][N](係数行列)とb[1](定数)を一緒にしたもの
/*      double a[4][5]={{1.0,1.0,1.0,1.0,10.0},
                               {2.0,1.0,3.0,2.0,21.0},
                               {1.0,3.0,2.0,1.0,17.0},
                               {3.0,2.0,1.0,1.0,14.0}};*/
/*      double a[3][4]={{1.0,1.0,-1.0,0.0},
                       {1.5,-2.0,0.0,-2.5},
                       {0.0,2.0,0.5,5.5}};*/
        double a[][]={{0.0,15.0,5.0,75.0},
                      {15.0,-15.0,-10.0,-60.0},
                      {5.0,-15.0,10.0,-20.0}};  
        int N=a.length;
        double x[]=new double [N];

//枢軸要素の抽出
//k列の係数a[k][k]〜a[N-1][k]の中から絶対値最大のものをみつけ
//それを含む行とk行を入れ替える       
public void pivot(int N,int k,double a[][]){
        int ip;
        double max;
        max=Math.abs(a[k][k]);
    ip=k;
        if(k != N-1){
                for(int i=k+1 ; i<N ; i++){
                        if(Math.abs(a[i][k]) > max){
                                max=Math.abs(a[i][k]);
                                ip=i;
                        }
                }
        }
        if(ip != k){
                for(int j=k ; j<=N ; j++){
                        double copy=a[k][j];
                        a[k][j]=a[ip][j];
                        a[ip][j]=copy;
                }
        }
}

//前進消去
public void forward(int N,int k,double a[][]){
    double p,q;
        p=a[k][k];
        for(int j=k;j<=N;j++)
            a[k][j]/=p;
        if( k != N-1){
                for(int i=k+1;i<N;i++){
                        q=a[i][k];
                        for(int l=k+1;l<=N;l++)
                a[i][l]-=q*a[k][l];
                }
        }
}

//後退代入
public void backward(int N,double a[][],double x[]){
        x[N-1]=a[N-1][N]/a[N-1][N-1];
        for(int k=N-2;k>=0;k--){
                double sum=0.0;
                for(int j=k+1;j<N;j++)
                        sum += a[k][j]*x[j];
        x[k]=a[k][N]-sum;
        }
}

public static void main(String[] args) {
        
        GaussNoSyoukyoHou2 gs=new GaussNoSyoukyoHou2();
        for(int k=0;k<gs.N;k++){
                gs.pivot(gs.N,k,gs.a);
                gs.forward(gs.N,k,gs.a);
        }
        gs.backward(gs.N,gs.a,gs.x);

    //解の表示
        System.out.printf("ガウスの消去法による連立1次方程式の解\n");
        for(int i=0; i<gs.N; i++){
                System.out.printf("x[%1d] = %10.3f\n",i,gs.x[i]);
    }

}
}