C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++で行列が可逆(正則)かどうかを判定するプログラムの書き方

行列が可逆(逆行列を持つ)かどうかは、行列式を求めることで判定できます。行列式が0以外であれば、その行列は可逆です。逆に、行列式が0になった場合は、行列は可逆ではありません。

例を見てみましょう。

与えられた行列:

4 2 1
2 1 1
9 3 2

この行列の行列式:3
したがって、この行列は可逆です。

可逆性を判定するプログラム例

以下は、行列が可逆かどうかを判定するC++プログラムの完全なコードです。

#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, d, 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;
    }
    d = determinant(matrix, n);
    cout<<"Determinant of the matrix is "<< d <<endl;
    if( d == 0 )
    cout<<"This matrix is not invertible as the determinant is zero";
    else
    cout<<"This matrix is invertible as the determinant is not zero";
    return 0;
}

実行結果

Enter the size of the matrix: 3
Enter the elements of the matrix:
1 2 3
2 1 2
1 1 4
The entered matrix is:
1 2 3
2 1 2
1 1 4
Determinant of the matrix is -7
This matrix is invertible as the determinant is not zero

プログラムの解説

main()関数での処理

このプログラムでは、まずmain()関数内で行列のサイズと各要素を入力として受け取ります。次にdeterminant()関数を呼び出し、戻り値である行列式を変数dに格納します。行列式が0であれば行列は可逆ではなく、0でなければ可逆であると判定されます。該当するコード部分は以下のとおりです。

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;
}
d = determinant(matrix, n);
cout<<"Determinant of the matrix is "<< d <<endl;
if( d == 0 )
cout<<"This matrix is not invertible as the determinant is zero";
else
cout<<"This matrix is invertible as the determinant is not zero";

2×2行列の場合:直接計算

determinant()関数では、行列のサイズが2の場合、行列式を直接計算してその値を返します。具体的には、主対角成分の積から反対対角成分の積を引くという公式を使います。

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

3×3以上の場合:再帰的に計算

行列のサイズが2でない場合、行列式は再帰的(recursive)に計算されます。ループ変数xijを使った3重のforループにより、余因子展開のための小行列(部分行列)を作成します。そしてdeterminant()関数を再帰的に呼び出して内部の行列式を求め、それを外側の係数と掛け合わせて合計します。これが余因子展開(ラプラス展開)による行列式の計算方法です。該当するコード部分は以下のとおりです。

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 ));
}

まとめ

このように、行列式を再帰的に計算することで、任意のサイズの正方行列が可逆かどうかを簡単に判定できます。行列式が0なら不可逆(特異行列)、0以外なら可逆(正則行列)であり、逆行列が存在します。計算量はO(n!)と大きいため大きな行列には不向きですが、小規模な行列の学習や検証には非常に有効な手法です。

  1. C++でべき等行列を判定するプログラムの作成方法

    行数を r、列数を c とする行列 M[r][c] が与えられ、r = c となる正方行列を考えます。この記事では、与えられた正方行列がべき等行列(アイデンポテント行列)であるかどうかを判定するC++プログラムを解説します。 べき等行列とは 行列 M がべき等行列であるとは、行列 M と自分自身の積が元の行列 M と等しくなること、すなわち M × M = M が成り立つことを指します。 例えば、次の行列を見てください。 この行列を自分自身で掛け合わせても、結果は元の行列とまったく同じになります。したがって、この行列はべき等行列であると言えます。 べき等行列の代表的な例としては、ベクトルを

  2. C++でグラフの隣接行列を実装する方法【サンプルコード付き解説】

    隣接行列とは グラフの隣接行列(Adjacency Matrix)とは、V×Vのサイズを持つ正方行列のことです。ここでVはグラフGの頂点数を表します。行列の行と列にはそれぞれ頂点が対応付けられ、頂点iから頂点jへの辺が存在する場合は、i行目・j列目の要素に1が格納されます(重み付きグラフの場合は、辺の重みなどの非ゼロの値が入ります)。辺が存在しない場合は0が格納されます。 なお、無向グラフの場合、辺は双方向につながりを持つため、隣接行列は必ず対称行列になります。つまり、adj[i][j]とadj[j][i]は常に同じ値となります。 隣接行列表現の計算量 空間計算量: 隣接行列にはO(V²)