C言語は1つの行列の逆行列を求めます(部分の主元のガウスは法を消します)
1、問題の由来
最近,ネットワークセキュリティを研究する過程でhill暗号が研究され,この暗号化体制では行列の逆行列が用いられている.ネットワークリソースを検索することによって,一部のメタのGauss消去法を用いて逆行列を解くアルゴリズムを見つけ,皆さんに共有した.
2、アルゴリズム実現
3、アルゴリズムケース
アルゴリズムの利用このアルゴリズムの例は次のhillパスワードを見てください
最近,ネットワークセキュリティを研究する過程でhill暗号が研究され,この暗号化体制では行列の逆行列が用いられている.ネットワークリソースを検索することによって,一部のメタのGauss消去法を用いて逆行列を解くアルゴリズムを見つけ,皆さんに共有した.
2、アルゴリズム実現
//********************************
//*** ***
//********************************
#include
#include
#include
#include
using namespace std;
#define N 10 // 10
//
float MatDet(float *p, int n); //
float Creat_M(float *p, int m, int n, int k); // A(m, n)
void print(float *p, int n); // n*n
bool Gauss(float A[][N], float B[][N], int n); // A B
int main()
{
float a[N][N], b[N][N];
int i,j,n;
cout << " !
";
cout << " : ";
cin >> n;
cout << " " << n << " :
";
// n
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
cin >> a[i][j];
}
}
//
if (Gauss(a, b, n))
{
cout << " :
";
for (i = 0; i < n; i++)
{
cout << setw(4);
for (j = 0; j < n; j++)
{
cout << b[i][j] << setw(10);
}
cout << endl;
}
}
system("PAUSE");
return 0;
}
//-----------------------------------------------
// : (n*n)
// : ,
// :
//----------------------------------------------
float MatDet(float *p, int n)
{
int r, c, m;
int lop = 0;
float result = 0;
float mid = 1;
if (n != 1)
{
lop = (n == 2) ? 1 : n; // , 2 , 1 , n
for (m = 0; m < lop; m++)
{
mid = 1; // ,
for (r = 0, c = m; r < n; r++, c++)
{
mid = mid * (*(p + r*n + c%n));
}
result += mid;
}
for (m = 0; m < lop; m++)
{
mid = 1; // ,
for (r = 0, c = n - 1 - m + n; r < n; r++, c--)
{
mid = mid * (*(p + r*n + c%n));
}
result -= mid;
}
}
else
result = *p;
return result;
}
//----------------------------------------------------------------------------
// : k*k A(m, n)
// : k*k , A m,n, k
// : k*k A(m, n)
//----------------------------------------------------------------------------
float Creat_M(float *p, int m, int n, int k)
{
int len;
int i, j;
float mid_result = 0;
int sign = 1;
float *p_creat, *p_mid;
len = (k - 1)*(k - 1); //k k-1
p_creat = (float*)calloc(len, sizeof(float)); //
p_mid = p_creat;
for (i = 0; i < k; i++)
{
for (j = 0; j < k; j++)
{
if (i != m && j != n) // i j p_mid
{
*p_mid++ = *(p + i*k + j);
}
}
}
sign = (m + n) % 2 == 0 ? 1 : -1; // 、
mid_result = (float)sign*MatDet(p_creat, k - 1);
free(p_creat);
return mid_result;
}
//-----------------------------------------------------
// : n*n
// : n*n , n
// :
//-----------------------------------------------------
void print(float *p, int n)
{
int i, j;
for (i = 0; i < n; i++)
{
cout << setw(4);
for (j = 0; j < n; j++)
{
cout << setiosflags(ios::right) << *p++ << setw(10);
}
cout << endl;
}
}
//------------------------------------------------------------------
// : A B
// : , ,
// : true or false
//-------------------------------------------------------------------
bool Gauss(float A[][N], float B[][N], int n)
{
int i, j, k;
float max, temp;
float t[N][N]; //
// A t[n][n]
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
t[i][j] = A[i][j];
}
}
// B
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
B[i][j] = (i == j) ? (float)1 : 0;
}
}
for (i = 0; i < n; i++)
{
//
max = t[i][i];
k = i;
for (j = i + 1; j < n; j++)
{
if (fabs(t[j][i]) > fabs(max))
{
max = t[j][i];
k = j;
}
}
// i ,
if (k != i)
{
for (j = 0; j < n; j++)
{
temp = t[i][j];
t[i][j] = t[k][j];
t[k][j] = temp;
//B
temp = B[i][j];
B[i][j] = B[k][j];
B[k][j] = temp;
}
}
// 0, , A ,
if (t[i][i] == 0)
{
cout << "There is no inverse matrix!";
return false;
}
// A i i
temp = t[i][i];
for (j = 0; j < n; j++)
{
t[i][j] = t[i][j] / temp; // 1
B[i][j] = B[i][j] / temp; //
}
for (j = 0; j < n; j++) // 0 -> n
{
if (j != i) // i
{
temp = t[j][i];
for (k = 0; k < n; k++) // j - i *j i
{
t[j][k] = t[j][k] - t[i][k] * temp;
B[j][k] = B[j][k] - B[i][k] * temp;
}
}
}
}
return true;
}
3、アルゴリズムケース
アルゴリズムの利用このアルゴリズムの例は次のhillパスワードを見てください