(14)稀疏矩阵的压缩-三元组(相乘)

2/22/2017来源:ASP.NET技巧人气:1802

(1)因为position[i]表示B的第i行第一个非零元素在B.data中的序号,position[i+1]-1就表示第i行最后一个非零元素在B.data中的序号。为了表示B的最后一行最后一个非零元素在B.data中的序号,需在向量position中增加一个分量,即B的第m2行第一个元素的位置,虽然B中无第m2行。

(2)矩阵相乘的基本思想是:对A.data中的每一个元素A.data.e,找到满足A.data[p].col=B.data[q].row的所有q,将A.data[p].e与B.data[q].e的乘积加到适当的求累积和的变量上。

(3)两个稀疏相乘的结果不一定是稀疏矩阵,相乘的两个分量A[i][k] x B[k][j]不为零,但累加的结果可能为零。

改进的三元组表的类型说明如下:

#define MAXSIZE 1000			//用户自定义三元组最大个数
#define MAXROW 100
typedef int ElemType;
typedef struct {				//三元组
	int row,col;				//非零元素的行数和列数
	ElemType e;					//非零元素的值
}Triple;
typedef struct {
	Triple data[MAXSIZE];		//三元组表
	int position[MAXROW];		//各行第一个非零元素的位置表
	int m,n, len;				//矩阵的行数、列数和非零个数
}TSMatrix;

完整代码:

#include<iostream>
using namespace std;
#define MAXSIZE 1000			//用户自定义三元组最大个数
#define MAXROW 100
typedef int ElemType;
int sum[10];
typedef struct {				//三元组
	int row,col;				//非零元素的行数和列数
	ElemType e;					//非零元素的值
}Triple;
typedef struct {
	Triple data[MAXSIZE];		//三元组表
	int position[MAXROW];		//各行第一个非零元素的位置表
	int m,n, len;				//矩阵的行数、列数和非零个数
}TSMatrix;
//输出矩阵
void PRint(TSMatrix a){
	int k;
	for (int i = 0; i < a.m;i++) {
		for (int j = 0; j < a.n;j++) {
			k = 0;
			for(int h=0;h<a.len;h++){
				if (i == a.data[h].row && j==a.data[h].col) {
					cout <<"     "<< a.data[h].e;
					k = 1;
				}
			}
			if (k == 0) {
				cout << "     " << k;
			}
		}
		cout << endl;
	}
}
//采用改进的三元组表表示法,求矩阵乘积C=A*B
void MulMatrix(TSMatrix A,TSMatrix B,TSMatrix *C) {
	int p=0,crow,ccol,brow;
	if (A.n != B.m) {
		cout << "矩阵无法相乘!" << endl;
	}
	else {
		C->m = A.m;
		C->n = B.n;
		C->len = 0;
		while (p < A.len) {		//处理A当前元素
			crow = A.data[p].row;
			for ( ccol = 0; ccol < C->n; ccol++) sum[ccol] = 0;	//当前行各元素清零
			while (p<A.len && A.data[p].row==crow) {
				brow = A.data[p].col;			//B的当前行等于A的当前元素的列号
				for (int q = B.position[brow]; q < B.position[brow + 1];q++) {	//处理B当前行
					ccol = B.data[q].col;	//乘积元素在C中的列号
					sum[ccol] += A.data[p].e*B.data[q].e;
				}
				p++;
			}
			for (ccol = 0; ccol < C->n; ccol++) {
				//压缩存储该行非零元素到三元组表C.data中
				if (sum[ccol]) {
					C->data[C->len].row = crow;
					C->data[C->len].col = ccol;
					C->data[C->len].e = sum[ccol];
					C->len++;
				}
			}
		}
	}
}

void main() {
	TSMatrix A, B, C;
	A.m = 4; A.n = 4; A.len = 2;
	A.data[0].row = 1; A.data[0].col = 1; A.data[0].e = 2; A.position[1] = 0;
	A.data[1].row = 2; A.data[1].col = 3; A.data[1].e = 3; A.position[2] = 1;
	A.position[3] = 2;
	
	B.m = 4; B.n = 4; B.len = 3;
	B.data[0].row = 1; B.data[0].col = 1; B.data[0].e = 2; B.position[1] = 0;
	B.data[1].row = 2; B.data[1].col = 3; B.data[1].e = 3; B.position[2] = 1;
	B.data[2].row = 3; B.data[2].col = 2; B.data[2].e = 2; B.position[3] = 2;
	B.position[4] = 3;

	MulMatrix(B, B, &C);
	print(C);
	system("pause");
}