Acwing --- 883。線形方程式を解くためのガウスの消去法(Java)_mathematics_gaussian消去法テンプレート

線形方程式を解くためのガウスの消去法

オリジナルタイトルリンク

①。タイトル

ここに画像の説明を挿入ここに画像の説明を挿入

②。考える

  • これは、離散数学における線形方程式の行列解ではありません。
    ここに画像の説明を挿入

前置知识:初等行(列)变换

  1. 行にゼロ以外の数値を掛けます(方程式の両側にゼロ以外の数値を同時に掛けても、方程式の解は変わりません)
  2. 特定の2行を交換します(2つの方程式の位置を交換します)
  3. ある行を別の行に数回追加します(ある方程式を別の方程式に数回追加します)

ここに画像の説明を挿入

  • 最後に、ラダー行列を下から上、最初の層に代入して、方程式の解を求めます。

算法步骤

  • 各列cを列挙し、
  • 現在の列の絶対値が最大の行を検索します
  • 基本線変換(2)を使用して、この線を一番上に変更します(はしご型の線は決定されず、最初の線ではありません)
  • 基本行変換(1)を使用して、行の最初の番号を1に変更します
  • (他のすべての数値は順番に変更されます)基本行変換(3)を使用して、後続のすべての行の現在の列の値を0に変更します。

③。学習ポイント

④。コードの実装

import java.util.Scanner;

public class Main {
    
    
	static int N=110;
	static double[][] a=new double[N][N+1];
	static int n=0;
	static double eps=0.000001;
	
	
	
	public static void main(String[] args) {
    
    
		Scanner sc = new Scanner(System.in);
		n=sc.nextInt();
		for (int i = 0; i <n; i++) {
    
    //行 n
			for (int j = 0; j <=n; j++) {
    
     //列n+1
				a[i][j]=sc.nextDouble();
			}
		}
		int t=guass(a);
		if(t==0) {
    
    //唯一解
			for (int i = 0; i <n; i++) {
    
    
				System.out.println(String.format("%.2f", a[i][n]));
			}
		}else if(t==1) {
    
     //五穷解
			System.out.println("Infinite group solutions");
		}else {
    
      //无解
			System.out.println("No solution");
		}
	}
	
	static int guass(double[][] a) {
    
    
		int row,col;
		//遍历每一列
		for(row=0,col=0;col<n;col++) {
    
    
			int t=row; 
			//找到该列中的绝对值的最大值的行号
			//每一个固定一行 不能进行修改
			for (int i =row; i <n; i++) {
    
    
				//Math.abs()可以用于浮点数取绝对值
				if(Math.abs(a[i][col])>Math.abs(a[t][col])) {
    
    
					t=i;
				}
			}
			//如果最大值为0,继续下一列寻找非0的最大值
			if(Math.abs(a[t][col])<eps) continue;
			//交换最大值的当前和和从上往下未固定的行
			for(int i=col;i<=n;i++) {
    
    
				//t是当前最大值的行 row是开始固定的那一行
				double temp=a[t][i];
				a[t][i]=a[row][i];
				a[row][i]=temp;
			}
			 //将当前的非0第一位数置为1,构造阶梯矩阵的斜边
			 //这里要注意从后往前去更新数据,因为这里变化是根据第一个数变化的,要保持它的数据最后变化或者找个数存一
			for (int i = n;i>=col; i--) {
    
    
				a[row][i]/=a[row][col];
			}
			
			//用上面那一行来更新下面的所有行,将该列中最大值改为1后下面的数全变成0
			//同样要注意从后往前更新数据
			for(int i=row+1;i<n;i++) {
    
    
				if(Math.abs(a[i][col])>eps) {
    
    
					for (int j = n; j >=col; j--) {
    
    
						a[i][j]-=a[row][j]*a[i][col];
					}
				}
			}
			//下一行处理
			row++;
		}
		//0解或者无穷解
		if(row<n) {
    
    
			  //阶梯状,更新不了下面的说明往下的都是0;
			//判断下面每一行的最后结果,如果不是0,说明无解
			for (int i =row; i <n; i++) {
    
    
				if(Math.abs(a[i][n])>eps) {
    
    
					return 2;
				}
			}
			return 1;
		}
		
		//处理唯一解,从下往上得出解
		for (int i =n-1; i>=0; i--) {
    
    
			for (int j =i+1; j <n; j++) {
    
    
				a[i][n]-=a[j][n]*a[i][j];
			}
		}
		return 0;
	}
}

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_45480785/article/details/113896468