Acwing---883.高斯消元解线性方程组 (Java)_数学知识_高斯消元模板

高斯消元解线性方程组

原题链接

①. 题目

在这里插入图片描述在这里插入图片描述

②. 思路

  • 这不就是离散数学里的矩阵解线性方程
    在这里插入图片描述

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

  1. 把某一行乘一个非0的数 (方程的两边同时乘上一个非0数不改变方程的解)
  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