稀疏矩陣順序存儲的運算方法

這裏說說稀疏矩陣用三元組順序存儲的的運算方法:
首先是三元組的數據結構類型:

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]
  1. m=j;
  2. a.tu*b.tu!=0;
=>if(a.nu== b.mu && a.tu*b.tu!=0){...}
  然後a矩陣的第i行與b矩陣的第j列相乘作爲新矩陣的第i,元;
//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);
    }
}
//減法與加法原理類似,這裏省去。


發佈了30 篇原創文章 · 獲贊 13 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章