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

C++로 행렬의 행렬식(Determinant) 계산하기

행렬식(Determinant)이란?

정사각 행렬의 행렬식은 행렬을 구성하는 원소 값들을 이용해 계산할 수 있는 스칼라 값입니다. 행렬 A의 행렬식은 보통 det(A)로 표기하며, 기하학적으로는 해당 행렬이 나타내는 선형 변환에서 길이·넓이·부피가 늘어나거나 줄어드는 배율, 즉 스케일링 인자(scaling factor)라고도 불립니다.

간단한 2×2 행렬의 행렬식 계산 예는 다음과 같습니다.

행렬:
3 1
2 7
행렬식 = 7×3 − 2×1
= 21 − 2
= 19
따라서 행렬식은 19입니다.

행렬식 계산 C++ 프로그램

다음은 사용자로부터 행렬의 크기와 원소를 입력받아 행렬식을 계산하는 C++ 프로그램입니다. 행렬식은 재귀 호출과 여인수 전개(cofactor expansion) 방식으로 구현되었습니다.

예제 코드

#include<iostream>
#include<math.h>
using namespace std;
int determinant( int matrix[10][10], int n) {
    int det = 0;
    int submatrix[10][10];
    if (n == 2)
    return ((matrix[0][0] * matrix[1][1]) - (matrix[1][0] * matrix[0][1]));
    else {
        for (int x = 0; x < n; x++) {
            int subi = 0;
            for (int i = 1; i < n; i++) {
                int subj = 0;
                for (int j = 0; j < n; j++) {
                    if (j == x)
                    continue;
                    submatrix[subi][subj] = matrix[i][j];
                    subj++;
                }
                subi++;
            }
            det = det + (pow(-1, x) * matrix[0][x] * determinant( submatrix, n - 1 ));
        }
    }
    return det;
}
int main() {
    int n, i, j;
    int matrix[10][10];
    cout << "Enter the size of the matrix:\n";
    cin >> n;
    cout << "Enter the elements of the matrix:\n";
    for (i = 0; i < n; i++)
    for (j = 0; j < n; j++)
    cin >> matrix[i][j];
    cout<<"The entered matrix is:"<<endl;
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++)
        cout << matrix[i][j] <<" ";
        cout<<endl;
    }
    cout<<"Determinant of the matrix is "<< determinant(matrix, n);
    return 0;
}

실행 결과

Enter the size of the matrix: 3
Enter the elements of the matrix:
7 1 3
2 4 1
1 5 1
The entered matrix is:
7 1 3
2 4 1
1 5 1
Determinant of the matrix is 10

코드 상세 설명

main() 함수: 먼저 행렬의 크기 n과 각 원소를 차례로 입력받고, 입력된 행렬을 화면에 출력한 뒤 determinant() 함수를 호출해 그 결과값을 출력합니다. 해당 과정은 아래 코드에서 확인할 수 있습니다.

cout << "Enter the size of the matrix:\n";
cin >> n;
cout <<"Enter the elements of the matrix:\n";
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
cin >> matrix[i][j];
cout<<"The entered matrix is:"<<endl;
for (i = 0; i < n; i++) {
    for (j = 0; j < n; j++)
    cout << matrix[i][j] <<" ";
    cout<<endl;
}
cout<<"Determinant of the matrix is "<< determinant(matrix, n);

기저 사례(2×2 행렬): determinant() 함수 내부에서 행렬의 크기가 2라면, ad − bc 공식을 적용해 행렬식을 즉시 계산하여 반환합니다.

if (n == 2)
return ((matrix[0][0] * matrix[1][1]) - (matrix[1][0] * matrix[0][1]));

재귀적 계산: 행렬의 크기가 2가 아니라면 첫 번째 행을 기준으로 여인수 전개를 수행합니다. 세 개의 중첩된 for 루프(루프 변수 x, i, j)를 사용해 각 열에 대응하는 소행렬(submatrix)을 만들고, determinant() 함수를 재귀적으로 호출하여 소행렬의 행렬식을 구한 후 부호 항 (-1)x와 원소 값을 곱해 누적합니다. 이 과정은 다음 코드로 구현됩니다.

for (int x = 0; x < n; x++) {
    int subi = 0;
    for (int i = 1; i < n; i++) {
        int subj = 0;
        for (int j = 0; j < n; j++) {
            if (j == x)
            continue;
            submatrix[subi][subj] = matrix[i][j];
            subj++;
        }
        subi++;
    }
    det = det + (pow(-1, x) * matrix[0][x] * determinant( submatrix, n - 1 ));
}

이 재귀 방식은 구조가 직관적이라 이해하기 쉽다는 장점이 있지만, 재귀 호출이 기하급수적으로 늘어나 시간 복잡도가 O(n!)에 달합니다. 따라서 차수가 큰 행렬을 다룰 때는 LU 분해나 가우스 소거법처럼 O(n³)에 처리 가능한 알고리즘을 사용하는 것이 효율적입니다.