稀疏矩阵相乘

来源:互联网 发布:汽车级单片机 区别 编辑:程序博客网 时间:2024/06/06 01:53

对于用三元组实现稀疏矩阵相乘的算法,首先构造一个结构体,结构图体中应该有五个量。其中第一个量是表示稀疏矩阵常用的三元组,定义如下:

typedef struct{    int i, j;         //该非零元素行列下标    ElemType e;}Triple;/*--------稀疏矩阵的三元组顺序表存储表示-------*/

下面是结构体的完整定义:

typedef struct {    Triple data[MAXSIZE+1];   //三元组    int num[MAXRC];           //一个数组记录矩阵每一行非零元个数    int rpos [MAXRC+1];       //一个数组记录第一个非零元个数    int mu, nu, tu;           //    .}RLSMatrix;

定义好结构体之后,我们要对结构体表示的矩阵实现矩阵相乘算法(注释已经写好了):

Status MultSMatrix(RLSMatrix M, RLSMatrix N, RLSMatrix &Q) {    if (M.nu != N.mu)return ERROR;    Q.mu = M.mu;    Q.nu = N.nu;    Q.tu = 0;    if (M.tu*N.tu != 0) {                               //  说明Q是非零矩阵            int ctemp[100];                             // 设置累加器ctemp数组            int brow;             for (int col = 1; col < M.mu; ++col) {      //将表示M,N每行元素非零元个数的数组初始化                M.num[col] = 0; N.num[col] = 0; }            for (int t = 1; t <= M.tu; ++t) {                ++M.num[M.data[t].i];            }for (int t = 1; t <= N.tu; ++t) {                ++N.num[N.data[t].i];            }                                           //求出M,N每行元素非零元个数            M.rpos[1] = 1;            N.rpos[1] = 1;            for (int col = 2; col <= M.mu; ++col) {                M.rpos[col] = M.rpos[col - 1] + M.num[col - 1];                N.rpos[col] = N.rpos[col - 1] + N.num[col - 1];            }                                            //通过计算得出每行第一个非零元在三元组中的位置并将其放入rpos数组        for (int arow = 1;arow<=M.mu;arow++) {            for (int j = 1; j <= N.nu; j++) ctemp[j] = 0;//初始化累加器            Q.rpos[arow] = Q.tu + 1;            int tp;            if (arow < M.mu)tp = M.rpos[arow + 1];            else { tp = M.tu + 1; }            for (int p = M.rpos[arow]; p < tp; ++p) {                            brow = M.data[p].j;                         //找到每行第一个非零元的列下标,此下标在N中对应一个行号                int t;                if (brow < N.mu)t = N.rpos[brow + 1];                else { t = N.tu + 1; }                      //如果对应行不超过N的行数,设置t为下一行首字母下标,否则,则设置t为最后一个非零元下标                for (int q = N.rpos[brow]; q < t; ++q) {                    int ccol = N.data[q].j;                    ctemp[ccol]+= M.data[p].e*N.data[q].e;  //在不超过t的范围内做对应乘和累加操作                }            }            for(int ccol = 1;ccol<=Q.nu;++ccol) {                if (ctemp[ccol]) {                    if (++Q.tu > MAXSIZE)return ERROR;      //将该行非零元放入Q的三元组                    Q.data[Q.tu].i = arow;                    Q.data[Q.tu].j = ccol;                    Q.data[Q.tu].e=ctemp[ccol];                }            }        }    }    return OK;}

之后在主函数中初始化M和N,并进行计算

int main(){    RLSMatrix *a, *b, c;    a = (RLSMatrix*)malloc(sizeof(RLSMatrix));    b = (RLSMatrix*)malloc(sizeof(RLSMatrix));    cout<<"请输入A矩阵的行列式和非零元素的值"<<endl;    cin>> a->mu >> a->nu >> a->tu;                                         for (int i = 1; i <=a->tu; i++)        cin >> a->data[i].i >> a->data[i].j >> a->data[i].e;    cout << "请输入B矩阵的行列式和非零元素的值" << endl;    cin >> b->mu >> b->nu >> b->tu;    for (int i = 1; i <= b->tu; i++)        cin >> b->data[i].i >> b->data[i].j >> b->data[i].e;    if (!MultSMatrix(*a, *b, c)) {        cout << "矩阵无法相乘" <<endl;    }    else {        cout<<"结果如下"<<endl;    }    cout <<c.mu<<"\t"<<c.nu<<"\t"<<c.tu;    for (int i = 1; i <= c.tu; i++) {        cout << "\n" << c.data[i].i << "\t" << c.data[i].j << "\t" << c.data[i].e;    }    free(a); free(b);    a = NULL;    b = NULL;    system("pause");}

这样就完成了稀疏矩阵相乘的操作,也可以自己根据需要修改主函数