가우스-자이델(Gauss-Seidel) 방법은 연립 선형 방정식을 반복법으로 풀 때 널리 사용되는 수치 해석 기법입니다. 이 글에서는 가우스-자이델 방법을 구현한 C++ 프로그램을 알고리즘, 코드, 실행 결과 순으로 살펴봅니다.
가우스-자이델 방법 개요
가우스-자이델 방법은 야코비(Jacobi) 반복법과 비슷하지만 한 가지 중요한 차이가 있습니다. 바로 각 반복 단계에서 새로 계산된 변수 값을 즉시 다음 변수의 계산에 활용한다는 점입니다. 덕분에 일반적으로 야코비 방법보다 더 빠르게 수렴하는 경향이 있습니다.
다만 이 방법이 항상 수렴하는 것은 아닙니다. 계수 행렬이 대각 우세(diagonally dominant)하거나, 대칭이면서 양의 정부호(positive definite)일 때 수렴이 보장됩니다.
알고리즘
Begin
행렬의 차원 p와 행렬의 요소들을 입력받는다.
x의 초기값과 반복 횟수 q를 입력받는다.
While q > 0
for 루프: i = 0 ~ p-1
n[i] = (b[i] / a[i][i]) 로 초기화
for 루프: j = 0 ~ p-1
if (j == i)
continue
n[i] = n[i] - ((a[i][j] / a[i][i]) * m[j])
m[i] = n[i]
q를 1 감소시킨다.
/*
여기서,
a[i][j] : 입력 행렬(계수 행렬)
b[i] : 방정식 우변의 값 배열
m[i] : x의 초기값 저장 배열
*/
Return 0
End
C++ 구현 예제
#include<iostream>
#include<conio.h>
using namespace std;
int main(void) {
float a[10][10], b[10], m[10], n[10];
int p = 0, q = 0, i = 0, j = 0;
cout << "Enter size of 2D array : ";
cin >> p;
for (i = 0; i < p; i++) {
for (j = 0; j < p; j++) {
cout << "a[" << i << ", " << j << " ]=";
cin >> a[i][j];
}
}
cout << "\nEnter values to the right side of equation\n";
for (i = 0; i < p; i++) {
cout << "b[" << i << ", " << j << " ]=";
cin >> b[i];
}
cout << "Enter initial values of x\n";
for (i = 0; i < p; i++) {
cout << "x:[" << i<<"]=";
cin >> m[i];
}
cout << "\nEnter the no. of iteration : ";
cin >> q;
while (q> 0) {
for (i = 0; i < p; i++) {
n[i] = (b[i] / a[i][i]);
for (j = 0; j < p; j++) {
if (j == i)
continue;
n[i] = n[i] - ((a[i][j] / a[i][i]) * m[j]);
m[i] = n[i];
}
cout<<"x"<<i + 1 << "="<<n[i]<<" ";
}
cout << "\n";
q--;
}
return 0;
}
실행 결과
Enter size of 2D array : 2 a[0, 0 ]=1 a[0, 1 ]=2 a[1, 0 ]=3 a[1, 1 ]=4 Enter values to the right side of equation b[0, 2 ]=1 b[1, 2 ]=2 Enter initial values of x x:[0]=0 x:[1]=0 Enter the no. of iteration : 3 x1 = 1. x2 = -0.25 x1 = 1.5 x2 = -0.625 x1 = 2.25 x2 = -1.1875
코드 동작 설명
위 프로그램은 다음 순서로 동작합니다.
- 사용자로부터 행렬의 크기 p를 입력받습니다.
- 계수 행렬 a, 방정식 우변 벡터 b, 미지수 x의 초기값 m을 차례로 입력받습니다.
- 지정된 반복 횟수 q만큼 루프를 돌며 각 변수의 새로운 근사값을 계산하고 화면에 출력합니다.
- 내부 루프에서
j == i(대각 성분)인 경우는 건너뛰고, 나머지 항들만 이용해n[i]를 갱신한 뒤 곧바로m[i]에 반영합니다. 이것이 가우스-자이델 방법의 핵심입니다.
실행 결과를 보면 반복이 진행될 때마다 x1, x2의 근사값이 갱신되어 출력되는 것을 확인할 수 있으며, 반복 횟수를 충분히 늘리면 실제 해에 가까워집니다.