C++でガウスのジョーダン法を使用して行列の逆行列を見つける
この問題では、2D行列mat[][]が与えられます。私たちのタスクは、ガウスのジョーダン法を使用して行列の逆行列を見つけることです。 。
それでは、問題の基本を理解しましょう。
マトリックス は数値の2次元配列です。
例
$ \ begin {bmatrix} 2&5&4 \\ 1&6&7 \\ 9&3&8 \ end {bmatrix} $
逆行列[A-1] −
正方行列に対して実行される操作です。以下は、行列が逆行列を持つために必要なプロパティです-
-
初期行列は正方行列である必要があります。
-
正則行列でなければなりません。
-
行列Aに対して、次のような単位行列Iが存在します。
$$ AA ^ {-1} =A ^ {-1} .A =I $$
それらは、与えられた行列の逆行列を見つけるために使用できる式です。
です$ A ^ {-1} \:=\:\ left(\ frac {adj(A)} {\ det(A)} \ right)$
adj(A)は行列Aの随伴作用素
det(A)は行列式Aの行列式です。
それらは、行列の逆行列を見つけるために使用する複数の方法です。この記事では、ガウスの消去法について学習します。 これは、 Elementary Row Opeationとも呼ばれます。 。
行列の逆行列を見つけるのは段階的な方法です。関連する手順は次のとおりです-
-
単位行列を使用して拡大行列を見つける。
-
手順1で見つけた拡大行列に対して行階段形を実行して、行列の階段形を見つけます。
-
プロセスで拡大行列に対して実行できる操作は次のとおりです
-
行の交換 (任意の2行を交換できます)
-
掛け算 (行の各要素には、0以外の定数値を掛けることができます。)
-
行交換(行を行の合計と行列の別の行の定数倍に置き換えます)。
-
例
ソリューションの動作を説明するプログラム
#include <iostream> #include <vector> using namespace std; void printMatrixValues(float** arr, int n, int m){ for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cout<<arr[i][j]<<"\t"; } cout<<endl; } return; } void printInverseMatrix(float** arr, int n, int m){ for (int i = 0; i < n; i++) { for (int j = n; j < m; j++) { printf("%.3f\t", arr[i][j]); } cout<<endl; } return; } void findInvMatGaussJordan(float** mat, int order){ float temp; printf("The inverse of matrix : A = \n"); printMatrixValues(mat, order, order); for (int i = 0; i < order; i++) { for (int j = 0; j < 2 * order; j++) { if (j == (i + order)) mat[i][j] = 1; } } for (int i = order - 1; i > 0; i--) { if (mat[i - 1][0] < mat[i][0]) { float* temp = mat[i]; mat[i] = mat[i - 1]; mat[i - 1] = temp; } } for (int i = 0; i < order; i++) { for (int j = 0; j < order; j++) { if (j != i) { temp = mat[j][i] / mat[i][i]; for (int k = 0; k < 2 * order; k++) { mat[j][k] -= mat[i][k] * temp; } } } } for (int i = 0; i < order; i++) { temp = mat[i][i]; for (int j = 0; j < 2 * order; j++) { mat[i][j] = mat[i][j] / temp; } } cout<<"A' =\n"; printInverseMatrix(mat, order, 2 * order); return; } int main(){ int order = 3; float** mat = new float*[20]; for (int i = 0; i < 20; i++) mat[i] = new float[20]; mat[0][0] = 6; mat[0][1] = 9; mat[0][2] = 5; mat[1][0] = 8; mat[1][1] = 3; mat[1][2] = 2; mat[2][0] = 1; mat[2][1] = 4; mat[2][2] = 7; findInvMatGaussJordan(mat, order); return 0; }
出力
The inverse of matrix : A = 6 9 5 8 3 2 1 4 7 A' = -0.049 0.163 -0.011 0.205 -0.141 -0.106 -0.110 0.057 0.205
-
接続行列を使用してグラフを表現するC++プログラム
グラフの接続行列は、メモリに保存するグラフの別の表現です。この行列は正方行列ではありません。接続行列の次数はVxEです。ここで、Vは頂点の数、Eはグラフのエッジの数です。 この行列の各行に頂点を配置し、各列にエッジを配置します。エッジe{u、v}のこの表現では、列eの場所uとvに対して1でマークされます。 隣接行列表現の複雑さ 接続行列表現は、計算中にO(Vx E)のスペースを取ります。完全グラフの場合、エッジの数はV(V-1)/2になります。したがって、接続行列はメモリ内でより大きなスペースを取ります。 入力 出力 E0 E1 E2
-
隣接行列を使用してグラフを表現するC++プログラム
グラフの隣接行列は、サイズV x Vの正方行列です。Vは、グラフGの頂点の数です。この行列では、各辺にV個の頂点がマークされています。グラフにiからjの頂点までのエッジがある場合、i thの隣接行列に 行とjth 列は1(または加重グラフの場合はゼロ以外の値)になります。それ以外の場合、その場所は0を保持します。 隣接行列表現の複雑さ 隣接行列表現はO(V 2 )計算中のスペースの量。グラフに最大数のエッジと最小数のエッジがある場合、どちらの場合も必要なスペースは同じになります。 入力 出力 0 1 2 3 4 5