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

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

  1. 接続行列を使用してグラフを表現するC++プログラム

    グラフの接続行列は、メモリに保存するグラフの別の表現です。この行列は正方行列ではありません。接続行列の次数はVxEです。ここで、Vは頂点の数、Eはグラフのエッジの数です。 この行列の各行に頂点を配置し、各列にエッジを配置します。エッジe{u、v}のこの表現では、列eの場所uとvに対して1でマークされます。 隣接行列表現の複雑さ 接続行列表現は、計算中にO(Vx E)のスペースを取ります。完全グラフの場合、エッジの数はV(V-1)/2になります。したがって、接続行列はメモリ内でより大きなスペースを取ります。 入力 出力 E0 E1 E2

  2. 隣接行列を使用してグラフを表現するC++プログラム

    グラフの隣接行列は、サイズV x Vの正方行列です。Vは、グラフGの頂点の数です。この行列では、各辺にV個の頂点がマークされています。グラフにiからjの頂点までのエッジがある場合、i thの隣接行列に 行とjth 列は1(または加重グラフの場合はゼロ以外の値)になります。それ以外の場合、その場所は0を保持します。 隣接行列表現の複雑さ 隣接行列表現はO(V 2 )計算中のスペースの量。グラフに最大数のエッジと最小数のエッジがある場合、どちらの場合も必要なスペースは同じになります。 入力 出力 0 1 2 3 4 5