稀疏矩阵的压缩存储
- 格式:ppt
- 大小:533.00 KB
- 文档页数:62
稀疏矩阵的压缩存储稀疏矩阵的压缩存储:实现稀疏矩阵压缩存储,并实现矩阵转置和求和。
输⼊矩阵时,⾸先需要输⼊⾮零元素的个数,然后分别输⼊矩阵的⾏号,列号和值。
输完2个矩阵后,⾃动进⾏计算第⼀个矩阵的转置以及两个矩阵的和。
例如:输⼊如下:100 90 5 //矩阵的⾏数为100,列数为90,共5个⾮零元素。
1 10 100 //a(1,10)=10050 60 200//a(50,60)=20050 80 100//a(50,80)=10060 60 200//a(60,60)=20099 89 10//a(99,89)=10100 90 2 //矩阵b的⾏数为100,列数为90,共2个⾮零元素。
1 1 10 //b(1,1)=1050 60 -200//b(50,60)=-200#include <iostream>using namespace std;struct Triple { //三元组int Row, Col; //⾮零元素⾏号/列号int value; //⾮零元素的值void operator = (Triple & R) //赋值{Row = R.Row; Col = R.Col; value = R.value;}};class SparseMatrix {private: //a = a*bint Rows, Cols, Terms; //⾏/列/⾮零元素数Triple *smArray; //三元组表public:SparseMatrix(int maxSize=100); //构造函数void Transpose(SparseMatrix& B); //转置SparseMatrix Add(SparseMatrix& b); //a = a+bfriend ostream& operator << (ostream& out, SparseMatrix &M);friend istream& operator >> (istream& in, SparseMatrix &M);};SparseMatrix::SparseMatrix(int maxSize){Terms = maxSize;smArray = new Triple[maxSize];Rows = Cols = 0;};void SparseMatrix::Transpose(SparseMatrix & B){int *rowSize = new int[Cols]; //列元素数数组int *rowStart = new int[Cols]; //转置位置数组B.Rows = Cols; B.Cols = Rows;B.Terms = Terms;if (Terms > 0) {int i, j;for (i = 0; i < Cols; i++) rowSize[i] = 0;for (i = 0; i < Terms; i++)rowSize[smArray[i].Col]++;rowStart[0] = 0;for (i = 1; i < Cols; i++)rowStart[i] = rowStart[i - 1] + rowSize[i - 1];for (i = 0; i < Terms; i++) {j = rowStart[smArray[i].Col];B.smArray[j].Row = smArray[i].Col;B.smArray[j].Col = smArray[i].Row;B.smArray[j].value = smArray[i].value;rowStart[smArray[i].Col]++;}}delete[] rowSize; delete[] rowStart;}SparseMatrix SparseMatrix::Add(SparseMatrix & b){SparseMatrix res;int i = 0, j = 0, index_a, index_b;res.Terms = 0;while (i < Terms&&j < b.Terms) {index_a = Cols * smArray[i].Row + smArray[i].Col;index_b = Cols * b.smArray[j].Row + b.smArray[j].Col;if (index_a < index_b) {res.smArray[res.Terms] = smArray[i];i++;}else if (index_a > index_b) {res.smArray[res.Terms] = b.smArray[j];j++;}else{int vv= smArray[i].value + b.smArray[j].value;if (vv != 0) {res.smArray[res.Terms] = smArray[i];res.smArray[res.Terms].value = vv;}if (vv == 0) {res.Terms--;}i++; j++;}res.Terms++;}for (; i < Terms; i++) {res.smArray[res.Terms] = smArray[i];res.Terms++;}for (; j < b.Terms; j++) {res.smArray[res.Terms] = b.smArray[j];res.Terms++;}return res;}ostream & operator<<(ostream & out, SparseMatrix & M){for (int i = 0; i < M.Terms; i++) {out << M.smArray[i].Row << " " << M.smArray[i].Col << " " << M.smArray[i].value << endl; }return out;// TODO: 在此处插⼊ return 语句}istream & operator>>(istream & in, SparseMatrix & M){in >> M.Rows >> M.Cols >> M.Terms;for (int i = 0; i < M.Terms; i++) {in >> M.smArray[i].Row >> M.smArray[i].Col >> M.smArray[i].value;}return in;// TODO: 在此处插⼊ return 语句}int main(){SparseMatrix s,s2,s3,s4;cin >> s;cin >> s3;s.Transpose(s2);cout << "The transformed matrix is:" << endl;cout << s2;s4=s.Add(s3);cout << "The added matrix is:" << endl;cout << s4;return 0;}。
稀疏矩阵压缩的存储方法
稀疏矩阵压缩存储方法是一种针对只有少量非零元素的矩阵进行存储的方法,以减少存储空间。
常见的稀疏矩阵压缩存储方法有三种:
1. COO(Coordinate Representation)坐标表示法:
将非零元素的行、列以及值分别存储起来。
可以用一个三元组的列表来表示,每个三元组包含非零元素的行、列和值。
这种方法的优点是简单直观,适用于非常稀疏的矩阵。
缺点是存储空间相对较大,查找和计算比较复杂。
2. CSR(Compressed Sparse Row)压缩行表示法:
将矩阵的行指针、列索引和非零元素的值分别存储起来。
行指针数组存储每一行的第一个非零元素在值数组中的索引位置,列索引和值数组分别存储每一个非零元素的列索引和值。
这种方法的优点是存储空间较小,查找和计算比较高效。
缺点是构造过程相对复杂,删除或插入元素可能导致数组的重新分配。
3. CSC(Compressed Sparse Column)压缩列表示法:
类似于CSR,只是做了行和列的交换。
列指针数组存储每一列的第一个非零元素在值数组中的索引位置,行索引和值数组分别存储每一个非零元素的行索引和值。
这种方法适用于以列为主要操作的稀疏矩阵运算。
注:以上方法仅是三种常见的压缩存储方法,实际上还有其他一些方法,如DIA (Diagonal)对角线表示法、ELL(Ellpack-Itpack)等,不同的方法适用于不同情况下的稀疏矩阵存储。
稀疏矩阵的压缩存储方法与应用场景稀疏矩阵指的是矩阵中绝大部分元素为0的情况下,只保存非零元素及其对应的坐标的一种存储方式。
相比于一般的矩阵存储方式,稀疏矩阵的压缩存储方法可以有效节省存储空间,并提高运算效率。
本文将介绍一些常见的稀疏矩阵的压缩存储方法以及其应用场景。
一、行压缩存储法(CRS)行压缩存储法(CRS,Compressed Row Storage)是一种经典的稀疏矩阵压缩存储方法。
在CRS中,矩阵的非零元素按行优先的顺序存储,并记录每行非零元素的开始位置及其列号。
由于CRS只存储非零元素及其对应的行列坐标,因此可以大大减少存储空间。
CRS适用于行操作较多的场景,比如图像处理、有限元分析等。
在这些场景下,常常需要对稀疏矩阵进行行操作,例如行相加、行相减、行乘以常数等。
CRS可以通过迅速定位非零元素所在的行并对其进行操作,提高计算效率。
二、列压缩存储法(CCS)列压缩存储法(CCS,Compressed Column Storage)是另一种常见的稀疏矩阵压缩存储方法。
在CCS中,矩阵的非零元素按列优先的顺序存储,并记录每列非零元素的开始位置及其行号。
与CRS相比,CCS可以更加高效地进行列操作,如列相加、列相减、列乘以常数等。
CCS常用于图论、网络分析等领域。
例如,在图论中,常常需要对邻接矩阵进行列操作,如计算图的邻接节点、计算图的度数等。
CCS 可以快速对非零元素所在的列进行操作,提高计算效率。
三、对角线压缩存储法(Diagonal Storage)对角线压缩存储法是一种适用于具有特殊结构的稀疏矩阵的压缩存储方法。
在对角线压缩存储法中,只存储矩阵的非零主对角线元素以及非零副对角线元素,其余元素均为0。
通过存储非零对角线元素及其位置,可以进一步减少存储空间。
对角线压缩存储法适用于具有对称或反对称性质的矩阵。
在数值计算、网络传输等领域,经常需要处理对称或反对称矩阵。
对角线压缩存储法可以有效存储这类特殊结构的矩阵,并提高运算效率。
稀疏矩阵存储方法稀疏矩阵是指矩阵中绝大部分元素为0的矩阵。
在实际问题中,往往会遇到大规模的稀疏矩阵,对于这种矩阵的存储需要考虑如何高效地使用内存空间。
下面将介绍几种常见的稀疏矩阵存储方法。
1. 链接存储法:在这种方法中,我们可以使用一个链表来存储非零元素的位置和值。
具体做法是每个非零元素都使用一个结点来表示,结点中包括行、列和对应的元素值。
这样,对于每个非零元素,我们只需要包含它的位置信息和值即可,并且可以通过遍历链表来获取所有的非零元素。
2. 顺序表存储法:在顺序表存储法中,我们使用两个数组来保存非零元素的位置和值。
一个一维数组存储所有非零元素的位置,另一个一维数组存储对应的值。
在这种方法中,我们需要额外的辅助空间来保存非零元素的位置信息,但是对于获取元素值的操作会更加高效,因为我们可以直接通过索引来访问元素。
3. 排序顺序表存储法:与顺序表存储法类似,不同之处在于我们需要对非零元素的位置进行排序。
一种常见的排序方法是按照行优先顺序进行排序。
这样做的好处是在矩阵乘法运算等操作中,我们可以利用行优先的顺序,减少对非零元素的访问次数,从而提高运算效率。
4. 压缩存储法:在压缩存储法中,我们通过记录每行非零元素的数量以及每个非零元素的位置和值来表示稀疏矩阵。
具体做法是使用三个一维数组分别存储每行非零元素的数量、非零元素的列索引和对应的值。
这种方法可以极大地节省存储空间,并且对于访问非零元素的操作也很高效。
以上介绍的是几种常见的稀疏矩阵存储方法,它们各自的特点和适用场景也不同。
选择何种存储方法应该根据具体应用的需求来确定。
例如,在求解线性方程组或稀疏矩阵乘法运算时,可以选择压缩存储法;而在矩阵的插入、删除操作较为频繁时,可以考虑使用链表存储法。
总之,在实际应用中,我们需要根据问题的特点和存储空间的要求,综合考虑各种因素来选择最合适的存储方法。
第4讲稀疏矩阵压缩存储下——教学讲义“列序”递增转置法的思考:采用稀疏矩阵存储方法,可否降低时间复杂度?(提示:通过降低对稀疏矩阵三元组的扫描次数实现)方法二:“一次定位快速转置”法【算法思想】在方法一中,为了使转置后矩阵的三元组表B仍按“行序递增”存放,必须多次扫描被转置矩阵的三元组表A,以保证按被转置矩阵列序递增进行转置。
因此要通过双重循环来完成。
改善算法的时间性能,必须去掉双重循环,使整个转置过程通过一重循环来完成,即只对被转置矩阵的三元组表A扫描一次,就使A中所有非零元的三元组“一次定位”直接放到三元组表B的正确位置上。
为了能将被转置三元组表A中的元素一次定位到三元组表B的正确位置上,需要预先计算以下数据:( 1 )待转置矩阵三元组表A每一列中非零元素的总个数(即转置后矩阵三元组表B的每一行中非零元素的总个数)。
( 2 )待转置矩阵每一列中第一个非零元素在三元组表B中的正确位置(即转置后矩阵每一行中第一个非零元素在三元组表B中的正确位置)。
为此,需要设两个数组分别为num[]和position[]。
其中num[ col]用来存放三元组表A第col列中非零元素总个数(三元组表B第col行中非零元素的总个数)。
position[ col]用来存放转置前三元组表A中第col列(转置后三元组表B中第col行)中第一个非零元素在三元组表B中的存储位置(下标值)。
num[ col]的计算方法:将三元组表A扫描一遍,对于其中列号为col的元素,给相应的num 数组中下标为col的元素加1 。
说明:在num[ col]的计算中,采用了“数组下标计数法”。
position[ col]的计算方法:①position[ 1 ]=1 ,表示三元组表A中,列值为1的第一个非零元素在三元组表B中的下标值;②position[ col]=position[ col-1 ]+num[ col-1 ]。
其中2 ≤col≤A.n。
稀疏矩阵压缩对于那些零元素数⽬远远多于⾮零元素数⽬,并且⾮零元素的分布没有规律的矩阵称为稀疏矩阵(sparse)。
⼈们⽆法给出稀疏矩阵的确切定义,⼀般都只是凭个⼈的直觉来理解这个概念,即矩阵中⾮零元素的个数远远⼩于矩阵元素的总数,并且⾮零元素没有分布规律。
由于稀疏矩阵中⾮零元素较少,零元素较多,因此可以采⽤只存储⾮零元素的⽅法来进⾏压缩存储。
由于⾮零元素分布没有任何规律,所以在进⾏压缩存储的时侯需要存储⾮零元素值的同时还要存储⾮零元素在矩阵中的位置,即⾮零元素所在的⾏号和列号,也就是在存储某个元素⽐如aij的值的同时,还需要存储该元素所在的⾏号i和它的列号j,这样就构成了⼀个三元组(i,j,aij)的线性表。
package example;public class Test{public static void main(String[] args) {int rows=6;int cols=6;int n=8;int[][] A={{25,0,0,32,0,-25},{0,33,77,0,0,0},{0,0,0,55,0,0},{0,0,0,0,0,0},{101,0,0,0,0,0},{0,0,38,0,0,0}};int[][] B=new int[n+1][3];B[0][0]=rows; //表⽰此矩阵的⾏数B[0][1]=cols; //表⽰此矩阵的列数B[0][2]=n; //表是⾮零的数⽬yasuo(A,B,rows,cols);for(int i=0;i<n+1;i++){for(int j=0;j<3;j++)System.out.print(B[i][j]+"\t");System.out.println();}}private static void yasuo(int[][] A, int[][] B, int rows, int cols) {int k=1;for(int i=0;i<rows;i++){for(int j=0;j<cols;j++){if(A[i][j]!=0){B[k][0]=i+1;B[k][1]=j+1;B[k][2]=A[i][j];k++;}}}}}/*6 6 81 1 251 4 321 6 -252 2 332 3 773 4 555 1 1016 3 38*/。
稀疏矩阵压缩的存储方法是稀疏矩阵压缩是一种数据结构,可以有效地占用存储空间,合理地存储稀疏矩阵。
通常来说,稀疏矩阵的元素大部分为0,只有少部分非零,所以采用压缩存储方法可以大大减少存储空间的使用。
稀疏矩阵的压缩存储方法有三种:顺序表压缩、链表压缩和十字链表压缩。
下面将对这三种方法进行详细介绍。
1.顺序表压缩方法:顺序表压缩方法是使用一个一维数组来存储稀疏矩阵。
数组的第一行存储矩阵的行数、列数、非零元素的个数。
数组的后续元素按行优先顺序存储矩阵的每一个非零元素。
例如,对于一个3*3的稀疏矩阵:1 0 00 0 23 0 0它的顺序表压缩形式为:3 3 2 第一行分别为行数、列数和非零元素个数1 1 1 第1个非零元素在第1行第1列,值为12 3 2 第2个非零元素在第2行第3列,值为23 1 3 第3个非零元素在第3行第1列,值为3在这个例子中,非零元素的个数为3,而原先需要占据9个空间的矩阵,现在只需要使用7个元素的数组就可以存储。
2.链表压缩方法:链表压缩方法首先将稀疏矩阵存储在单链表中。
单链表中的每一个节点包含4个数据域:行数,列数,元素值和指针域。
其中,指针域指向下一个非零元素节点。
例如,对于一个5*5的稀疏矩阵:0 0 0 0 03 0 0 0 00 0 1 0 00 0 0 2 00 0 0 0 0它的链表表示形式如下:(1,2,3)->(2,1,3)->(3,3,1)->(4,4,2)其中,每个元素依次表示行数、列数和元素值。
指针域则指向下一个非零元素。
相对于顺序表压缩,链表压缩更适用于稀疏矩阵比较大时,且存在大量的非零元素。
因为链表压缩能够动态分配存储空间,可以严格掌控存储空间的使用效率。
3.十字链表压缩方法:十字链表压缩是一种特殊的链表压缩方式,因为它在存储矩阵的同时,能够比较直观地表示矩阵的结构信息。
下面是一个矩阵以十字链表方式存储的示例:首先,将矩阵按行、列分别建立链表。
稀疏矩阵及其压缩存储方法1.基本概念稀疏矩阵(SparseMatrix):是矩阵中的一种特殊情况,其非零元素的个数远小于零元素的个数。
设m行n列的矩阵含t个非零元素,则称以二维数组表示高阶的稀疏矩阵时,会产生零值元素占的空间很大且进行了很多和零值的运算的问题。
特殊矩阵:值相同的元素或0元素在矩阵中的分布有一定的规律。
如下三角阵、三对角阵、稀疏矩阵。
压缩存储:为多个值相同的元素只分配一个存储空间;对0元素不分配空间。
目的是节省大量存储空间。
n x n的矩阵一般需要n2个存储单元,当为对称矩阵时需要n(1+n)/2个单元。
2.三元组顺序表——压缩存储稀疏矩阵方法之一(顺序存储结构)三元组顺序表又称有序的双下标法,对矩阵中的每个非零元素用三个域分别表示其所在的行号、列号和元素值。
它的特点是,非零元在表中按行序有序存储,因此便于进行依行顺序处理的矩阵运算。
当矩阵中的非0元素少于1/3时即可节省存储空间。
(1)稀疏矩阵的三元组顺序表存储表示方法#define MAXSIZE 12500 // 假设非零元个数的最大值为12500typedef struct {int i, j; // 该非零元的行下标和列下标ElemType e; //非零元素的值} Triple; // 三元组类型typedef union { //共用体Triple data[MAXSIZE + 1]; // 非零元三元组表,data[0]未用int mu, nu, tu; // 矩阵的行数、列数和非零元个数} TSMatrix; // 稀疏矩阵类型(2)求转置矩阵的操作◆用常规的二维数组表示时的算法for (col=1; col<=nu; ++col)for (row=1; row<=mu; ++row)T[col][row] = M[row][col];其时间复杂度为: O(mu×nu)◆用三元组顺序表表示时的快速转置算法Status FastTransposeSMatrix(TSMatrix M, TSMatrix &T) {// 采用三元组顺序表存储表示,求稀疏矩阵M的转置矩阵TT.mu = M.nu; 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];// 求M 中每一列所含非零元的个数cpot[1] = 1;for (col=2; col<=M.nu; ++col) cpot[col] = cpot[col-1] + num[col-1];// 求M 中每一列的第一个非零元在b.data 中的序号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];} // for} // ifreturn OK;} // FastTransposeSMatrix其时间复杂度为: O(mu +nu)3.行逻辑联接的顺序表——压缩存储稀疏矩阵方法之二(链接存储结构)行逻辑联接的顺序表:稀疏矩阵中为了随机存取任意一行的非0元素,需要知道每一行的第一个非0元素在三元组表中的位置,因此将上述快速转置算法中指示行信息的辅助数组cpot 固定在稀疏矩阵的存储结构中,让每一行对应一个单链表,每个单链表都有一个表头指针,这种“带行链接信息”的三元组表即称为行逻辑联接的顺序表。
稀疏矩阵算法
稀疏矩阵是指矩阵中大部分元素都为零的矩阵。
在实际应用中,很多矩阵都是稀疏矩阵,例如图像处理中的像素矩阵、文本处理中的词频矩阵等。
由于稀疏矩阵中大部分元素都为零,因此常规的矩阵算法会浪费大量时间和空间。
为了高效地处理稀疏矩阵,我们需要使用稀疏矩阵算法。
稀疏矩阵算法可以分为压缩存储和稀疏矩阵运算两部分。
压缩存储是指将稀疏矩阵中的非零元素存储起来,而忽略掉零元素。
常见的压缩存储方式有三种:行压缩存储法(CRS)、列压缩存储法(CCS)和对角线存储法。
其中,CRS和CCS是最常用的两种压缩存储方式。
在CRS中,非零元素按照行的顺序进行存储,同时需要记录每一行的起始位置和非零元素个数。
在CCS中,非零元素按照列的顺序进行存储,同时需要记录每一列的起始位置和非零元素个数。
对角线存储法则是将稀疏矩阵的对角线元素存储下来,其余的非零元素按照行的顺序存储。
稀疏矩阵运算是指对稀疏矩阵进行各种运算,包括加、减、乘、转置、求逆等。
其中,稀疏矩阵乘法是应用最广泛的运算。
稀疏矩阵乘法的基本思想是通过压缩存储方式将矩阵中的非零元素存储下来,然后利用矩阵乘法的基本性质进行计算,最后将结果存储在稀疏矩阵中。
总之,稀疏矩阵算法可以大大提高对稀疏矩阵进行计算的效率。
在实际应用中,我们需要根据具体情况选择合适的压缩存储方式和运
算方法,以达到最佳性能。
稀疏矩阵存储格式
稀疏矩阵存储格式是一种优化矩阵存储的方式,适用于大部分元素为0的稀疏矩阵。
常见的稀疏矩阵存储格式包括三种:
1. COO(Coordinate List)格式:将非零元素的行列坐标和对
应的数值存储在三个单独的数组中。
2. CSR(Compressed Sparse Row)格式:将稀疏矩阵按行压缩存储,使用三个数组存储非零元素的数值、列索引和行偏移量。
3. CSC(Compressed Sparse Column)格式:将稀疏矩阵按列
压缩存储,使用三个数组存储非零元素的数值、行索引和列偏移量。
这些存储格式的选择取决于矩阵的稀疏性、操作的类型以及具体应用场景。
通过采用稀疏矩阵存储格式,可以节省存储空间并提高矩阵运算效率。
第3讲 稀疏矩阵压缩存储上——教学讲义稀疏矩阵是指矩阵中大多数元素为零的矩阵。
从直观上讲,当非零元素个数低于总元素的30 %时,这样的矩阵为稀疏矩阵。
如下图所示的矩阵M 、 N 中,非零元素个数均为8个,矩阵元素总数均为6 ×7 =42 ,显然8 /42 <30 %,所以M 、 N 都是稀疏矩阵。
1 稀疏矩阵的三元组表表示法 ( 1 ) 稀疏矩阵的三元组存储表示对于稀疏矩阵的压缩存储,采取只存储非零元素的方法。
由于稀疏矩阵中非零元素aij 的分布没有规律 ,因此,要求在存储非零元素值的同时还必须存储该非零元素在矩阵中所处的行号和列号的位置信息,这就是稀疏矩阵的三元组表表示法。
每个非零元素在一维数组中的表示形式如下图所示。
说明:为处理方便,将稀疏矩阵中非零元素对应的三元组按“行序为主序”用一维结构体数组进行存放,将矩阵的每一行(行由小到大)的全部非零元素的三元组按列号递增存放。
由此得到矩阵M 、 N 的三元组表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 0M=6×7 0 0 -3 0 0 15 12 0 0 0 18 0 9 0 0 24 0 0 00 0 0 0 -7 0 0 0 0 0 0 00 14 0 0 0 00 0 0 0 07×6N= 稀疏矩阵M 和N三元组的结构( 2 )稀疏矩阵三元组表的类型定义 稀疏矩阵三元组表类型定义如下:#define MAXSIZE 1000 /*设非零元素的个数最多为1000*/ typedef struct { int row, col; /*该非零元素的行下标和列下标*/ ElementType e ; /*该非零元素的值*/ }Triple; typedef struct{ Triple data[MAXSIZE+1]; /* 非零元素的三元组表。
大型稀疏矩阵的优化压缩存储技术及其应用
随着科技的不断发展和应用,大型稀疏矩阵的应用逐渐增加。
然而,大型稀疏矩阵在存储时会占用大量的空间,导致存储和计算成本高。
因此,如何优化大型稀疏矩阵的存储是一个需要解决的问题。
优化稀疏矩阵存储的常见方法是稀疏矩阵压缩存储技术,该技术
可以通过将矩阵中的零元素进行压缩,从而降低存储空间。
现在,主
要有三种存储格式:COO格式、CSR格式以及CSC格式。
COO格式是最简单的稀疏矩阵压缩格式,它把非零元素的行列坐
标和对应的数值存储在一个三元组中。
COO格式具有灵活性和简单性,但是由于存在大量的重复行和列,会浪费大量的存储空间。
CSR格式和CSC格式是针对COO格式的优化,它们分别按照行和
列的顺序存储矩阵的非零元素,并记录每行或每列非零元素的个数和
起始位置。
这种方式比COO格式更加高效,可以大幅度减少存储空间。
然而,这两种格式的存储方法都有一定的局限性,因此现在还有其他
一些稀疏矩阵存储格式,如LIL,JDS等。
大型稀疏矩阵优化压缩存储技术的应用范围非常广泛,如科学计算、图谱算法、机器学习等都有它的应用。
例如,在机器学习中,稀
疏矩阵存储格式可以用来存储大型的文本数据和特征向量,以便进行
文本挖掘和分类等任务。
同时,它还可以被用于处理搜索引擎、社交
网络和图像识别等领域的数据。
总之,大型稀疏矩阵的优化压缩存储技术是十分重要的技术,可
以大幅度降低存储和计算成本,同时提高速度和效率。
随着科技的不
断发展和应用,这一技术将会在更多的领域得到应用。
稀疏矩阵的存储与压缩稀疏矩阵是指其中大部分元素为0的矩阵。
由于矩阵中存在大量的0元素,因此在存储和处理稀疏矩阵时,采用传统的二维数组存储方式会造成大量的存储空间浪费和计算时间过长。
为了高效地存储和处理稀疏矩阵,人们提出了各种稀疏矩阵的存储与压缩方法。
一、压缩存储稀疏矩阵的压缩存储方法主要包括行压缩存储(CSR)、列压缩存储(CSC)和对角线压缩存储(DIA)等。
1. 行压缩存储(CSR)行压缩存储是将稀疏矩阵的非零元素按行存储在一维数组中,并使用两个数组存储每一行的非零元素和其所在的列索引。
举个例子,假设有一个3×3的稀疏矩阵,其非零元素分别为a(1,2)=5、a(2,1)=3、a(2,3)=7和a(3,2)=4,那么行压缩存储的结果为:values = [5, 3, 7, 4]columns = [2, 1, 3, 2]row_pointers = [0, 1, 3, 4]其中values数组存储了非零元素的值,columns数组存储了非零元素所在的列索引,row_pointers数组存储了每一行的非零元素在values 和columns数组中的起始位置。
该压缩存储方法可以有效地节省存储空间,并且便于进行行遍历。
2. 列压缩存储(CSC)列压缩存储与行压缩存储类似,只是将稀疏矩阵的非零元素按列存储在一维数组中,并使用两个数组存储每一列的非零元素和其所在的行索引。
同样以上述的稀疏矩阵为例,列压缩存储的结果为:values = [3, 5, 7, 4]rows = [2, 1, 2, 3]column_pointers = [0, 1, 3, 4]其中values数组存储了非零元素的值,rows数组存储了非零元素所在的行索引,column_pointers数组存储了每一列的非零元素在values 和rows数组中的起始位置。
列压缩存储方法在列遍历时具有较好的性能。
3. 对角线压缩存储(DIA)对角线压缩存储适用于具有某种特定结构的稀疏矩阵,例如对角线稀疏矩阵等。
稀疏矩阵压缩的存储方法稀疏矩阵是在大多数元素为零的矩阵中只存储非零元素的一种矩阵表示方法。
稀疏矩阵压缩的存储方法旨在减少内存和存储空间的占用,同时保持矩阵的有效性。
以下是一些常见的稀疏矩阵压缩存储方法:1.压缩行存储(Compressed Row Storage,CRS):该方法将矩阵分为三个数组:值数组、列索引数组和行偏移数组。
值数组存储非零元素的值。
列索引数组存储每个非零元素所在的列索引。
行偏移数组存储每一行的第一个非零元素在值数组中的位置。
这种方法适用于稀疏矩阵中非零元素的分布较为均匀的情况。
2.压缩列存储(Compressed Column Storage,CCS):与CRS相似,但它将列作为主要的单位进行压缩。
值数组、行索引数组和列偏移数组分别存储非零元素的值、行索引和每一列的第一个非零元素在值数组中的位置。
这种方法适用于需要按列进行操作的情况。
3.坐标列表(COO):COO方法以三个数组的形式存储稀疏矩阵的非零元素:行索引、列索引和值。
这种方法的优势在于可以方便地添加和删除元素,但对于大型稀疏矩阵可能会浪费大量内存。
4.对角线存储(Diagonal Storage):如果稀疏矩阵是对称的,并且只存储对角线上和它下面的元素,这种存储方法可能非常有效。
只需存储对角线元素和它们的下面的元素,而忽略上面的元素。
5.分层压缩(Hierarchical Storage):对于大型稀疏矩阵,可以将矩阵分成多个较小的块,并使用其他稀疏矩阵压缩方法对每个块进行单独压缩。
这种方法有助于减小每个块的大小,从而提高存储和检索效率。
选择适当的稀疏矩阵压缩方法取决于矩阵的特点、应用需求和存储资源。
不同的方法在内存占用和操作效率方面都有各自的优劣。
根据具体情况,可以选择最适合的方法以最大程度地减小存储空间。
对稀疏矩阵结构的操作稀疏矩阵是一种特殊的矩阵结构,其大部分元素为0,只有少部分非零元素。
由于稀疏矩阵的特殊性,对其进行操作时需要采用特定的方法和算法。
本文将介绍几种常见的对稀疏矩阵进行操作的方法。
一、稀疏矩阵的存储方式稀疏矩阵的存储方式有多种,常见的有三元组表示法和压缩存储方式。
三元组表示法是将非零元素的行、列和值分别存储在三个数组中,这种存储方式简单直观,但是对于大规模稀疏矩阵来说,空间占用较大。
压缩存储方式则是将稀疏矩阵按行或按列进行压缩存储,只存储非零元素的位置和值,可以大大减小空间占用。
二、稀疏矩阵的加法和减法对于稀疏矩阵的加法和减法,可以采用三元组表示法或压缩存储方式。
首先需要将两个矩阵转换为相同的存储方式,然后按照矩阵的行列进行遍历,将对应位置的元素进行加法或减法操作。
在遍历过程中,需要注意处理非零元素的情况,可以采用稀疏矩阵的存储结构进行判断和处理。
三、稀疏矩阵的乘法稀疏矩阵的乘法是一种复杂的运算,涉及到矩阵的行列遍历和乘法操作。
对于两个稀疏矩阵的乘法,可以采用三元组表示法或压缩存储方式。
首先需要将两个矩阵转换为相同的存储方式,然后按照矩阵的行列进行遍历,对于每个非零元素,需要找到对应位置的元素进行乘法操作,并将结果累加。
在遍历过程中,可以采用稀疏矩阵的存储结构进行优化,减少不必要的运算。
四、稀疏矩阵的转置稀疏矩阵的转置是将矩阵的行和列进行互换,对于稀疏矩阵,可以采用三元组表示法或压缩存储方式进行转置。
对于三元组表示法,只需要将行和列进行互换即可;对于压缩存储方式,只需要将行和列的索引进行互换,并按照转置后的行列顺序重新排列非零元素。
五、稀疏矩阵的求逆稀疏矩阵的求逆是一种复杂的运算,需要借助于线性代数的知识和算法。
对于稀疏矩阵的求逆,可以采用LU分解、LDU分解或Cholesky分解等方法。
这些方法可以将稀疏矩阵分解为三个矩阵的乘积,然后再求解逆矩阵。
在求解过程中,需要注意处理稀疏矩阵的特殊结构,以提高求解的效率。
稀疏矩阵的压缩存储及运算一、实验内容实现稀疏矩阵的压缩存储方法以及在特定存储方法下的基本运算二、实验母的掌握数组的应用,包括稀疏矩阵、特殊矩阵的压缩存储方法。
矩阵的基本运算的实现,包括矩阵相加、转置、乘法等。
三、问题描述1)用行逻辑链接顺序表和十字链表分别实现稀疏矩阵的压缩存储2)编程实现矩阵的转置运算和乘法运算(运用行逻辑链接顺序表或十字链表作为存储结构)四、问题的实现稀疏矩阵的抽象数据类型定义:ADT SpareseMatrix{数据对象:;,,2,1;,,2,1|{n j m i D a ij ===},,列数分别称为矩阵的行数和和n m ElemSet a j i ∈数据关系: :}1,11|,{}11,1|,{},{,1,1,,n j m i Col n j m i Row Col Row R a a a a j i j i j i j i ≤≤-≤≤><=-≤≤≤≤><==++基本操作:CreateSMatrix(&M);操作结果:创建稀疏矩阵M 。
PrintSMatrix(M);初始条件:稀疏矩阵M 存在。
操作结果:输出稀疏矩阵M 。
AddSMatrix(M ,N ,&Q);初始条件:稀疏矩阵M 和N 的行数和列数对应相等。
操作结果:求稀疏矩阵的和Q=M+N 。
MultSMatrix(M ,N ,&Q);初始条件:稀疏矩阵M 的列数等于N 的行数。
操作结果:求稀疏矩阵乘积Q=M*N 。
TransposeSMatrix(M,&T);初始条件:稀疏矩阵M 存在。
操作结果:求稀疏矩阵M 的转置矩阵T 。
}ADT SpareseMatrix五、主要源程序代码#include <iostream>using namespace std;#define MAXSIZE 100;typedef struct OLNode{int i,j;int e;struct OLNode *right,*down;}OLNode,*OLink;typedef struct{OLink *rhead,*chead;int mu,nu,tu;}CrossList; //十字链表结构体定义int CreatSMatrix_OL(CrossList &M){int i,j,e;OLink q;OLink p;cout<<"请输入稀疏矩阵的行数,列数,非零元素的个数:";cin>>M.mu;cin>>M.nu;cin>>M.tu;M.rhead=(OLink *)malloc((M.mu+1)*sizeof(OLNode));M.chead=(OLink *)malloc((M.nu+1)*sizeof(OLNode));for(i=1;i<=M.mu;i++) M.rhead[i]=NULL;for(i=1;i<=M.nu;i++) M.chead[i]=NULL;cout<<"请输入稀疏矩阵,若为空,则退出"<<endl;cin>>i;cin>>j;cin>>e;while (i!=0){p=(OLink)malloc(sizeof(OLNode));p->i=i;p->j=j;p->e=e;if (M.rhead[i]==NULL || M.rhead[i]->j>j) {p->right=M.rhead[i];M.rhead[i]=p;}else{q=M.rhead[i];while (q->right && q->right->j<j)q=q->right;p->right=q->right;q->right=p;}if (M.chead[j]==NULL || M.chead[j]->i>i) {p->down=M.chead[j];M.chead[j]=p;}else{q=M.chead[j];while (q->down && q->down->i<i)q=q->down;p->down=q->down;q->down=p;}cin>>i;cin>>j;cin>>e;}} //创建十字链表void TurnSMatrix_OL(CrossList &M){int a,b;OLink p,q;for(a<1;a<=M.mu;a++){q=p=M.rhead[a];while(q){b=p->i;p->i=p->j;p->j=b;q=p->right;p->right=p->down;p->down=q;}}} //十字链表实现稀疏矩阵转置int AddSMatrix_OL(CrossList *A,CrossList *B){OLNode *pa,*pb,*p,*pre,*cp[100];int i,j,t;t=A->tu+B->tu;for(j=1;j<=A->nu;j++) cp[j]=A->chead[j];for(i=1;i<=A->mu;i++){pa=A->rhead[i];pb=B->rhead[i];pre=NULL;while(pb){if(pa==NULL || pa->j>pb->j){p=(OLink)malloc(sizeof(OLNode));if(!pre)A->rhead[i]=p;else pre->right=p;p->right=pa;pre=p;p->i=i;p->j=pb->j;p->e=pb->e;if(!A->chead[p->j]){A->chead[p->j]=cp[p->j]=p;p->down=NULL;}else{cp[p->j]->down=p;cp[p->j]=p;}pb=pb->right;}else if(pa->j<pb->j) {pre=pa;pa=pa->right;}else if(pa->e+pb->e){t--;pa->e+=pb->e;pre=pa;pa=pa->right;pb=pb->right;}else{t=t-2;if(!pre)A->rhead[i]=pa->right;else pre->right=pa->right;p=pa;pa=pa->right;if(A->chead[p->j]==p) A->chead[p->j]=cp[p->j]=p->down;else cp[p->j]->down=p->down;free(p);pb=pb->right;}}}A->mu=A->mu>B->mu? A->mu:B->mu;A->nu=A->nu>B->nu? A->nu:B->nu;return 1;} //十字链表实现两稀疏矩阵相加int MultSMatrix_OL(CrossList M,CrossList N,CrossList &Q){int i,j,e;OLink p0,q0,p,p1,p1a;if(M.nu!=N.mu){cout<<"稀疏矩阵A的列数和B的行数不相等,不能相乘";return 0;}Q.mu=M.mu;Q.nu=N.nu;Q.tu=0;if(!(Q.rhead=(OLink *)malloc((Q.mu+1)*sizeof(OLink))))exit(-2);if(!(Q.chead=(OLink *)malloc((Q.nu+1)*sizeof(OLink))))exit(-2);for(i=1;i<=Q.mu;i++) Q.rhead[i]=NULL;for(i=1;i<=Q.nu;i++) Q.chead[i]=NULL;for(i=1;i<=Q.mu;i++)for(j=1;j<=Q.nu;j++){p0=M.rhead[i];q0=N.chead[j];e=0;while(p0 && q0){if(p0->j>q0->i) q0=q0->down;else if(p0->j<q0->i) p0=p0->right;else{e+=p0->e*q0->e;q0=q0->down;p0=p0->right;}}if(e){if(!(p=(OLink)malloc(sizeof(OLNode))))exit(-2);Q.tu++;p->i=i;p->j=j;p->e=e;p->right=NULL;p->down=NULL;if(Q.rhead[i]==NULL)Q.rhead[i]=p1=p;else p1->right=p;p1=p;if(Q.chead[j]==NULL)Q.chead[j]=p;else{p1a=Q.chead[j];while(p1a->down)p1a=p1a->down;p1a->down=p;}}}return 1;} //十字链表实现两稀疏矩阵相乘int ShowSMatrix(CrossList *A){int a;OLink p;for(a=1;a<=A->mu;a++)if(A->rhead[a]) {p=A->rhead[a];}while(p){printf("%3d%3d%3d\n",p->i,p->j,p->e);p=p->right;}return 1;} //十字链表显示void main(){int n;char c;CrossList MM,TT,SS;CreatSMatrix_OL(MM);cout<<"您输入的稀疏矩阵(只列出非零元素):"<<endl;cout<<"行列大小"<<endl;ShowSMatrix(&MM);cout<<"请选择操作:"<<endl;cout<<"1:实现稀疏矩阵的转置"<<endl;cout<<"2:实现两稀疏矩阵的相加"<<endl;cout<<"3:实现两稀疏矩阵的相乘"<<endl;cout<<"4:退出程序"<<endl;cin>>n;switch(n){case 1:TurnSMatrix_OL(MM);cout<<"转置后的稀疏矩阵:行列大小"<<endl;ShowSMatrix(&MM);break;case 2:cout<<"请输入另一个稀疏矩阵:"<<endl;CreatSMatrix_OL(TT);AddSMatrix_OL(&MM,&TT);cout<<"相加后的矩阵为:"<<endl;ShowSMatrix(&MM);break;case 3:cout<<"请输入另一个稀疏矩阵:"<<endl;CreatSMatrix_OL(TT);MultSMatrix_OL(MM,TT,SS);cout<<"相乘后的矩阵为:"<<endl;ShowSMatrix(&SS);break;case 4:exit(0);default:cout<<"error!"<<endl;}system("pause");}六、总结整个实验中学会了稀疏矩阵的压缩存储方法,用十字链表来存储,以及在特定存储方法下的基本运算。