Gaussian elimination method (Gauss elimination) Analysis & Solution & template -- original czyuan
Gaussian elimination method is an algorithm in linear algebra. It can be used to solve linear equations, obtain the rank of a matrix, and obtain the inverse matrix of a reversible matrix.
The principle of Gaussian elimination method is:
If we convert the Augmented Matrix into an Elementary Line Transformation, Ax = B and Cx = D are the same solutions to the equations.
Therefore, we can use the elementary row transformation to convert the Augmented Matrix into a row-step array, and then return to find the solution of the equation.
The above is a review of linear algebra. Next we will talk about the application of Gaussian elimination method in programming.
First, we will introduce the process of Gaussian elimination in the program:
(We set the number of equations in the equations to EQU and the number of variable elements to var. Note: n equations and N variable elements are generally used, but some questions intentionally make the number of equations different from the number of variations)
1. Convert the equations into an augmented matrix.
2. Use Elementary Row Transformation to convert the Augmented Matrix into step arrays.
Enumeration K ranges from 0 to equ-1. The column currently being processed is COL (initially 0). Each time you find the column below the K (including the K row ), the column with the largest absolute value of the element in the col column is exchanged with row K. If all the elements in the col column are 0, the col + 1 column will be processed, and K will not change.
3. convert to a row-level array to determine the solution.
① No solution
When the equation appears (0, 0 ,..., 0, A) and! If it is set to 0, no solution is available.
② Unique Solution
The condition is k = equ, that is, the row step is formed into a strict upper triangle array. Use the return generation to obtain the solution set one by one.
③ Infinite solution.
The condition is k <equ, that is, a strict upper triangle cannot be formed, and the number of free yuan is equ-K. However, some questions require that you determine which variables are not missing.
Here we will introduce this solution separately:
First, there are at least var-K free variables, that is, there are at least var-K uncertain variables. We should consider all the changes as uncertain. Determine the number of uncertain variable elements in each equation. If there are more than one variable, the equation cannot be solved. If there is only one variable, the variable is determined.
The above describes the method for solving integer linear equations. The complexity is O (N3 ). The Method for Solving floating-point linear equations is similar. However, when determining whether the value is 0, add the EPS to eliminate the Accuracy Problem.
The following describes how to solve the linear equations using Gaussian elimination method on OJ:
Poj 1222 extended lights out
Http://acm.pku.edu.cn/JudgeOnline/problem? Id = 1222
Poj 1681 painter's Problem
Http://acm.pku.edu.cn/JudgeOnline/problem? Id = 1681
Poj 1753 flip game
Http://acm.pku.edu.cn/JudgeOnline/problem? Id = 1753
Poj 1830 Switch
Http://acm.pku.edu.cn/JudgeOnline/problem? Id = 1830
Poj 3185 the water bowls
Http://acm.pku.edu.cn/JudgeOnline/problem? Id = 3185
The problem of switching windows and lights is typical for solving linear equations. The number of equations and the number of variables are the number of rows * Number of columns. You can directly set the template to solve the problem. However, when an infinite solution occurs, it is necessary to enumerate the solution, because it is impossible to determine which solution is the most optimal.
Poj 2947 widget Factory
Http://acm.pku.edu.cn/JudgeOnline/problem? Id = 2947
Solve the Problem of homogeneous equations. Similar to the general solution to linear equations, you only need to add the remainder in the solution process.
Note: When the system of equations has a unique solution, the solution must be between [3, 9.
Poj 1166 the clocks
Http://acm.pku.edu.cn/JudgeOnline/problem? Id = 1166
There are various solutions to the classic BFS problem. You can also use the inverse matrix to multiply the matrix.
However, it seems that some problems have been solved by Gaussian elimination method (which has plagued me for N days... being plagued ...), since period 4 is not a prime number, the remainder cannot be obtained during the solution process (because the remainder may increase the solution set). However, the remainder operation is still required for the final solution set, the final solution is not guaranteed to be correct... no one answered questions in discuss for several days... which of the following is your hope ~~
Poj 2065 SETI
Http://acm.pku.edu.cn/JudgeOnline/problem? Id = 2065
This is also the problem of solving the same equations. Since P in the question is a prime number, you can obtain the remainder directly when solving the problem. Just apply the template to solve the problem. (Although there are few AC users, it is still a relatively watery question ,)
Poj 1487 single-player games
Http://acm.pku.edu.cn/JudgeOnline/problem? Id = 1487
A very troublesome question... the description in the question seems to have used the lexical definition in the Compilation Principle (it gives people the feeling they don't want to do it after reading it ...)
The idea of solving the equations is still very good-looking (the premise is that you can read the questions no more than five times ...), however, it is difficult to convert the string expression of the tree into a equations. I use stack + recursion to break it down. First, use the stack idea to find the number of children at the node, and then recursively solve each child.
This solution equations are also different... first, we need to solve the floating-point number equations, pay attention to the accuracy problem, and then ask about the uncertain variable, and solve it according to the method described above.
After a hard fight, I wrote 6000 + B... in addition, compaction is about giant C ++ Wa and G ++ AC. Maybe it's about accuracy... looking at this question and looking at this code, there is no desire to change...
Hdu oj 2449
Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 2449
A pure Gaussian question in the Harbin field competition. At that time, he Niu knocked for more than an hour... it is mainly to write a score class and set a high-precision template (to be lazy, Java ...) done ~~
Pay attention to the output when the values are 0 and negative.
Fze oj 1704
Http://acm.fzu.edu.cn/problem.php? PID = 1, 1704
One of the questions of the foru Grand Prix is still a classic switch problem, but the number of equations and the number of variations are different (it is time to test the template ~~), At last, the order of the augmented array is required, and high precision is required ~~
Sgu 275 to XOR or not to XOR
Http://acm.sgu.ru/problem.php? Contest = 0 & problem = 275
Question:
Http://hi.baidu.com/czyuan%5Facm/blog/item/be3403d32549633d970a16ee.html
Here, we provide templates for solving the integer linear equations that are fairly satisfactory. (floating point numbers are similar and are not provided )~~
/* Used to obtain the equations of integers .*/
# Include <iostream>
# Include <string>
# Include <cmath>
Using namespace STD;
Const int maxn = 105;
Int equ, VAR; // There are equ equations and VAR variable elements. The number of rows in the augmented array is equ, ranging from 0 to equ-1, and the number of columns is Var + 1, respectively, ranging from 0 to var.
Int A [maxn] [maxn];
Int X [maxn]; // solution set.
Bool free_x [maxn]; // determines whether the variable is uncertain.
Int free_num;
Void debug (void)
{
Int I, J;
For (I = 0; I <equ; I ++)
{
For (j = 0; j <var + 1; j ++)
{
Cout <A [I] [J] <"";
}
Cout <Endl;
}
Cout <Endl;
}
Inline int gcd (int A, int B)
{
Int T;
While (B! = 0)
{
T = B;
B = A % B;
A = T;
}
Return;
}
Inline int lcm (int A, int B)
{
Return a * B/gcd (A, B );
}
// Gaussian elimination method (Gauss-Jordan elimination ). (-2 indicates a floating point solution, but no integer solution.-1 indicates no solution, 0 indicates a unique solution, and greater than 0 indicates an infinite solution, and returns the number of free variables)
Int Gauss (void)
{
Int I, J, K;
Int max_r; // the row with the largest absolute value of the current column.
Int Col; // The column currently being processed.
Int Ta, TB;
Int LCM;
Int temp;
Int free_x_num;
Int free_index;
// Convert to a tiered array.
Col = 0; // The column currently being processed.
For (k = 0; k <equ & Col <var; k ++, Col ++)
{// Enumerate the currently processed rows.
// Find the row with the largest absolute value of the col column element and swap it with row K (to reduce the error in Division)
Max_r = K;
For (I = k + 1; I <equ; I ++)
{
If (ABS (A [I] [col])> ABS (A [max_r] [col]) max_r = I;
}
If (max_r! = K)
{// Exchange with row K.
For (j = K; j <var + 1; j ++) Swap (A [k] [J], a [max_r] [J]);
}
If (A [k] [col] = 0)
{// Indicates that the column K is 0, and the next column of the current row is processed.
K --; continue;
}
For (I = k + 1; I <equ; I ++)
{// Enumerate the rows to be deleted.
If (A [I] [col]! = 0)
{
LCM = lcm (ABS (A [I] [col]), ABS (A [k] [col]);
Ta = LCM/ABS (A [I] [col]), TB = LCM/ABS (A [k] [col]);
If (A [I] [col] * A [k] [col] <0) TB =-TB; // if the difference is that two numbers are added together.
For (j = Col; j <var + 1; j ++)
{
A [I] [J] = A [I] [J] * Ta-A [k] [J] * TB;
}
}
}
}
Debug ();
// 1. No solution: the simplified augmented array contains rows such as (0, 0,..., A) (! = 0 ).
For (I = K; I <equ; I ++)
{// For the infinite solution, if you want to determine which are the free variable elements, the exchange in the elementary row transformation will be affected, and the exchange will be recorded.
If (A [I] [col]! = 0) Return-1;
}
// 2. infinite solution: In the augmented array of Var * (VAR + 1), (0, 0 ,..., 0) This indicates that no strict upper triangle array is formed.
// The number of rows displayed is the number of free yuan.
If (k <var)
{
// First, there are at least var-K variables.
For (I = k-1; I> = 0; I --)
{
// Row I will not be (0, 0,..., 0), because such rows are from row K to row equ.
// Similarly, row I will not be (0, 0,..., A),! If it is 0, there is no such solution.
Free_x_num = 0; // used to determine the number of uncertain variable elements in the row. If more than one variable exists, it cannot be solved and they are still uncertain variable elements.
For (j = 0; j <var; j ++)
{
If (A [I] [J]! = 0 & free_x [J]) free_x_num ++, free_index = J;
}
If (free_x_num> 1) continue; // No fixed variable can be obtained.
// There is only one uncertain variable free_index, so we can solve the variable and the variable is determined.
Temp = A [I] [Var];
For (j = 0; j <var; j ++)
{
If (A [I] [J]! = 0 & J! = Free_index) temp-= A [I] [J] * X [J];
}
X [free_index] = temp/A [I] [free_index]; // obtain the variable.
Free_x [free_index] = 0; // The variable is determined.
}
Return var-K; // The free variable has var-K.
}
// 3. Unique Solution: a strict upper triangle array is formed in the augmented array of Var * (VAR + 1.
// Calculates the Xn-1, Xn-2... x0.
For (I = var-1; I> = 0; I --)
{
Temp = A [I] [Var];
For (j = I + 1; j <var; j ++)
{
If (A [I] [J]! = 0) temp-= A [I] [J] * X [J];
}
If (TEMP % A [I] [I]! = 0) Return-2; // indicates that there is a floating point solution, but no integer solution.
X [I] = temp/A [I] [I];
}
Return 0;
}
Int main (void)
{
Freopen ("input.txt", "r", stdin );
Int I, J;
While (scanf ("% d", & equ, & var )! = EOF)
{
Memset (A, 0, sizeof ());
Memset (x, 0, sizeof (x ));
Memset (free_x, 1, sizeof (free_x); // all variables are uncertain at the beginning.
For (I = 0; I <equ; I ++)
{
For (j = 0; j <var + 1; j ++)
{
Scanf ("% d", & A [I] [J]);
}
}
// Debug ();
Free_num = Gauss ();
If (free_num =-1) printf ("no solution! \ N ");
Else if (free_num =-2) printf ("floating point solution, no integer solution! \ N ");
Else if (free_num> 0)
{
Printf ("infinite solution! Number of free variables: % d \ n ", free_num );
For (I = 0; I <var; I ++)
{
If (free_x [I]) printf ("X % d is uncertain \ n", I + 1 );
Else printf ("X % d: % d \ n", I + 1, x [I]);
}
}
Else
{
For (I = 0; I <var; I ++)
{
Printf ("X % d: % d \ n", I + 1, x [I]);
}
}
Printf ("\ n ");
}
Return 0;
}
/* Original czyuan. For more information, see the source. */