[高斯消元及理论]线性方程组整数/浮点数,模线性方程组,异或方程组模板
文章目錄
- 理論
- 線性方程組整數類型解
- 線性方程組浮點類型解
- 模線性方程組
- 異或方程組
- 高斯約旦消元
- 約旦消元
- 無解
- 無窮解
- 唯一解
理論
高斯消元法,是線性代數規劃中的一個算法,可用來為線性方程組求解。但其算法十分復雜,不常用于加減消元法,求出矩陣的秩,以及求出可逆方陣的逆矩陣
用系數矩陣表示n元一次方程,如
{2x+3y+4z=20x?2y+3z=66x+4y?3z=5?(234201?23664?35)\begin{cases} 2x+3y+4z=20\\ x-2y+3z=6\\ 6x+4y-3z=5\\ \end{cases} \ ? \begin{pmatrix} 2&3&4&20\\ 1&-2&3&6\\ 6&4&-3&5\\ \end{pmatrix} ??????2x+3y+4z=20x?2y+3z=66x+4y?3z=5??????216?3?24?43?3?2065????
系數矩陣的運算法則:
? 1.將某一行同時乘以/除以一個非0常數。
? 2.某一行加上或減去另一行的若干倍
演示過程
(234201?23664?35)?r1?12(1322101?23664?35)?r2?r1,r3?6r1(1322100?721?40?5?15?55)\begin{pmatrix} 2&3&4&20\\ 1&-2&3&6\\ 6&4&-3&5\\ \end{pmatrix} \ ?^{r_1*\frac{1}{2}}\begin{pmatrix} 1&\frac{3}{2}&2&10\\ 1&-2&3&6\\ 6&4&-3&5\\ \end{pmatrix}\ ?^{r_2-r_1,r_3-6r_1}\begin{pmatrix} 1&\frac{3}{2}&2&10\\ 0&-\frac{7}{2}&1&-4\\ 0&-5&-15&-55\\ \end{pmatrix} ???216?3?24?43?3?2065??????r1??21????116?23??24?23?3?1065??????r2??r1?,r3??6r1????100?23??27??5?21?15?10?4?55????
?r2?(?27)(13221001?27870?5?15?55)?r1?32r2,r3+5r2(1017758701?278700?1157?3457)\ ?^{r_2*(-\frac{2}{7})}\begin{pmatrix} 1&\frac{3}{2}&2&10\\ 0&1&-\frac{2}{7}&\frac{8}{7}\\ 0&-5&-15&-55\\ \end{pmatrix}\ ?^{r_1-\frac{3}{2}r_2,r_3+5r_2}\begin{pmatrix} 1&0&\frac{17}{7}&\frac{58}{7}\\ 0&1&-\frac{2}{7}&\frac{8}{7}\\ 0&0&-\frac{115}{7}&-\frac{345}{7}\\ \end{pmatrix}??r2??(?72?)???100?23?1?5?2?72??15?1078??55??????r1??23?r2?,r3?+5r2????100?010?717??72??7115??758?78??7345??????r3?(?7115)(1017758701?27870013)?r1?177r3,r2+27r3(100101020013)\ ?^{r_3*(-\frac{7}{115})} \begin{pmatrix} 1&0&\frac{17}{7}&\frac{58}{7}\\ 0&1&-\frac{2}{7}&\frac{8}{7}\\ 0&0&1&3\\ \end{pmatrix} \ ?^{r_1-\frac{17}{7}r_3,r_2+\frac{2}{7}r_3} \begin{pmatrix} 1&0&0&1\\ 0&1&0&2\\ 0&0&1&3\\ \end{pmatrix} ??r3??(?1157?)???100?010?717??72?1?758?78?3??????r1??717?r3?,r2?+72?r3????100?010?001?123????
即{x1=1x2=2x3=3\begin{cases} x_1=1\\ x_2=2\\ x_3=3\\ \end{cases}??????x1?=1x2?=2x3?=3?
算法流程:
? 從1到n枚舉i,第i步定未知數i為主元,從上到下找到第一個未知數i不為0的方程定為主方程(如不存在則跳過這一步)
? 通過乘除系數使得主方程未知數i前面的系數為1 ? 對于其他方程,若未知數i前面的系數為k,那么該方程減去主方程的k倍,使得該方程未知數i系數為0
? 時間復雜度O(n^3)
一般來講,n個未知數n個方程在方程之間線性不相關的情況下,恰好有一組解
如果算法結束后,存在一行全為0,那么被消去的未知數可以任意取值,稱為自由元
如果有一行前n個數為0,最后一個數不為0,那么方程無解
當方程組數和未知數數不相等時,也可通過上面方法判定解數
提一句:多解
解的個數等于自由變量的取值范圍的冪
若自由變量的取值范圍為ppp ,自由變量有mmm個,則解的個數為pmp^mpm
線性方程組整數類型解
int a[maxn][maxn];//增廣矩陣 int ans[maxn]; bool Free[maxn];//標記是否為自由變元 int GCD ( int a, int b ) {if ( ! b )return a;return GCD ( b, a % b ); } int LCM ( int a, int b ) {return a / GCD ( a, b ) * b; } int Fabs ( int x ) {if ( x < 0 )return -x;return x; }int Gauss ( int equ, int var ) {for ( int i = 0;i <= var;i ++ ) {ans[i] = 0;Free[i] = 1;}int row, col, MaxRow;col = 1;for ( row = 1;row <= equ && col < var;row ++, col ++ ) {MaxRow = row;for ( int i = row + 1;i <= equ;i ++ )//尋找當前列絕對值最大的行 if ( Fabs ( a[i][col] ) > Fabs ( a[MaxRow][col] ) )MaxRow = i;if ( MaxRow != row ) {//與第row行交換 for ( int i = row;i <= var;i ++ )swap ( a[row][i], a[MaxRow][i] );}if ( ! a[row][col] ) {//說明col列第row行及以下都是0,就處理當前行的下一列 row --;continue;}for ( int i = row + 1;i <= equ;i ++ ) {//枚舉要刪去各自col列的變元的系數的行 if ( a[i][col] ) {int lcm = LCM ( Fabs ( a[i][col] ), Fabs ( a[row][col] ) );int T1 = lcm / Fabs ( a[i][col] );int T2 = lcm / Fabs ( a[row][col] );if ( a[i][col] * a[row][col] < 0 )T2 = -T2;for ( int j = col;j <= var;j ++ )a[i][j] = a[i][j] * T1 - a[row][j] * T2;}}}//無解:化簡的增廣矩陣中存在(0,0,...,a)這種類型 for ( int i = row;i <= equ;i ++ )if ( a[i][col] )return -1;int temp;//無窮解,矩陣中出現(0,0,...0) if ( row < var ) {for ( int i = row - 1;i > 0;i -- ) {// 第i行一定不會是(0, 0, ..., 0)的情況,因為這樣的行是在第k行到第equ行.// 同樣,第i行一定不會是(0, 0, ..., a), a != 0的情況,這樣的無解的int free_num = 0, idx;//用于判斷該行中的不確定的變元的個數,如果超過1個,則無法求解,它們仍然為不確定的變元for ( int j = 1;j < var;j ++ ) if ( a[i][j] && Free[j] ) {free_num ++;idx = j;}if ( free_num > 1 ) //無法求解出確定的變元 continue;temp = a[i][var];//說明只有一個不確定的變元,那么就可以解出該變元for ( int j = 1;j < var;j ++ ) {if ( a[i][j] && j != idx )temp -= a[i][j] * ans[j];}ans[idx] = temp / a[i][idx];Free[idx] = 0;}return var - row;//自由變元的個數 }//唯一解的情況,是一個嚴格的上三角形//1 0 ... 0//0 1 ... 0//0 0 1 . 0 for ( int i = var - 1;i > 0;i -- ) {temp = a[i][var];for ( int j = i + 1;j < var;j ++ )if ( a[i][j] )temp -= a[i][j] * ans[j];//--因為x[i]存的是temp/a[i][i]的值,即是a[i][i]=1時x[i]對應的值 // if ( temp % a[i][i] )//可以用來判斷有浮點數解,無整數解,但這個是整數解模板 // return -2;ans[i] = temp / a[i][i];}return 0; }線性方程組浮點類型解
#define eps 1e-6 double a[maxn][maxn]; double ans[maxn]; bool Free[maxn];int GCD ( int a, int b ) {if ( ! b )return a;return GCD ( b, a % b ); } int LCM ( int a, int b ) {return a / GCD ( a, b ) * b; }int Gauss ( int equ, int var ) {for ( int i = 0;i <= var;i ++ ) {ans[i] = 0;Free[i] = 1;}int row, col, MaxRow;col = 0;for ( row = 0;row < equ && col < var;row ++, col ++ ) {MaxRow = row;for ( int i = row + 1;i < equ;i ++ ) if ( fabs ( a[i][col] ) > fabs ( a[MaxRow][col] ) )MaxRow = i;if ( MaxRow != row ) {for ( int i = row;i <= var;i ++ )swap ( a[row][i], a[MaxRow][i] );}if ( fabs ( a[row][col] ) < eps ) {row --;continue;}for ( int i = row + 1;i < equ;i ++ ) {if ( fabs ( a[i][col] ) > eps ) {double temp = a[i][col] / a[row][col];for ( int j = col;j <= var;j ++ )a[i][j] -= a[row][j] * temp;a[i][col] = 0;}}}for ( int i = row;i < equ;i ++ )if ( fabs ( a[i][col] ) > eps )return -1;double temp;if ( row < var ) {for ( int i = row - 1;i >= 0;i -- ) {int free_num = 0, idx;for ( int j = 0;j < var;j ++ ) if ( a[i][j] && Free[j] ) {free_num ++;idx = j;}if ( free_num > 1 )continue;temp = a[i][var];for ( int j = 0;j < var;j ++ ) {if ( a[i][j] && j != idx )temp -= a[i][j] * ans[j];}ans[idx] = temp / a[i][idx];Free[idx] = 0;}return var - row;}for ( int i = var - 1;i >= 0;i -- ) {temp = a[i][var];for ( int j = i + 1;j < var;j ++ )if ( a[i][j] )temp -= a[i][j] * ans[j];ans[i] = temp / a[i][i];}return 0; }模線性方程組
int gcd( int x, int y ) {if( ! y ) return x;else return gcd( y, x % y ); }int inv( int x, int m ) {if( x == 0 ) return 0;if( x == 1 ) return 1;return inv( m % x, m ) * ( m - m / x ) % m; }int Gauss( int equ, int var ) {int row, col = 1;for( row = 1;row <= equ && col < var;row ++, col ++ ) {int MaxRow = row;for( int i = row + 1;i <= equ;i ++ )if( Fabs( a[i][col] ) > Fabs( a[MaxRow][col] ) )MaxRow = i;if( row != MaxRow ) {for( int i = row;i <= var;i ++ )swap( a[row][i], a[MaxRow][i] );}if( ! a[row][col] ) { row --; continue; }for( int i = row + 1;i <= equ;i ++ ) {if( a[i][col] ) {int d = gcd( Fabs( a[row][col] ), Fabs( a[i][col] ) );int lcm = Fabs( a[row][col] ) / d * Fabs( a[i][col] );int T1 = lcm / Fabs( a[i][col] );int T2 = lcm / Fabs( a[row][col] );if( a[i][col] * a[row][col] < 0 ) T2 = -T2;for( int j = col;j <= var;j ++ ) {a[i][j] = a[i][j] * T1 - a[row][j] * T2;a[i][j] = ( a[i][j] % mod + mod ) % mod;}}}}for( int i = row;i <= equ;i ++ )if( a[i][col] ) return -1;if( row < var ) return var - row;for( int i = var - 1;i;i -- ) {int temp = a[i][var];for( int j = i + 1;j < var;j ++ ) {if( a[i][j] ) {temp -= a[i][j] * x[j];temp = ( temp % mod + mod ) % mod;}}x[i] = temp * inv( a[i][i], mod ) % mod;}return 0; }異或方程組
int cnt; int a[maxn][maxn]; int ans[maxn]; bool Free[maxn];int GCD ( int a, int b ) {if ( ! b )return a;return GCD ( b, a % b ); } int LCM ( int a, int b ) {return a / GCD ( a, b ) * b; }int Gauss ( int equ, int var ) {int row, col, MaxRow;col = 0;for ( row = 0;row < equ && col < var;row ++, col ++ ) {MaxRow = row;for ( int i = row + 1;i < equ;i ++ ) if ( fabs ( a[i][col] ) > fabs ( a[MaxRow][col] ) )MaxRow = i;if ( MaxRow != row ) {for ( int i = row;i <= var;i ++ )swap ( a[row][i], a[MaxRow][i] );}if ( a[row][col] == 0 ) {row --;Free[++ cnt] = col;continue;}for ( int i = row + 1;i < equ;i ++ ) {if ( a[i][col] ) {for ( int j = col;j <= var;j ++ )a[i][j] ^= a[row][j];}}}for ( int i = row;i < equ;i ++ )if ( a[i][col] )return -1;if ( row < var ) return var - row;for ( int i = var - 1;i >= 0;i -- ) {ans[i] = a[i][var];for ( int j = i + 1;j < var;j ++ )if ( a[i][j] )ans[i] ^= ( a[i][j] && ans[j] );}return 0; }高斯約旦消元
約旦消元
void gauss_jordan ( int equ, int var ) {int row, col = 0;for ( row = 0;row < equ && col < var;row ++, col ++ ) {int MaxRow = row;for ( int i = row + 1;i < equ;i ++ )if ( fabs ( a[i][col] ) > fabs ( a[MaxRow][col] ) )MaxRow = i;if ( MaxRow != row ) {for ( int i = 0;i <= var;i ++ )swap ( a[row][i], a[MaxRow][i] );}if ( fabs ( a[row][col] ) < eps ) {row --;continue;}for ( int i = 0;i < equ;i ++ )if ( i != row )for ( int j = var;j >= row;j -- )a[i][j] -= a[i][col] / a[row][col] * a[row][j];} }無解
for ( int i = 0;i < equ;i ++ ) {bool flag = 1;for ( int j = i;j < var;j ++ )if ( fabs ( a[i][j] ) > eps )flag = 0;if ( flag && fabs ( a[i][var] ) > eps )return ! printf ( "-1" );}無窮解
for ( int i = 0;i < equ;i ++ ) {int free_num = 0;for ( int j = i;j < var;j ++ )if ( fabs ( a[i][j] ) > eps )free_num ++;if ( free_num > 1 )return ! printf ( "0" );}唯一解
for ( int i = 0;i < equ;i ++ )ans[i] = a[i][var] / a[i][i];for ( int i = 0;i < equ;i ++ )if ( fabs ( ans[i] ) < eps )printf ( "x%d=0\n", i + 1 );elseprintf ( "x%d=%.2f\n", i + 1, ans[i] );溫馨提示,不保證code的絕對正確,反正我是過了
錯了別打我,至少別打臉(跑ε=ε=ε=( ̄▽ ̄)
總結
以上是生活随笔為你收集整理的[高斯消元及理论]线性方程组整数/浮点数,模线性方程组,异或方程组模板的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎样系统还原 电脑怎么还原系统
- 下一篇: [树链剖分][SDOI 2011]染色,