您的位置:首页 > 其它

稀疏矩阵的加减法、乘法、求逆运算

2015-01-15 20:24 274 查看
(项目需要,借此学习,感谢!转自:http://jgzhen125.blog.163.com/blog/static/44508644201010169277572/

#include <iostream>

#include <iomanip>

using namespace std;

const int MAXSIZE = 100; //定义非零元素的最多个数

const int MAXROW = 10; //定义数组行数的最大值

const int SIZENUM = 10;

typedef struct //定义三元组元素

{

int r, c; //矩阵的行号和列号

int v; //矩阵元素值

}Triple;

typedef struct //定义普通三元组对象

{

Triple data[MAXSIZE+1];

int rows, cols, nzeroNums; //行数、列数、非零元素个数

}TSMatrix;

typedef struct //定义行逻辑链接的顺序表

{

Triple data[MAXSIZE+2]; //非0元三元组表

int rpos[MAXROW+1]; //各行第一个非零元素的位置表

int rows, cols, nzeroNums; //行数、列数、非零元素个数

}RLSMatrix;

//输入三元组矩阵

template <class T>

bool InputTSMatrix(T &M, int y)

{

cout << "输入矩阵的行数、列数和非零元素个数: ";

cin >> M.rows >> M.cols >> M.nzeroNums;

cout << "请输入非零元素对应的行号、列号和相应的元素值: " << endl;

for (int i = 1; i <= M.nzeroNums; i++)

{

cin >> M.data[i].r >> M.data[i].c >> M.data[i].v;

}

return true;

}

//输出矩阵,按标准格式输出

template <class T>

bool OutputSMatrix(T M)

{

int i, j, k = 1;

for (i = 0; i < M.rows; i++)

{

for (j = 0; j < M.cols; j++)

{

if ((M.data[k].r-1) == i && (M.data[k].c-1) == j)

{

cout << setw(4) << M.data[k].v;

k++;

}

else

cout << setw(4) << "0";

}//end_j

cout << endl;

}//end_i

return true;

}

//求稀疏矩阵的转置

int TranSMatrix()

{

TSMatrix M, T;

InputTSMatrix(M, 0);

int col, p, q = 1;

T.rows = M.cols;

T.cols = M.rows;

T.nzeroNums = M.nzeroNums;

if (T.nzeroNums)

{

for (col = 1; col <= M.cols; col++)

{

for (p = 1; p <= M.nzeroNums; p++)

{

if (M.data[p].c == col)

{

T.data[q].r = M.data[p].c;

T.data[q].c = M.data[p].r;

T.data[q].v = M.data[p].v;

++q;

}

}//end_p

}//end_col

}//end_if

cout << "运用普通转置算法, 输入矩阵的转置矩阵为: " << endl;

OutputSMatrix(T);

return 1;

}

//稀疏矩阵的快速转置

int FastTranMat()

{

TSMatrix M, T;

int num[MAXROW+1]; //表示矩阵M中第col列非零元素的个数

int cpot[MAXROW+1]; //表示矩阵M中第col列第一个非0元素在b.data中的位置

int p, q, col, t;

InputTSMatrix(M, 0); //输入稀疏矩阵

T.rows = M.cols;

T.cols = M.rows;

T.nzeroNums = M.nzeroNums;

if (T.nzeroNums)

{

for (col = 1; col <= M.cols; col++)//M中各列元素初始化

{

num[col] = 0;

}

for (t = 1; t <= M.nzeroNums; t++)

{

++num[M.data[t].c]; //求M中每一列非零元个数

}

//求第col列第一个非零元在b.data中的序号

cpot[1] = 1;

for (col = 2; col <= M.cols; col++)

{

cpot[col] = cpot[col-1] + num[col-1];

}

for (p = 1; p <= M.nzeroNums; p++)

{

col = M.data[p].c; //稀疏矩阵M中每个元素对应的列号

q = cpot[col]; //稀疏矩阵M中第一个非零元素位置

T.data[q].r = M.data[p].c;

T.data[q].c = M.data[p].r;

T.data[q].v = M.data[p].v;

++cpot[col];

}//end_for

}//end_if

cout << "运用快速算法,输入矩阵的转置为: " << endl;

OutputSMatrix(T);

return 1;

}

//求取稀疏矩阵每一行非零元个数

bool Count(RLSMatrix &M)

{

int row, p;

int num[MAXROW+1];

for (row = 1; row <= M.rows; row++)

{

num[row] = 0; //清零

}

for (p = 1; p <= M.nzeroNums; p++)

{

++num[M.data[p].r]; //统计M每一行非零元个数

}

M.rpos[1] = 1;

//M中每一行非零元的起始位置

for (row = 2; row <= M.rows; row++)

{

M.rpos[row] = M.rpos[row-1] + num[row-1];

}

return true;

}

//两个稀疏矩阵的乘法

bool MultSMatrix()

{

RLSMatrix M, N, Q; //构建三个带链接信息的三元组表示的数组

InputTSMatrix(M, 1); //用普通三元组形式输入数组

InputTSMatrix(N, 1);

Count(M);

Count(N);

if (M.cols != N.rows)

{

cout << "Error!";

return false;

}

//Q的初始化

Q.rows = M.rows;

Q.cols = N.cols;

Q.nzeroNums = 0;

int mrow, nrow, p, q, t, tp, qcol;

int ctemp[MAXROW+1]; //辅助数组

//如果Q是非零矩阵

if (M.nzeroNums * N.nzeroNums)

{

for (mrow = 1; mrow <= M.rows; mrow++)

{

//当前行各元素累加器清零

for (int x = 1; x <= N.cols; x++)

{

ctemp[x] = 0;

}//end_x

//当前行的首个非零元素在三元组中的位置为此行前所有非0元素加1

Q.rpos[mrow] = Q.nzeroNums + 1;

if (mrow < M.rows)

{

tp = M.rpos[mrow+1];

}

else

tp = M.nzeroNums + 1;

for (p = M.rpos[mrow]; p < tp; p++) //对当前行的每个非零元素操作

{

nrow = M.data[p].c; //在N中找到与M操作元素的c值相等的行值r

if (nrow < N.rows)

{

t = N.rpos[nrow+1];

}

else

t = N.nzeroNums + 1;

//对找出的行的每个非零元素进行操作

for (q = N.rpos[nrow]; q < t; q++)

{

qcol = N.data[q].c;

//将乘得到的对应值放在相应元素的累加器里面

ctemp[qcol] += M.data[p].v * N.data[q].v;

}

}//p_end_for

//对已经求出的累加器中的值压缩到Q中

for (qcol = 1; qcol <= Q.cols; qcol++)

{

if (ctemp[qcol])

{

if (++Q.nzeroNums > MAXSIZE)

{

cout << "Error!" << endl;

return 0;

}

Q.data[Q.nzeroNums].r = mrow;

Q.data[Q.nzeroNums].c = qcol;

Q.data[Q.nzeroNums].v = ctemp[qcol];

}

}//qcol_end_for

}//arow_end_for

}//end_if

cout << "两个稀疏矩阵相乘的结果为:\n";

OutputSMatrix(Q);

return 1;

}

//两个稀疏矩阵的加法

int AddMatrix()

{

TSMatrix A, B, C;

int i = 1, j = 1, k = 1; //i, j, k分别用以保存A、B、C非零元素个数

int value = 0;

InputTSMatrix(A, 0);

InputTSMatrix(B, 0);

if (A.rows != B.rows || A.cols != B.cols)

{

cout << "两个稀疏矩阵的大小不等,不能相加!" << endl;

return 0;

}

if (A.rows == B.rows && A.cols == B.cols)

{

while (i <= A.nzeroNums && j <= B.nzeroNums)

{

if (A.data[i].r == B.data[j].r)

{

if (A.data[i].c < B.data[j].c)

{

C.data[k].r = A.data[i].r;

C.data[k].c = A.data[i].c;

C.data[k].v = A.data[i].v;

k++;

i++;

}

else if (A.data[i].c > B.data[j].c)

{

C.data[k].r = B.data[j].r;

C.data[k].c = B.data[j].c;

C.data[k].v = B.data[j].v;

k++;

j++;

}

else

{

value = A.data[i].v + B.data[j].v;

if (value != 0)

{

C.data[k].r = A.data[i].r;

C.data[k].c = A.data[i].c;

C.data[k].v = value;

k++;

}

i++;

j++;

}

}//end_if

else if (A.data[i].r < B.data[j].r)

{

C.data[k].r = A.data[i].r;

C.data[k].c = A.data[i].c;

C.data[k].v = A.data[i].v;

k++;

i++;

}

else

{

C.data[k].r = B.data[j].r;

C.data[k].c = B.data[j].c;

C.data[k].v = B.data[j].v;

k++;

j++;

}

//把剩余部分元素存入C中

if (i > A.nzeroNums && j <= B.nzeroNums)

{

for (; j <= B.nzeroNums; j++)

{

C.data[k].r = B.data[j].r;

C.data[k].c = B.data[j].c;

C.data[k].v = B.data[j].v;

k++;

}

}

if (i <= A.nzeroNums && j > B.nzeroNums)

{

for (; i <= A.nzeroNums; i++)

{

C.data[k].r = A.data[i].r;

C.data[k].c = A.data[i].c;

C.data[k].v = A.data[i].v;

k++;

}

}

}//end_while

C.rows = A.rows;

C.cols = A.cols;

C.nzeroNums = k-1;

cout << "输出两个稀疏矩阵的和: " << endl;

OutputSMatrix(C);

return 1;

}//end_if

else

return 0;

}

//两个稀疏矩阵的减法

int SubMatrix()

{

TSMatrix A, B, C;

int m = 1, n = 1, k = 1, temp;

InputTSMatrix(A, 0);

InputTSMatrix(B, 0);

C.rows = A.rows;

C.cols = A.cols;

C.nzeroNums = 0;

if (A.rows == B.rows && A.cols == B.cols)

{

while (m <= A.nzeroNums && n <= B.nzeroNums)

{

if (A.data[m].r == B.data
.r)

{

if (A.data[m].c == B.data
.c)

{

temp = A.data[m].v - B.data
.v;

if (temp != 0)

{

C.data[k].r = A.data[m].r;

C.data[k].c = A.data[m].c;

C.data[k].v = temp;

k++;

}

m++;

n++;

}

else if (A.data[m].c < B.data
.c)

{

C.data[k].r = A.data[m].r;

C.data[k].c = A.data[m].c;

C.data[k].v = A.data[m].v;

k++;

m++;

}

else

{

C.data[k].r = B.data
.r;

C.data[k].c = B.data
.c;

C.data[k].v = -B.data
.v;

k++;

n++;

}

}

else if (A.data[m].r < B.data
.r)

{

C.data[k].r = A.data[m].r;

C.data[k].c = A.data[m].c;;

C.data[k].v = A.data[m].v;

k++;

m++;

}

else

{

C.data[k].r = B.data
.r;

C.data[k].c = B.data
.c;

C.data[k].v = -B.data
.v;

k++;

n++;

}

}//end_while

if (m <= A.nzeroNums)

{

for (; m <= A.nzeroNums; m++)

{

C.data[k].r = A.data[m].r;

C.data[k].c = A.data[m].c;

C.data[k].v = A.data[m].v;

k++;

}

}

if (n <= B.nzeroNums)

{

for (; n <= B.nzeroNums; n++)

{

C.data[k].r = B.data
.r;

C.data[k].c = B.data
.c;

C.data[k].v = -B.data
.v;

k++;

}

}

C.nzeroNums = k-1;

cout << "两个稀疏矩阵的差为:\n";

OutputSMatrix(C);

return 1;

} //end_if

else

{

cout << "两个稀疏矩阵的大小不同,不能相减!\n";

return 0;

}

}

//得到矩阵元素M[i][j]的值

int value(TSMatrix M, int i, int j)

{

int k;

for (k = 1; k <= M.nzeroNums; k++)

{

if (M.data[k].r == i && M.data[k].c == j)

{

return M.data[k].v;

}

}

return 0;

}

//矩阵乘法的算法2

int MultMat()

{

TSMatrix A, B, C;

InputTSMatrix(A, 0);

InputTSMatrix(B, 0);

int i, j, k, temp = 0, p = 1;

if (A.cols != B.rows)

{

cout << "矩阵A的列数不等于矩阵B的行数不能相乘!\n";

return 0;

}

else

{

for (i = 1; i <= A.rows; i++)

{

for (j = 1; j <= B.cols; j++)

{

temp = 0;

for (k = 1; k <= A.cols; k++)

{

temp += value(A, i, k) * value(B, k, j);

}

if (temp != 0)

{

C.data[p].r = i;

C.data[p].c = j;

C.data[p].v = temp;

p++;

}

}

}

C.rows = A.rows;

C.cols = B.cols;

C.nzeroNums = p-1;

OutputSMatrix(C);

return 1;

}

}

//计算矩阵的行列式, 通过递归算法来实现

int JsMatrix(int s[][MAXROW], int n)

{

int i, j, k, r, total = 0;

int b[SIZENUM][SIZENUM]; //b

用于存放在矩阵s

中元素s[0]的余之式

if (n == 1)

{

total = s[0][0];

}

else if (n == 2)

{

total = s[0][0] * s[1][1] - s[0][1] * s[1][0];

}

else

{

for (i = 0; i < n; i++)

{

for (j = 0; j < n-1; j++)

{

for (k = 0; k < n-1; k++)

{

if (k >= i)

{

b[j][k] = s[j+1][k+1];

}

else

{

b[j][k] = s[j+1][k];

}

}//end_for_k

}//end_for_j

if (i % 2 == 0)

{

r = s[0][i] * JsMatrix(b, n-1); //递归调用

}

else

{

r = (-1) * s[0][i] * JsMatrix(b, n-1);

}

total += r;

}//end_for_i

}//end_else

return total;

}

//求原矩阵个元素对应的余之式, 存放在b

中,定义为float型

void N1Matrix(int s[][SIZENUM], float b[][SIZENUM], int n)

{

int i, j, k, l, m, g, a[SIZENUM][SIZENUM];

for (i = 0; i < n; i++)

{

m = i;

for (j = 0; j < n; j++)

{

g = j;

for (k = 0; k < n-1; k++)

{

for (l = 0; l < n-1; l++)

{

if (k >= m && l >= g)

{

a[k][l] = s[k+1][l+1];

}

else if (k < m && l >= g)

{

a[k][l] = s[k][l+1];

}

else if (k >= m && l < g)

{

a[k][l] = s[k+1][l];

}

else

{

a[k][l] = s[k][l];

}

}//end_for_l

}//end_for_k

b[i][j] = JsMatrix(a, n-1);

}//end_for_j

}//end_for_i

}

//稀疏矩阵求逆

void InverseMat()

{

TSMatrix M;

InputTSMatrix(M, 0);

int i, j, k, n = M.rows;

float temp;

int a[SIZENUM][SIZENUM];

float b[SIZENUM][SIZENUM], c[SIZENUM][SIZENUM];

for (i = 0; i < n; i++) //初始化矩阵a

{

for (j = 0; j < n; j++)

{

a[i][j] = 0;

}

}

for (i = 1; i <= M.nzeroNums; i++) //给矩阵a赋值

{

a[M.data[i].r-1][M.data[i].c-1] = M.data[i].v;

}

cout << "稀疏矩阵对应的普通矩阵为: \n";

for (i = 0; i < n; i++) //打印原矩阵

{

for (j = 0; j < n; j++)

{

cout << setw(4) << a[i][j] << setw(4);

}

cout << endl;

}

k = JsMatrix(a, n);

cout << "矩阵的行列式值: |A| = " << k << endl;

if (k == 0)

{

cout << "行列式的值为0, 原矩阵无逆矩阵!" << endl;

}

else

{

N1Matrix(a, b, n); //调用函数,得到原矩阵各元素对应的余之式存放在数组b



//求代数余之式

cout << "普通矩阵各元素对应的代数余之式矩阵为: \n";

for (i = 0; i < n; i++)

{

for (j = 0; j < n; j++)

{

if ((i+j)%2 != 0 && b[i][j] != 0)

{

b[i][j] = -b[i][j];

}

cout << setw(4) << b[i][j] << setw(4);

}

cout << endl;

}//end_for_i

//对b

转置,此时b

存放的为原矩阵的伴随矩阵

for (i = 0; i < n; i++)

{

for (j = i+1; j < n; j++)

{

temp = b[i][j];

b[i][j] = b[j][i];

b[j][i] = temp;

}

}

cout << "伴随矩阵A*: " << endl;

for (i = 0; i < n; i++) //打印伴随矩阵A*

{

for (j = 0; j < n; j++)

{

cout << setw(4) << b[i][j] << setw(4);

}

cout << endl;

}

for (i = 0; i < n; i++) //求逆矩阵,此时c

中存放的是原矩阵的逆矩阵

{

for (j = 0; j < n; j++)

{

c[i][j] = b[i][j]/k;

}

}

cout << "逆矩阵(A*)/|A|: " << endl;

for (i = 0; i < n; i++) //打印逆矩阵

{

for (j = 0; j < n; j++)

{

cout << setw(6) << c[i][j] << setw(6);

}

cout << endl;

}

}//end_else

}

int main()

{

char c;

cout << setw(50) << "******欢迎使用稀疏矩阵的相关操作!******" << endl << endl;

cout.fill('*');

cout << setw(20) << '*';

cout << "请选择要进行的操作";

cout << setw(20) << '*' << endl;

cout << setw(6) << '*' << " 1: 稀疏矩阵的普通转置算法" << endl;

cout << setw(6) << '*' << " 2: 稀疏矩阵的快速转置算法" << endl;

cout << setw(6) << '*' << " 3: 稀疏矩阵的乘法的快速算法" << endl;

cout << setw(6) << '*' << " 4: 稀疏矩阵的乘法的经典算法" << endl;

cout << setw(6) << '*' << " 5: 稀疏矩阵的加法" << endl;

cout << setw(6) << '*' << " 6: 稀疏矩阵的减法" << endl;

cout << setw(6) << '*' << " 7: 求稀疏矩阵的逆" << endl;

cout << setw(6) << '*' << " 0: 退出程序" << endl;

cout.fill(' ');

c = getchar();

switch(c)

{

case '1':

TranSMatrix();

break;

case '2':

FastTranMat();

break;

case '3':

MultSMatrix();

break;

case '4':

MultMat();

break;

case '5':

AddMatrix();

break;

case '6':

SubMatrix();

break;

case '7':

InverseMat();

break;

case '0':

cout << "谢谢使用! 再见!" << endl;

break;

default:

cout << "错误命令!" << endl << endl;

break;

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: