[Algorithm] Detailed explanation of Gaussian elimination

Original link (strongly recommend Amway)

0.Prerequisite knowledge

  • Know how to solve a system of linear equations in three variables
  • Have hands, have brains

1.Representation and storage of answers

First solve a system of equations:

2x+3y+5z=31
x-4y -z=-6
4x+2y-5z=9


We write this system of equations into a table format that can be read by machines :

2 3 5 31
1 -4 -1 -6
4 2 -5 9

The first column represents xxThe coefficient of x , the second column representsyyThe coefficient of y ...
Notethat the extra fourth column is the specific value of the answer.
The first row represents equation 1, the second column represents equation 2...


Because we always use x, y, zx,y,zx,y,z meansnnThe number n is inconvenient, so we usea 1 , a 2 . . . an a_1,a_2...a_na1,a2...anTo represent.

That is, the meaning of the above table is:

i ( 1 ≤ i ≤ n ) i(1\le i\le n)i(1iColumn n ) represents ai a_iin each formulaaiCoefficient of n + 1 n+1n+Column 1 represents the specific valueof each formula. (Because these are ordinary values ​​when stored, readersmust distinguish them clearly)

i ( 1 ≤ i ≤ n ) i(1\le i\le n)i(1iLine n ) represents theiithi formulas.

Then throughout the text, use a [ i ] [ j ] a[i][j]a [ i ] [ j ] Display No.iiLine i , jjValue/coefficient of column j .


2. Gaussian elimination idea

The name is so high-end, but the method is very crude. The specific operation is: addition, subtraction and elimination + substitution and elimination .

First, follow the coefficient matrix above:

2 3 5 31
1 -4 -1 -6
4 2 -5 9

Then start Gaussian elimination.

enumerationii _i ,sequentially eliminate unknowns ai a_iai

Then enumerate jjj , find aminimum absolute valuethat is not0 00 a [ j ] [ i ] a[j][i] a[j][i]

Find the minimum a[j][i]a[j][i]a [ j ] [ i ]jjAfter j , add thejjthThe j formula and theiii expression exchange

enum jjj ,设 m u l = a [ i ] [ i ] / a [ j ] [ i ] mul=a[i][i]/a[j][i] mul=a[i][i]/a[j][i]
j j j expression multiplied bymul mulm u l and minusiii formula

Let’s analyze why we do this layer by layer.
First, enumerate iii , need toeliminate the iii unknown numbers.
Then, selectjjj usea [ j ] [ i ] a[j][i]a [ j ] [ i ] is the smallest, which is actuallynot necessary(I will explain why later). exchangejjj formula andiii formula.
Later, enumerate eachjjj , willjja [ i ] [ i ] / a [ j ] [ i ] a[i][i]/a[j][i ]a [ i ] [ i ] / a [ j ] [ i ] , because jj needs to bej formulaiiThe coefficient of term i is adjustedtoiii shikikoiiThe coefficients of i terms are the same;
changejjj minusiiThe purpose of formula i is to eliminate the iiThe coefficient of item i .

Why choose the smallest absolute value instead of 0 00 a [ j ] [ i ] a[j][i] a [ j ] [ i ]jjWhere is j ? Becausea [ j ] [ i ] a[j][i]smallestabsolute valuea [ j ] [ i ] can roughlyformmore divisible situations, and this can avoid.
Cannot take0 00 is of course.

If you still don’t understand? Then simulate it layer by layer.
Let’s take this system of equations as an example:

2 3 5 31
1 -4 -1 -6
4 2 -5 9

First, eliminate the first coefficient.

1 -4 -1 -6
2 3 5 31
4 2 -5 9

Find the minimum a [ 1 ] a[1]For the formula a [ 1 ] , adjust to the first one;

1 -4 -1 -6
1 3/2 5/2 31/2
4 2 -5 9

The second persimmon × 0.5 \times 0.5×0.5

1 -4 -1 -6
0 11/2 7/2 43/2
4 2 -5 9

Subtract the first from the second equation.


By analogy, the coefficient matrix of the final answer is: (not aligned, a bit ugly)

4 0 0 20
0 -4.5 0 -9
0 0 7.611 22.833

Then the final n + 1 n+1n+1 coefficient divided byiii rowiiThe value in column i is enough.

3. The code you want to see.

P3389 [Template] Gaussian elimination method

The comments are a bit sparse, but just understandable.

#include<bits/stdc++.h>
#define RI register int
using namespace std;typedef long long LL;const int inf=1073741823;int FL,CH;template<typename T>void in(T&a){
    
    for(a=0,FL=1,CH=getchar();!isdigit(CH);CH=getchar())FL=(CH=='-')?-1:1;for(;isdigit(CH);CH=getchar())a=a*10+CH-'0';a*=FL;}template<typename T,typename ...Args>void in(T&a,Args&...args){
    
    in(a);in(args...);}
const int maxn=110;const double eps=1e-6;
double a[maxn][maxn];
int n;
int main()
{
    
    
	cin>>n;
	for(RI i=1;i<=n;++i){
    
    
		for(RI j=1;j<=n+1;++j)scanf("%lf",&a[i][j]);}
	//输入系数矩阵
	for(RI rp,i=1;i<=n;++i)
	{
    
    
		rp=i;
		for(RI j=i+1;j<=n;++j)
		if(fabs(a[j][i])>fabs(a[rp][i]))rp=j;
		if(fabs(a[rp][i])<=eps)
		return printf("No Solution"),0;
		//寻找绝对值最小的 j
		//这个特殊一点,要判无解
		if(i!=rp)swap(a[rp],a[i]);
		//交换 j 和 i
		double div=a[i][i];
		for(RI j=1;j<=n;++j)
		if(j!=i){
    
    
			div=a[j][i]/a[i][i];
			//计算 mul 值
			for(RI k=1;k<=n+1;++k)
				a[j][k]-=a[i][k]*div;
			//乘上,再减去
			//高斯消元算法的精髓
		}
	}
	for(RI i=1;i<=n;++i)
		printf("%.2lf\n",a[i][n+1]/a[i][i]);//回代,并输出答案
	return 0;
}

Guess you like

Origin blog.csdn.net/zhy_Learn/article/details/118769379
Recommended