您的位置:首页 > 其它

三元组矩阵的乘法

2015-11-11 18:17 274 查看
三元组矩阵的乘法,针对稀疏矩阵:

源代码如下:

<构造位置表用了两种方法>

#include <stdlib.h>
#include <stdio.h>
#define MAXSIZE 100	//非零元的最大个数
#define MAX_ROW_NUM 20//最大行列数
#define ElenType int
#define Status int//返回值类型
#define OK 1
#define ERROR 0
#define OVERFLOW -1

/*稀疏矩阵的三元组存储结构*/
typedef struct {
int row,col;//非零元的行下标和列下标
ElenType data;//元素的值
}Triple;
typedef struct {
Triple dataArray[MAXSIZE+1];//非零元组表,dataArray[0]未用
int rpos[MAX_ROW_NUM+1];//各行第一个非零元的位置(在目标矩阵中的存储位置)表
int row_count,col_count,data_count;//矩阵的行数,列数和非零元个数
}*TSMatrix,Matrix;//代表Triple Sequence Matrix 三元组矩阵

/*创建一个矩阵*/
Status CreateTSMatrix(TSMatrix &M){
M = (TSMatrix)malloc(sizeof(Matrix));
if(!M){
exit(OVERFLOW);
}
printf("输入三元组的行数,列数和非零元个数:");
int rc,cc,dc;
scanf("%d%d%d",&rc,&cc,&dc);
M->row_count = rc;
M->col_count = cc;
M->data_count = dc;
int i = 0;
printf("开始构造矩阵\n");
int r,c,d;//作为临时变量
while(i<dc){
printf("输入第%d个非零元的行号,列号和值:",i+1);
scanf("%d%d%d",&r,&c,&d);
if(r>rc || c>cc){	//行和列不能越界
printf("此组数据不合法,请重新输入\n");
continue;
}else{
//因为下标从1 开始,所以i+1
M->dataArray[i+1].row = r;
M->dataArray[i+1].col = c;
M->dataArray[i+1].data = d;
i++;//此时才++
}
}
/*构造rpos[]的值*/
//////////方法一//////////
/*此方法就是只用一个数组rpos本身来构造*/
for(i=1;i<=M->row_count;i++){
M->rpos[i] = 0;//赋初值为0
}
for(i=1;i<=M->data_count;i++){
M->rpos[M->dataArray[i].row]++;//计算每一行有多少个非零元
}
//从后往前计算rpos[]的值,即累加
for(i=M->row_count;i>=1;i--){
M->rpos[i] = 1;
for(int j=i-1;j>=1;j--){
M->rpos[i] += M->rpos[j];
}
}
/////////方法二//////////
/*用一个辅助数组num来计算非零元个数,与稀疏矩阵的转置里方法一致*/
/*	int i=1,num[MAX_ROW_NUM+1];
for(i=1;i<=M->row_count;i++){
M->rpos[i] = 0;//赋初值为0
}
for(i=1;i<=M->data_count;i++){
num[M->dataArray[i].row]++;//计算每一行有多少个非零元
}
M->rpos[1] = 1;
for(i=2;i<=M->row_count;i++){
M->rpos[i] = M->rpos[i-1] + num[i];//递推
}
*/
printf("构造矩阵成功\n");
return OK;
}
/*打印三元组矩阵*/
Status PrintTSMatrix(TSMatrix M){
//用描述法吧
for(int i=1;i<=M->data_count;i++){
printf("行号 列号 值:%d %d %d",M->dataArray[i].row,M->dataArray[i].col, M->dataArray[i].data);
printf("\n");
}
return OK;
}
/*实现矩阵的乘法: Q = M * N */
Status MultTSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q){
int arow,brow,p,q,ccol,ctemp[MAX_ROW_NUM+1],t,tp;
if(M->col_count != N->row_count){//不能相乘
return ERROR;
}
if(0 == M->data_count * N->data_count ){//有一个是零矩阵
return ERROR;
}
//Q初始化
Q->row_count = M->row_count;
Q->col_count = N->col_count;
Q->data_count = 0;
//从M的第一行开始到最后一行,arow是M的当前行
for(arow=1;arow<=M->row_count;arow++){
for(ccol=1;ccol<=Q->col_count;ccol++){
ctemp[ccol] = 0;//Q的当前行的各列元素清零
}
Q->rpos[arow] = Q->data_count + 1;//开始时从第一个存储位置开始存,后面是基于前面的
if(arow < M->row_count){
tp = M->rpos[arow+1];//下一行的起始位置
}else{
tp = M->data_count + 1;//最后一行的边界
}
for(p=M->rpos[arow];p<tp;p++){
//对M当前行的每一个非零元
//找到对应元素在N中的行号,即M中当前元的列号
brow = M->dataArray[p].col;
//原理同上
if(brow<N->row_count){
t = N->rpos[brow+1];
}else{
t = N->data_count+1;
}
for(q=N->rpos[brow];q<t;q++){
ccol = N->dataArray[q].col;//乘积元素在Q中列的位置
ctemp[ccol] += M->dataArray[p].data * N->dataArray[q].data;
}//for_q
}//for_p
//该压缩存储该行非零元了
for(ccol=1;ccol<=Q->col_count;ccol++){
if(0!=ctemp[ccol]){
if(++Q->data_count > MAXSIZE){//注意这里有个++
return ERROR;
}
Q->dataArray[Q->data_count].row = arow;
Q->dataArray[Q->data_count].col = ccol;
Q->dataArray[Q->data_count].data = ctemp[ccol];
}
}
}//for_arow
return OK;
}
int main(){
TSMatrix M,N,Q;
Q = (TSMatrix)malloc(sizeof(TSMatrix));
CreateTSMatrix(M);
printf("矩阵M:\n");
PrintTSMatrix(M);
CreateTSMatrix(N);
printf("矩阵N:\n");
PrintTSMatrix(N);
MultTSMatrix(M,N,Q);
printf("矩阵Q:\n");
PrintTSMatrix(Q);
return 0;
}


现在用一个例子来验证一下:



运行结果:

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