稀疏矩阵顺序存储的运算方法
来源:互联网 发布:宜乎百姓之谓我爱也忽 编辑:程序博客网 时间:2024/05/22 12:34
这里说说稀疏矩阵用三元组顺序存储的的运算方法:
然后a矩阵的第i行与b矩阵的第j列相乘作为新矩阵的第i,元;
首先是三元组的数据结构类型:
const int maxn= 100;typedef struct{ int i,j;//矩阵行标,列标 int e;//元素值}Triple;typedef struct{ Triple date[maxn +1];//非零三元组表 int mu;//行数 int nu;//列数 int tu;//非零元数}RLSMatrix;
先说说乘法的思想,两矩阵可以做乘法的前提是a[n][m]*b[j][k]
- m=j;
- a.tu*b.tu!=0;
//nump[i]记录矩阵p第i行非零元的个数prpos[i]记录矩阵p第i行第一个非零元在三元组中的位置//numq[i]记录矩阵q第i行非零元的个数qrpos[i]记录矩阵q第i行第一个非零元在三元组中的位置RLSMatrix Multiplication(RLSMatrix &p,RLSMatrix &q){ if(p.nu==q.mu && 0!=p.tu*q.tu){ RLSMatrix v; v.mu=p.mu; v.nu=q.nu; v.tu=1; //初始化 int nump[maxn+1]; int numq[maxn+1]; int pqtemp[maxn+1]; int prpos[maxn+1]; int qrpos[maxn+1]; memset(nump,0,sizeof(nump)); memset(numq,0,sizeof(numq)); for(int g=1;g<=p.tu;g++)//p 每一行非零元的个数; nump[p.date[g].i]+=1; for(int f=1;f<=q.tu;f++)//q 每一行非零元的个数; numq[q.date[f].i]+=1; for(int k=0;k<=q.tu+1;k++)//q 每行非零元地址设为0 qrpos[k]=0; for(int h=0;h<=p.tu+1;h++)//p 每行非零元地址设为0 prpos[h]=0; prpos[1]=1; qrpos[1]=1; for(int l=2;l<=q.mu+1;l++)//p每行非零元地址 prpos[l]=prpos[l-1]+nump[l-1]; for(int t=2;t<=q.mu+1;t++)//q 每行非零元地址 qrpos[t]=qrpos[t-1]+numq[t-1]; for(int arow=1;arow<=p.mu;arow++){ int a=prpos[arow]; int b=prpos[arow+1]; memset(pqtemp,0,sizeof(pqtemp)); //a的第i行与b的第i行对应相乘,得到的值按b对应的列标一一存在pqtemp中 for(int tt=a;tt<b ;tt++ ){ int w=p.date[tt].j; int aa=qrpos[w]; int bb=qrpos[w+1]; for(int nn=aa;nn<bb;nn++){ //pi,j*qj,? pqtemp[q.date[nn].j]+=p.date[tt].e*q.date[nn].e; } } //将pqtemp中的值逐个存入结果三元组中 for(int mm=1;mm<=q.nu;mm++){//压缩存储 if(pqtemp[mm]!=0){ v.date[v.tu].i=arow; v.date[v.tu].j=mm; v.date[v.tu].e=pqtemp[mm]; v.tu+=1; } } } v.tu--; return v; } else{ cout<<"两矩阵不满足乘法的条件!!"<<endl; exit(0); }}
稀疏矩阵的转置
//cpot[i]第i列的第一个非零元的位置//num[i]第i列非零元的个数RLSMatrix TransposeSmatrix(RLSMatrix &M){//矩阵为非空 if(M.tu){ RLSMatrix p; //转置后矩阵的行值为原矩阵的列值,非零元个数不变 p.tu=M.tu; p.nu=M.mu; p.mu=M.nu; //辅助数组,num[i]第i列非零元个数 //cpot[i]第i列的第一个非零元的位置 int num[maxn+1]; int cpot[maxn+1]; memset(num,0,sizeof(num)); memset(cpot,0,sizeof(cpot)); //num[i]和cpot[i]的初始化 for(int i=1;i<=M.tu;i++) num[M.date[i].j]++; cpot[1]=1; for(int i=2;i<=M.nu;i++) cpot[i]=cpot[i-1]+num[i-1]; //逐个读取原矩阵,进行转置变化 for(int k=1;k<=M.tu;k++){ int f=M.date[k].j; int t=cpot[f]; p.date[t].i=M.date[k].j; p.date[t].j=M.date[k].i; p.date[t].e=M.date[k].e; cpot[f]++; }//for return p; }//if}
稀疏矩阵的加法
RLSMatrix Add(RLSMatrix &p, RLSMatrix &q){ if(p.nu==q.nu && p.mu==q.mu){ RLSMatrix v; int f=1,t=1,temp=1; v.nu=p.nu; v.mu=p.mu; v.tu=0; while(f<=p.tu && t<=q.tu){ if(p.date[f].i==q.date[t].i && p.date[f].j==q.date[f].j){ if(0!=(p.date[f].e+q.date[f].e)){ v.date[temp].i=p.date[f].i; v.date[temp].j=p.date[f].j; v.date[temp].e=p.date[f].e+q.date[f].e; temp++;v.tu++; //cout<<p.date[f].e<<' '<<q.date[f].e<<' '<<v.date[f].e<<' '<<temp<<' '<<v.tu<<endl; }//if f++;t++; continue ; }//if else{ if( (p.date[f].i>q.date[t].i) || (p.date[f].i==q.date[t].i && p.date[f].j>q.date[t].j) ){ v.date[temp].i=q.date[t].i; v.date[temp].j=q.date[t].j; v.date[temp].e=q.date[t].e; temp++; t++;v.tu++;//cout<<p.date[f].e<<' '<<q.date[f].e<<' '<<v.date[f].e<<' 'temp<<' '<<v.tu<<endl; continue ; }//if else{ v.date[temp].i=p.date[f].i; v.date[temp].j=p.date[f].j; v.date[temp].e=p.date[f].e; temp++; f++;v.tu++; continue; }//else }//else }//while //三元组p未被读完 while(f<=p.tu){ v.date[temp].i=p.date[f].i; v.date[temp].j=p.date[f].j; v.date[temp].e=p.date[f].e; temp++; v.tu++; f++; } //三元组q未被读完 while(t<=q.tu){ v.date[temp].i=q.date[t].i; v.date[temp].j=q.date[t].j; v.date[temp].e=q.date[t].e; temp++; v.tu++; t++; } return v; }//if else{ cout<<"矩阵大小不相等,不可相加!!"<<endl; exit(0); }}//减法与加法原理类似,这里省去。
0 0
- 稀疏矩阵顺序存储的运算方法
- 稀疏矩阵的顺序存储
- 稀疏矩阵的顺序存储结构表示
- 稀疏矩阵的三元组顺序存储
- 稀疏矩阵的存储及运算
- 顺序存储结构的三元组稀疏矩阵的乘法运算
- 稀疏矩阵的存储方法之二
- 稀疏矩阵的变带宽存储方法。
- 稀疏矩阵的三元组顺序表存储
- 关于稀疏矩阵的压缩存储与基本运算
- 稀疏矩阵 三元组顺序存储
- 稀疏矩阵存储、转置、乘法运算
- 稀疏矩阵的基本运算
- 稀疏矩阵的基本运算
- 稀疏矩阵的存储格式
- 稀疏矩阵的压缩存储
- 稀疏矩阵的压缩存储
- 稀疏矩阵的压缩存储
- Linux strace命令
- CodeForces 535B — Tavas and SaDDas
- fork()相关
- 条件编译
- [C编译器]在VS中编译调试C程序
- 稀疏矩阵顺序存储的运算方法
- MYSQL数据库简单的状态检查(show status)
- P2P理财项目四个月开发总结
- DM8168 & DVR_RDK配置
- 【转载&收藏】Oracle/MSSQL/Mysql 常用数据库的字段类型及大小
- 进程间通信---在父进程跟子进程之间利用管道进行通信。一个简单的例子
- Beautiful Soup 4.2.0 文档
- 杭电OJ1016 素数环
- Android Studio 快捷键