Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++로 구현하는 가우스-자이델(Gauss-Seidel) 방법


가우스-자이델(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

코드 동작 설명

위 프로그램은 다음 순서로 동작합니다.

  1. 사용자로부터 행렬의 크기 p를 입력받습니다.
  2. 계수 행렬 a, 방정식 우변 벡터 b, 미지수 x의 초기값 m을 차례로 입력받습니다.
  3. 지정된 반복 횟수 q만큼 루프를 돌며 각 변수의 새로운 근사값을 계산하고 화면에 출력합니다.
  4. 내부 루프에서 j == i(대각 성분)인 경우는 건너뛰고, 나머지 항들만 이용해 n[i]를 갱신한 뒤 곧바로 m[i]에 반영합니다. 이것이 가우스-자이델 방법의 핵심입니다.

실행 결과를 보면 반복이 진행될 때마다 x1, x2의 근사값이 갱신되어 출력되는 것을 확인할 수 있으며, 반복 횟수를 충분히 늘리면 실제 해에 가까워집니다.