Gauss-Seidel módszer lineáris egyenletrendszer megoldására
A Gauss-Seidel módszer (Seidel-módszer, Libman-folyamat, szekvenciális helyettesítési módszer) egy klasszikus iteratív módszer lineáris egyenletrendszer megoldására .
Seidelről és Gaussról kapta a nevét .
A probléma leírása
Vegyük a rendszert:
, hol
Vagy
És megmutatjuk, hogyan lehet ezt Gauss-Seidel módszerrel megoldani.
Módszer
A módszer lényegének tisztázására átírjuk a problémát az űrlapba
Itt az egyenletben átvittük a jobb oldalra az összes olyan kifejezést, amelyek tartalmazzák a , for . Ez a bejegyzés a következővel ábrázolható
ahol az elfogadott jelölésben olyan mátrixot jelent, amelynek főátlója tartalmazza a mátrix megfelelő elemeit és az összes többi nullát; míg a és mátrixok felső és alsó háromszög alakú részeket tartalmaznak , amelyek főátlóján nullák vannak.
Az iteratív folyamat a Gauss-Seidel módszerben a képlet szerint épül fel
a megfelelő kezdeti közelítés kiválasztása után .
A Gauss-Seidel módszer a Jacobi-módszer módosításaként tekinthető . A módosítás fő gondolata, hogy az új értékeket a beérkezésükkor használjuk fel, míg a Jacobi-módszerben csak a következő iterációig:
ahol
Így a -edik közelítés i -edik komponensét a képlet számítja ki
Például amikor :
, vagyis
, vagyis
, vagyis
Konvergencia feltétel
Tegyünk egy elégséges feltételt a módszer konvergenciájához.
|
Tétel . Legyen, ahola mátrix inverze -re. Ezután a kezdeti közelítés bármely választásához:
- a Gauss-Seidel módszer konvergál;
- a módszer konvergencia sebessége megegyezik egy geometriai haladás nevezővel való konvergenciájának sebességével ;
- helyes hibabecslés: .
|
|
Felmondási feltétel
A Seidel iteratív folyamat befejezésének feltétele, ha a pontosság egyszerűsített formában érhető el, a következő:
Az iteratív folyamat befejezésének pontosabb feltétele a forma
és több számítást igényel. Ritka mátrixokhoz jó .
#include <iostream>
#include <cmath>
névtér használata std ;
// Végfeltétel
bool konverge ( double xk [ 10 ], double xkp [ 10 ], int n , double eps )
{
kettős norma = 0 ;
for ( int i = 0 ; i < n ; i ++ )
norma += ( xk [ i ] - xkp [ i ]) * ( xk [ i ] - xkp [ i ]);
return ( sqrt ( norma ) < eps );
}
dupla okr ( double x , double eps )
{
int i = 0 ;
double neweps = eps ;
míg ( új hírek < 1 )
{
i ++ ;
neweps *= 10 ;
}
int okr = pow ( double ( 10 ), i );
x = int ( x * okr + 0,5 ) / double ( okr );
visszatér x ;
}
bool átló ( dupla a [ 10 ][ 10 ], int n )
{
int i , j , k = 1 ;
dupla összeg ;
for ( i = 0 ; i < n ; i ++ ) {
összeg = 0 ;
for ( j = 0 ; j < n ; j ++ ) összeg += abs ( a [ i ][ j ]);
összeg -= absz ( a [ i ][ i ]);
if ( összeg > a [ i ][ i ])
{
k = 0_ _
cout << a [ i ][ i ] << " < " << összeg << endl ;
}
más
{
cout << a [ i ][ i ] << " > " << összeg << endl ;
}
}
return ( k == 1 );
}
int main ()
{
setlocale ( LC_ALL , "" );
dupla eps , a [ 10 ][ 10 ], b [ 10 ], x [ 10 ], p [ 10 ];
int n , i , j , m = 0 ;
int metódus _
cout << "Adja meg a négyzetmátrix méretét: " ;
cin >> n ;
cout << "Adja meg a számítási pontosságot: " ;
cin >> eps ;
cout << "A mátrix kitöltése: " << endl << endl ;
for ( i = 0 ; i < n ; i ++ )
for ( j = 0 ; j < n ; j ++ )
{
cout << "A[" << i << "][" << j << "] = " ;
cin >> a [ i ][ j ];
}
cout << endl << endl ;
cout << "Az A mátrixod: " << endl << endl ;
for ( i = 0 ; i < n ; i ++ )
{
for ( j = 0 ; j < n ; j ++ )
cout << a [ i ][ j ] << " " ;
cout << endl ;
}
cout << endl ;
cout << "Töltsd ki az ingyenes tagok oszlopot: " << endl << endl ;
for ( i = 0 ; i < n ; i ++ )
{
cout << "B[" << i + 1 << "] = " ;
cin >> b [ i ];
}
cout << endl << endl ;
/*
A módszer előrehaladása, ahol:
a[n][n] - Együtthatók mátrixa
x[n], p[n] - Jelenlegi és korábbi megoldások
b[n] - Jobb oldali részek oszlopa
A fenti tömbök mindegyike valós és
meg kell határozni a főprogramban,
az x[n] tömbbe is be kell tenni a kezdőbetűt
megoldás oszlop közelítése (pl. minden nulla)
*/
for ( int i = 0 ; i < n ; i ++ )
x [ i ] = 1 ;
cout << "Diagonális dominancia: " << endl ;
if ( átlós ( a , n )) {
csináld
{
for ( int i = 0 ; i < n ; i ++ )
p [ i ] = x [ i ];
for ( int i = 0 ; i < n ; i ++ )
{
double var = 0 ;
for ( int j = 0 ; j < n ; j ++ )
if ( j != i ) var += ( a [ i ][ j ] * x [ j ]);
x [ i ] = ( b [ i ] - var ) / a [ i ][ i ];
}
m ++ ;
} while ( ! konverge ( x , p , n , eps ));
cout << "Rendszerdöntés:" << endl << endl ;
for ( i = 0 ; i < n ; i ++ ) cout << "x" << i << " = " << okr ( x [ i ], eps ) << "" << endl ;
cout << "Iterációk: " << m << endl ;
}
else {
cout << "Nincs átlós dominancia" << endl ;
}
system ( "szünet" );
return 0 ;
}
Megvalósítási példa Pythonban
import numpy mint np
def seidel ( A , b , eps ):
n = len ( A )
x = np . nullák ( n ) # nulla vektor
converge = Hamis
, miközben nem konvergál :
x_new = np . másolás ( x )
i - re az ( n tartományban ): s1 = összeg ( A [ i ][ j ] * x_új [ j ] j esetén az ( i ) tartományban ) s2 = összeg ( A [ i ][ j ] * x [ j ] j esetén az ( i + 1 , n ) tartományban ) x_új [ i ] = ( b [ i ] - s1 - s2 ) / A [ i ][ i ]
konvergál = np . sqrt ( összeg (( x_új [ i ] - x [ i ]) ** 2 for i tartományban ( n ))) < = eps x = x_new
vissza x
Lásd még
Jegyzetek
Linkek
Az SLAE megoldásának módszerei |
---|
Közvetlen módszerek |
|
---|
Iteratív módszerek |
|
---|
Tábornok |
|
---|