オリジナルタイトルリンク
①。タイトル
②。考える
- これは、離散数学における線形方程式の行列解ではありません。
前置知识:初等行(列)变换
- 行にゼロ以外の数値を掛けます(方程式の両側にゼロ以外の数値を同時に掛けても、方程式の解は変わりません)
- 特定の2行を交換します(2つの方程式の位置を交換します)
- ある行を別の行に数回追加します(ある方程式を別の方程式に数回追加します)
- 最後に、ラダー行列を下から上、最初の層に代入して、方程式の解を求めます。
算法步骤
- 各列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++) {
for (int j = 0; j <=n; j++) {
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++) {
if(Math.abs(a[i][col])>Math.abs(a[t][col])) {
t=i;
}
}
if(Math.abs(a[t][col])<eps) continue;
for(int i=col;i<=n;i++) {
double temp=a[t][i];
a[t][i]=a[row][i];
a[row][i]=temp;
}
for (int i = n;i>=col; i--) {
a[row][i]/=a[row][col];
}
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++;
}
if(row<n) {
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;
}
}