zoukankan      html  css  js  c++  java
  • 稀疏矩阵算法

    1、稀疏矩阵的压缩存储
         为了节省存储单元,可只存储非零元素。由于非零元素的分布一般是没有规律的,因此在存储非零元素的同时,还必须存储非零元素所在的行号、列号,才能迅速确定一个非零元素是矩阵中的哪一个元素。稀疏矩阵的压缩存储会失去随机存取功能。
         其中每一个非零元素所在的行号、列号和值组成一个三元组(i,j,aij),并由此三元组惟一确定。
         稀疏矩阵进行压缩存储通常有两类方法:顺序存储和链式存储。链式存储方法。

    2、三元组表
         将表示稀疏矩阵的非零元素的三元组按行优先(或列优先)的顺序排列(跳过零元素),并依次存放在向量中,这种稀疏矩阵的顺序存储结构称为三元组表。
      注意:
        
    以下的讨论中,均假定三元组是按行优先顺序排列的。
          
    (1)三元组表的类型说明
         为了运算方便,将矩阵的总行数、总列数及非零元素的总数均作为三元组表的属性进行描述。其类型描述为:
      #define MaxSize 10000 //由用户定义
      typedef int DataType; //由用户定义
      typedef struct { //三元组
        int i,j;//非零元的行、列号
        DataType v; //非零元的值
       }TriTupleNode;

      typedef struct{ //三元组表
        TriTupleNode data[MaxSize]; //三元组表空间
        int m,n,t; //矩阵的行数、列数及非零元个数
      }TriTupleTable; 
        
    (2) 压缩存储结构上矩阵的转置运算
        一个m×n的矩阵A,它的转置矩阵B是一个n×m的矩阵,且:
             A[i][j]=B[j][i],0≤i<m,0≤j<n,
        即A的行是B的列,A的列是B的行。

    ①三元组表表示的矩阵转置的思想方法
      第一步:根据A矩阵的行数、列数和非零元总数确定B矩阵的列数、行数和非零元总数。
      第二步:当三元组表非空(A矩阵的非零元不为0)时,根据A矩阵三元组表的结点空间data(以下简称为三元组表),将A的三元组表a->data置换为B的三元组表b->data。

    ②三元组表的转置
         方法一:简单地交换a->data中i和j中的内容,得到按列优先顺序存储倒b->data;再将b->data重排成按行优先顺序的三元组表。
         方法二:由于A的列是B的行,因此,按a->data的列序转置,所得到的转置矩阵B的三元组表b->data必定是按行优先存放的。
         按这种方法设计的算法,其基本思想是:对A中的每一列col(0≤col≤a->n-1),通过从头至尾扫描三元组表a->data,找出所有列号等于col的那些三元组,将它们的行号和列号互换后依次放人b->data中,即可得到B的按行优先的压缩存贮表示。

    下面是完整的稀疏矩阵算法,包括加法,转置,乘法等

    #include <stdio.h>
    #include <stdlib.h>
    #define A 6
    #define B 7
    #define A1 3
    #define B1 4
    #define A2 4
    #define B2 2
    #define OK 1
    #define ERROR -1;
    #define MAXSIZE 1000

    typedef int Status;
    typedef int ElemType;
    typedef struct {
      int i,j;
      ElemType e;
    }Triple;       
    typedef struct {
      Triple data[MAXSIZE+1];
      int rpos[MAXSIZE+1];
      int mu,nu,tu;
    }TSMatrix;       

    void CreatTripleTable (int array_a[A][B],TSMatrix *a)
    /*array_aÊÇÒ»¸öÏ¡Êè¾ØÕó,aÊDzúÉúµÄÏà¶ÔÓ¦µÄÈýÔª×é´æ´¢*/
    {                                                    
      int i,j,k=1;
      //a->data=(Triple *)malloc((MAXSIZE+1)*sizeof(Triple));
      for (i=0;i<A;i++) /*°´ÐÐÓÅÏÈ˳ÐòɨÃèarray_aµÄÔªËØ,²»Îª0Õß´æÈëBÖÐ*/
        for (j=0;j<B;j++)
          if (array_a[i][j]!=0)
          {      
            a->data[k].i=i+1;
            a->data[k].j=j+1;
            a->data[k].e = array_a[i][j];
            //printf("i=%d\n",a->data[k].i);
            //printf("j=%d\n",a->data[k].j);
            //printf("e=%d\n",a->data[k].e);
            //printf("k=%d\n",k);
            //printf("\n");
            k++;
          }
      a->mu=A;
      a->nu=B;
     // data[0][1]=N;
      a->tu=k-1;/*´æÈë·Ç0ÔªËظöÊý*/
    }/*CreatTripleTable*/

    void CreatTripleTable1 (int array_a[A1][B1],TSMatrix *a)
    /*array_aÊÇÒ»¸öÏ¡Êè¾ØÕó,aÊDzúÉúµÄÏà¶ÔÓ¦µÄÈýÔª×é´æ´¢*/
    {                                                    
      int i,j,k=1;
      //a->data=(Triple *)malloc((MAXSIZE+1)*sizeof(Triple));
      for (i=0;i<A1;i++) /*°´ÐÐÓÅÏÈ˳ÐòɨÃèarray_aµÄÔªËØ,²»Îª0Õß´æÈëBÖÐ*/
        for (j=0;j<B1;j++)
          if (array_a[i][j]!=0)
          {      
            a->data[k].i=i+1;
            a->data[k].j=j+1;
            a->data[k].e = array_a[i][j];
            k++;
          }
      a->mu=A1;
      a->nu=B1;
      a->tu=k-1;/*´æÈë·Ç0ÔªËظöÊý*/
    }

    void CreatTripleTable2 (int array_a[A2][B2],TSMatrix *a)
    /*array_aÊÇÒ»¸öÏ¡Êè¾ØÕó,aÊDzúÉúµÄÏà¶ÔÓ¦µÄÈýÔª×é´æ´¢*/
    {                                                    
      int i,j,k=1;
      //a->data=(Triple *)malloc((MAXSIZE+1)*sizeof(Triple));
      for (i=0;i<A2;i++) /*°´ÐÐÓÅÏÈ˳ÐòɨÃèarray_aµÄÔªËØ,²»Îª0Õß´æÈëBÖÐ*/
        for (j=0;j<B2;j++)
          if (array_a[i][j]!=0)
          {      
            a->data[k].i=i+1;
            a->data[k].j=j+1;
            a->data[k].e = array_a[i][j];
            k++;
          }
      a->mu=A2;
      a->nu=B2;
      a->tu=k-1;/*´æÈë·Ç0ÔªËظöÊý*/
    }

    Status TransposeSMatrix(TSMatrix *M,TSMatrix *T)
    {
      int p,q,col;     
      T->mu=M->nu;  T->nu=M->mu;  T->tu=M->tu;
      if (T->tu) {
        q=1;
        for (col=1;col<=M->nu;++col)
          for (p=1;p<=M->tu;++p)
            if (M->data[p].j==col) {
              T->data[q].i=M->data[p].j;    T->data[q].j=M->data[p].i; 
              T->data[q].e=M->data[p].e;    ++q;
            }   
      }         
      return OK;
    }

    Status FastTransposeSMatrix(TSMatrix *M,TSMatrix *T)
    {
      int t,p,q,col,num[A],cpot[M->nu];     
      T->mu=M->mu;  T->nu=M->mu;  T->tu=M->tu;
      if (T->tu) {
        for (col=1;col<=M->nu;++col) num[col]=0;
        for (t=1;t<=M->tu;++t) ++num[M->data[t].j];
        cpot[1]=1;
        for (col=2;col<=M->nu;++col) cpot[col]=cpot[col-1]+num[col-1];
        for (p=1;p<=M->tu;++p) {
          col=M->data[p].j;   q=cpot[col];
          T->data[q].i=M->data[p].j;    T->data[q].j=M->data[p].i; 
          T->data[q].e=M->data[p].e;    ++cpot[col];
        }   
      }               
      return OK;
    }  

    Status TSMatrix_Add(TSMatrix M,TSMatrix N,TSMatrix *C)//ÈýÔª×é±íʾµÄÏ¡Êè¾ØÕó¼Ó·¨
    {
      int i,j,x,ce,pa,pb,pc;  
      if (M.mu!=N.mu || M.nu!=N.nu) return ERROR;
      C->mu=M.mu;C->nu=M.nu;C->tu=0;
      pa=1;pb=1;pc=1;
      for(x=1;x<=M.mu;x++) //¶Ô¾ØÕóµÄÿһÐнøÐмӷ¨
      {
        while(M.data[pa].i<x) pa++;
        while(M.data[pb].i<x) pb++;
        while(M.data[pa].i==x&&N.data[pb].i==x)//ÐÐÁÐÖµ¶¼ÏàµÈµÄÔªËØ
        {
          if(M.data[pa].j==N.data[pb].j)
          {
            ce=M.data[pa].e+N.data[pb].e;
            if(ce) //ºÍ²»Îª0
            {
              C->data[pc].i=x;
              C->data[pc].j=M.data[pa].j;
              C->data[pc].e=ce;
              pa++;pb++;pc++;
            }
          }//if
          else if(M.data[pa].j>N.data[pb].j)
          {
            C->data[pc].i=x;
            C->data[pc].j=N.data[pb].j;
            C->data[pc].e=N.data[pb].e;
            pb++;pc++;
          }
          else
          {
            C->data[pc].i=x;
            C->data[pc].j=M.data[pa].j;
            C->data[pc].e=M.data[pa].e;
            pa++;pc++;
          }
        }//while
        while(M.data[pa].i==x) //²åÈëAÖÐÊ£ÓàµÄÔªËØ(µÚxÐÐ)
        {
          C->data[pc].i=x;
          C->data[pc].j=M.data[pa].j;
          C->data[pc].e=M.data[pa].e;
          pa++;pc++;
        }
        while(N.data[pb].i==x) //²åÈëBÖÐÊ£ÓàµÄÔªËØ(µÚxÐÐ)
        {
          C->data[pc].i=x;
          C->data[pc].j=N.data[pb].j;
          C->data[pc].e=N.data[pb].e;
          pb++;pc++;
        }
      }//for
      C->tu=pc;
      return OK;
    }//TSMatrix_Add  

    void PrintSMatrix(TSMatrix M)
    {
      int i,j,pa; 
      int a[M.mu][M.nu];
      pa=1;
      for (i=0;i<M.mu;i++)  
        for (j=0;j<M.nu;j++)
          a[i][j]=0;
      for (pa=1;pa<=M.tu;pa++) {   
        //printf("%d\n",M.data[pa].i);
        //printf("%d\n",M.data[pa].j);
        //printf("%d\n",M.data[pa].e);
        a[M.data[pa].i-1][M.data[pa].j-1]=M.data[pa].e;
      } 
      for (i=0;i<M.mu;i++) {  
        for (j=0;j<M.nu;j++)
          printf("%6d",a[i][j]);            
          printf("\n");
      } 
      printf("\n");
    }   

    void GetRpos(TSMatrix *M) {
      int row,t,j,num[M->mu],cpot[M->nu];
      for (row=1;row<=M->mu;++row) num[row]=0; 
      for (t=1;t<=M->tu;++t) ++num[M->data[t].i];
      M->rpos[1]=1;
      for (row=2;row<=M->mu;++row) M->rpos[row]=M->rpos[row-1]+num[row-1];
      for (t=1;t<=M->mu;++t) printf("%d\n",M->rpos[t]);
    }                

    Status MultSMatrix(TSMatrix M,TSMatrix N,TSMatrix *Q) {
      int arrow,brow,tp,p,q,t,ccol,ctemp[Q->nu];    
      if (M.nu!=N.mu) return ERROR;
      Q->mu=M.mu;  Q->nu=N.nu;  Q->tu=0;
      if (M.tu*N.tu!=0) {   
        for (arrow=1;arrow<=M.mu;++arrow) {
          for (p=1;p<=N.nu;p++) ctemp[p]=0; 
          Q->rpos[arrow]=Q->tu+1;
          if (arrow<M.mu) tp=M.rpos[arrow+1];
          else tp=M.tu+1;
          for (p=M.rpos[arrow];p<tp;++p) {
            brow=M.data[p].j;
            if (brow<N.mu) t=N.rpos[brow+1];
            else {t=N.tu+1;} 
            for (q=N.rpos[brow]; q<t; ++q) {
              ccol=N.data[q].j;        
              //printf("ctemp[ccol]=%d\n",ctemp[ccol]);
              ctemp[ccol]+=M.data[p].e * N.data[q].e;
              //printf("ccol=%d\n",ccol);
              //printf("M.data[p].e * N.data[q].e=%d * %d\n",M.data[p].e,N.data[q].e);
              //printf("ctemp[ccol]=%d\n",ctemp[ccol]);
              //printf("")
            }   
          }   
          for (ccol=1; ccol<=Q->nu;++ccol)
            if (ctemp[ccol]){
              if (++Q->tu>MAXSIZE) return ERROR;
              Q->data[Q->tu].i=arrow;
              Q->data[Q->tu].j=ccol;
              Q->data[Q->tu].e=ctemp[ccol];
            }  
        }      
      }  
    }      

    void DestroySMatrix(TSMatrix M)
    {
      M.mu=0;  M.nu=0;  M.tu=0;  
    }    
                     
    int main(int argc, char *argv[])
    {
      TSMatrix a,b,c,d,e;  //Èç¹ûдΪ*a£¬Ôò±ØÐë¼ÓÉÏa=(TSMatrix *)malloc(sizeof(TSMatrix)),»ò¼ÓÒ»TSMatrix b,a=&b;
      TSMatrix aa,bb,cc;
      int array[A][B]={{0,12,9,0,0,0,0},{0,0,0,0,0,0,0},{-3,0,0,0,0,14,0},{0,0,24,0,0,0,0},{0,18,0,0,0,0,0},{15,0,0,-7,0,0,0}};
      int array1[A][B]={{0,12,3,4,0,0,0},{0,0,0,3,0,0,0},{-3,0,0,0,0,14,0},{0,0,24,0,0,0,0},{0,18,0,0,0,0,0},{15,0,0,-7,0,0,0}};
     
      int array2[A1][B1]={{3,0,0,5},{0,-1,0,0},{2,0,0,0}};
      int array3[A2][B2]={{0,2},{1,0},{-2,4},{0,0}};
     
      //a=(TSMatrix *)malloc(sizeof(TSMatrix)); 
      CreatTripleTable(array,&a);
      PrintSMatrix(a);
      printf("Transpose\n");
      TransposeSMatrix(&a,&c);
      PrintSMatrix(c);
      printf("Fast Transpose\n");
      FastTransposeSMatrix(&a,&d);
      PrintSMatrix(d);   
     
      printf("Add Transpose\n");
      CreatTripleTable(array1,&b); 
      TSMatrix_Add(a,b,&e);
      PrintSMatrix(e);
       
      CreatTripleTable1(array2,&aa);
      PrintSMatrix(aa);
      CreatTripleTable2(array3,&bb);
      PrintSMatrix(bb);
      GetRpos(&aa);
      GetRpos(&bb);
      MultSMatrix(aa,bb,&cc);
      PrintSMatrix(cc);

      DestroySMatrix(a);
      DestroySMatrix(b);               
      DestroySMatrix(c);
      DestroySMatrix(aa);
      DestroySMatrix(bb);               
      DestroySMatrix(cc);
      system("PAUSE"); 
      return 0;
    }

  • 相关阅读:
    【转】编写高质量代码改善C#程序的157个建议——建议123:程序集不必与命名空间同名
    【转】编写高质量代码改善C#程序的157个建议——建议122:以<Company>.<Component>为命名空间命名
    【转】编写高质量代码改善C#程序的157个建议——建议121:为应用程序设定运行权限
    【转】编写高质量代码改善C#程序的157个建议——建议119:不要使用自己的加密算法
    【转】编写高质量代码改善C#程序的157个建议——建议118:使用SecureString保存密钥等机密字符串
    看后有感,请努力吧,趁年轻
    springmvc图片上传
    七月份,工作总结
    switch… case 语句的用法
    ibatis动态查询
  • 原文地址:https://www.cnblogs.com/djcsch2001/p/2035167.html
Copyright © 2011-2022 走看看