第lO卷第4期2010年2月 科学技术与工・程 Vo1.10 No.4 Feb.2010 1671—1815(2010)4—1041-04 Science Technology and En ̄neefing @2010 Sci.Tech.Engng. 基于压缩存储的稀疏矩阵转置算法研究 王敏 (渭南师范学院计算机科学系,渭南714000) 摘要介绍了对稀疏矩阵进行压缩存储的几种存储方式,重点分析了稀疏矩阵的三元组压缩存储的不同存储结构,提出利 嗣数组首下标元素存储稀疏矩阵总行数、总列数和非零元素总个数三个信息的改进的三元组顺序表存储定义方式,同时给出 了用C语言编写的基于该定义上设计矩阵转置的几种算法。通过对各算法进行时间复杂度分析,总结出了几种算法的优 缺点。 关键词稀疏矩阵 压缩存储 三元组表 矩阵转置 时问复杂度 巾图法分类号TP311.12; 文献标志码A 计算机中存储矩阵的一般方法是采用二维数 组,其优点是可以随机地访问每一个元素,从而易于 实现矩阵的各种运算¨J。但对于稀疏矩阵(设m X n 1稀疏矩阵的三元组表存储结构 对矩阵的操作可归根结底为对矩阵元素的定位 的矩阵中有z个不为0的元素,令 =÷m ,£ ,称 为 和修改两大类,这两类操作都是根据给定的一组行 列值进行元素的访问。首先分析一下采用压缩存储 的稀疏矩阵中非零元素三元组的抽象数据类型(Ab— stract Data Type):可将各非零元素三元组按照“行序 为主、列序为辅”的顺序排成一个序列,则在该序列 矩阵的稀疏因子,通常认为6≤0.05时为稀疏矩 阵 )来说,大量零元素的存储会造成存储空间的 浪费。为了在实现矩阵相关操作时提高存储空间的 利用率,需要对稀疏矩阵进行有效的压缩存储,即只 存储矩阵中的非零元素。由于稀疏矩阵中的非零元 素分布没有规律,要实现压缩存储,则记录每个非零 中,除了首尾以外的其余三元组都只有唯一的前驱 和后继。显然,这构成一种线性逻辑结构,可采用顺 序和非顺序两种存储方式,具体采用哪种主要取决 于将设计实现矩阵的哪些操作。非顺序存储方式主 要采用链式存储结构(比如十字链表),适用于设计 实现对稀疏矩阵的非零元素个数有改变的一类操作 (比如矩阵相加、相减、相乘等);而对于矩阵转置之 类非零元素个数不变的操作,则采用顺序存储结构 (比如一维数组)实现较为方便,即三元组顺 元素的元素值的同时,还必须给出其所在行、列的下 标位置,构成形如(FOW,column,value)的非零元素 三元组。 本文将重点研究稀疏矩阵采用三元组表压缩存 储方式的改进办法,给出改进后用C语言编写的几 种不同的稀疏矩阵转置算法,通过对各个算法进行 时间复杂度分析,总结比较出各个算法的优缺点。 序表 引。 稀疏矩阵的存储信息还应包括矩阵总行数、矩 2009年l1月10日收到 作者简介:王件算法一 国家自然科学基金(60803132)资助 阵总列数和矩阵中非零元素的总个数。大多数参考 文献中关于稀疏矩阵存储结构的定义均额外定义了 敏(1972一),陕西临潼人,讲师,硕士,研究方向:软 用于存储这三方面信息的结构体成员变量,而这种 1042 科学技术与工程 l0卷 存储处理其实可以进行简化:由于前述三种信息的 类型同三元组的各个成员类型相兼容,因此可将三 元组向量的首下标单元的对应三元分别用于存放这 三方面信息。三元组顺序表存储结构的稀疏矩阵可 使用C语言定义如下: #deftne MAX 1000 。typedef struct{ int r0w.col; Elemtype val; }Triple[ ]; typedef Triple TSMamx[ ][MAX]; 由于矩阵的行列编号一般从1起始,因而可将 C语言数组的0下标单元用于存储前述三种信息。 2矩阵转置操作的算法比较 基于三元组顺序表存储结构实现矩阵转置的算 法可归纳为直接转置、根据转置矩阵的行序进行转 置和快速转置三种。下面将待转置矩阵记作A( 行Ⅳ列),转置矩阵记作B(Ⅳ行 列),分别对几种 算法加以分析讨论。 2.1直接转置算法 该算法的第一步直接将矩阵A的非零元素三元 组的行列互换后赋值给转置矩阵B;为了保证矩阵 B仍然是以“行序为主序”存放,该算法还需要进一 步对 矩阵中的三元组进行按行排序。 执行第一步时,算法的基本语句是实现三元组 赋值操作的循环体语句,因而此部分算法的时间复 杂度取决于矩阵中的非零元素三元组的个数(视为 问题的规模乃),即 (n)=0(凡);执行第二步时,算 法的时间复杂度既同问题的规模n相关,又取决于 所采用的排序算法,且排序过程中将有三元组的移 动操作。例如采用快速排序算法时该部分的平均时 间复杂度 (n)=0(凡×Ig:n),这样,两步操作总的 时间复杂度为 (n)=TI(n)+ (n)= 0(n+n×Ig2n),即T(n)=O(凡×Ig2n)。 2.2根据转置矩阵的行序进行转置的算法 该算法是在矩阵A的三元组表中按照转置矩阵 日的行序(即矩阵A的列序),逐一将A的三元组行 列互换并赋值给B的转置操作。基于前述存储类型 TSMatrix的算法可用C语言描述如下: void TransposeMatrix(TSMatrix A,TSMatrix B) {int i,j, ; //i为A的三元组表下标,j为B的三元组表下标 ( B)[O].10W=A[0].col; (}B)[O].col=A[0].row; ( B)[0].val=A[O].val; if(A[O].v ̄)//有非零元素三元组则进行转置 { for(j=1,r=1;r<=(}B)[o 3.row;r++) //根据B的行逐行进行转置 for(i=1;i<=A[0].val;i++) {if(A[i].col==r) //当A中三元组的列号为正在查找的行时进行转置 {(女B)[j].1ow= ; (十B)[j].col=A[i].1ow; (}B)[j].val=A[i].val; j++; } } }I 程序中的基本语句是双重循环的循环体语句, 因而算法的时间复杂度取决于转置矩阵B的总行数 Ⅳ和矩阵中非零元素三元组的个数 0].val(即前 述问题的规模n),从而算法的时间复杂度 为 (凡)=D(N×n)。 2.3快速转置算法 快速转置算法是依次将待转置矩阵A的三元组 行列互换后,直接放到转置矩阵 的三元组表中的 正确位置。该算法需考虑两个因素:一是矩阵A每 列中非零元素的个数(即转置矩阵日每一行中非零 元素的个数);二是矩阵A各列中第一个非零元素三 元组在 中的正确位置(即矩阵曰各行中第一个非 零元素三元组在B中的正确位置)。为此,可设置 两个数组rgum[]和position[],前者用来存放 中 第coz列(B中第c0z行)的非零元素个数,后者用以 存放A中第col列(B中第col行)中第一个非零元 素在三元组表B中的正确位置 。 计算lzum[co1]可通过一遍对矩阵A的三元组 表的循环扫描,将其中列号为c0Z的元素的对应 nlzm[co1]加1;而position[co1]可通过如下公式计算: 4期 王敏:基于压缩存储的稀疏矩阵转置算法研究 1043 position[co1] fl (col=1); 因而算法总的时间复杂度为T(凡)=0(N+n)。 m[c0f_1] ti on[col -1] (1<col<A[0].co1)。 得到上述两个数组的对应值后,要将A中的三 元组直接放到B中的正确位置,可利用poshion数组 3结论 在对矩阵采用三元组顺序表压缩存储技术时, 由于需要同时保存矩阵的总行数和总列数,另外为 实现:position[co1]的初值为矩阵A的三元组表中第 coz列(日中第coz行)的第一个非零元素三元组在 了便于三元组顺序表的操作,还需保存非零元素三 中的正确位置,当A中第c0z列有一个元素加入三元 组表B时,则positoin[c0z]的值加1,即:使 positoin[co1]始终指向三元组表A中第c0z列中下一 个非零元素在三元组表曰中的正确位置 引。基于 前述存储类型TSMatrix的C: void FastTransMatrix(TSMatrix A,TSMatrix B) {int col,i,j;//col作为辅助数组下标 //i指示矩阵A的三元组表下标,j指示B的三元组表下标 int num[MAX],position[MAX]; ( B)[0】.10W:A[0].col; (+B)[0].col=A[O].row; ( B)[o].val=A[O].val; if(A[0].v8J) //有非零元素三元组则进行转置 {for(col=1;col<=A[0].col;r++) num[co1]:0; //矩阵A各列非零元素个数计数预置为0 for(i=1;i<:A[0].val;r++) hum[A[i].co1]++; //矩阵A各列非零元素个数计数 position[1]=1; ofr(col=2;col<=A[0].col;col++) //求col列中第一个非零元素三元组在B中的正确位置 position[co1]=position[col—i]+num[col一1]; for(i=1;i<:A[O].val;i++) //对矩阵A的三元组表扫描一遍完成转置 {J=position[A[i].co1]; ( B)[J].IOW=A[i].col; ( B)[j].col:A[i].1OW; ( B)[j】.val=A[i].val; position[co1]+ ;} }} 该算法程序由前后四个循环部分组成,各个循 环的基本语句分别执行了A[0].col、A[O].val、A [0].c0l—l和A[0].va1次,其中A[0].val即前述 问题的规模n,A[0].col也即转置矩阵的总行数Ⅳ, 元组的总个数,本文给出了利用三元组表向量首下 标单元存储这些信息的存储方案,并给出了对应的 C语言结构定义TSMamx,这就省去了另外再定义这 些结构体成员变量的麻烦。 本文给出的算法的C语言程序均已上机测试通 过。通过对比分析三种算法的时间复杂度,可得到 以下结论: 快速转置算法的平均时间复杂度最低。对于直 接转置的方法~和按转置矩阵B的行序进行转置的 方法二来说,当问题的规模n较小时,log:13也较小, 因而此时方法一的时间复杂度较低,但方法一在对 矩阵B中的三元组进行按行排序时要涉及元素的移 动,算法的实际执行效率会有所降低。另外,随着问 题的规模n的增大,即非零元素个数接近矩阵的行 列之积(M×N)时,则方法一的时间复杂度接近 0(M×N×log (M×N)),方法二的时间复杂度接近 D(M×N2),均不如非压缩存储的经典双重循环算 法(其时间复杂度为 (n)=0(M×Ⅳ));而此时快 速转置算法的时间复杂度接近0(M×N)。 稀疏矩阵的三元组表压缩存储结构虽然节约了 存储空间,但同普通的矩阵存储方式比较,增加了实 现相同操作的算法设计难度。另外随着非零元素个 数的增加,算法的时间效率也逐渐降低。可见,前两 种算法从某种程度上说是以时间为代价换取了空间 的节省。快速转置算法虽然在时间效率上较前两种 算法有所提高,但在空间上除了三元组表所占空间 外,还需要增加辅助向量nlgm[Ⅳ]和positoin[Ⅳ]的 空间,则又是以空间为代价换取了时间的节省。可 见,算法的运行时间、所占的存储空间以及算法设计 的简单性往往是相互矛盾的,因而在设计时仍需要 根据实际情况加以权衡。 1044 科学技术与工程 10卷 2严蔚敏,吴伟民.数据结构.北京:清华大学出版社,2000:96,98 参考文献 3耿国华.数据结构.C语言描述.西安:西安电子科技大学出版 社。2006:1O1一l04 1徐孝凯.数据结构简明教程.北京:清华大学出版社,1995:71 Study Oil the Sparse Matrix Transpose Algorithms Based Oil Compressed Storage WANG Min (Weinan Teachers University,Weinan 714000,P.R.China) 『Abstract] Several compression storage methods of the sparse matrix are described and focused on analysis of dif- ferent compression storage technology about the triple list f0r the sparse matrix.After describing the compression storage definition about the triple list 0f the sparse matrix.an improved storage defining method is put forward to use an arrav element in the first subscript of the sequence triple list array to daclare the information about the totl nnm aber of rows.the total number of columns and the the total number of non—zero elements of the sparse matirx,and hen staves the matrix transposing algorithms written in C pogram language based 0n the definition proposed.By ana lyzing the time complexity of several sparse matrix transposition algorithms,which based on the compression storage stnctiure dicussed here,the advantages and disadvantages of the algorithms discussed are summarized. [Key words] sparse matrix 、 、 compressed storage tirple list rtanspose matirx time complexity (上接第1040页) Research about Software System Size Estimation by Iteration Development LIN Fang (1)el,all『llent ofComputer andInformationScience,Journal ofFujian University ofTechnology,Fuzhou 350014,P.R.China) 『Abstract] RUP development process is the mainstream of modem software development with characteristics of it— eHlti0_n and use case driven.UCP based on the use case is a sofware tsize estimation technique.The development of RUP is practiced,and research bouta software system size estimation.Fisrt estimates iteration numbers,second esti・ mates the use case points each iteration by UCP,which include developing the new applications and modifying the old applications.The size of totl saofwarte system.Finally is estimated. [Key words] RUP UCP size estimation UML iteration