用三元组存储稀疏矩阵及其快速转置
稀疏矩阵的三元组存储方式
稀疏矩阵可以用一个三元组数组表示,数组每个元素是一个三元组,三元组形式为
(矩阵行号,矩阵列号,元素值)
三元组个数,即数组长度,为稀疏矩阵的非零元素个数。
三元组元素按照行号递增,列号递增的方式排序。
例如矩阵M:
[
1
0
0
0
0
0
0
2
0
]
\begin{bmatrix} 1 & 0 & 0 \\ 0 & 0 & 0 \\ 0 & 2 & 0 \end{bmatrix}
⎣⎡100002000⎦⎤
对应的的三元组数组为:
(0,0,1)
(2,1,2)
快速转置算法
输入:原矩阵A的三元组数组
输出:原矩阵的转置矩阵B的三元组数组
转置相当于把A的三元组数组每个元素的行列交换,然后按照列递增,行递增的顺序重排,从而算法类似于桶排序,将列相同的三元组按它们在A矩阵的三元组数组中的先后顺序放到同一个桶中,所有桶按列号从小到大排。从而需要两个大小均为矩阵A列数的数组row_size和row_start,row_size记录每个桶的大小,row_start记录每个桶下一个存进来的元素在B矩阵的三元组数组中的下标,每在桶中放入一个元素,下标自增以存放下一个元素。
例如矩阵M:
[
1
0
0
0
0
0
0
0
2
0
0
0
0
0
0
0
3
0
0
0
0
0
4
5
0
]
\begin{bmatrix} 1 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 2 & 0 \\ 0 & 0 & 0 & 0 & 0 \\ 0 & 3 & 0 & 0 & 0 \\ 0 & 0 & 4 & 5 & 0 \end{bmatrix}
⎣⎢⎢⎢⎢⎡1000000030000040200500000⎦⎥⎥⎥⎥⎤
对应的三元组数组变为其转置矩阵的三元组数组:

row_size数组为{1,1,1,2,0},初始的row_start数组为{0,1,2,3,5}
列数相同则颜色相同,一个颜色即为一个“桶”,也就是转置矩阵一行的所有非零元素,将每种颜色按列号从小到大排序,由于在原数组中就是按行号递增的顺序存放,所以同种颜色的三元组顺序保持不变。
预先定义两个数组row_size, row_start分别存储B每行的非零元素个数和当前
非零元素在三元组数组中的下标,row_size数组所有元素初始化为0
elements_A: A的三元组数组
elements_B: B的三元组数组
col_num: A的列数,B的行数,也是桶的个数
// 统计每个桶的大小,即B每行非零元素个数
1、对elements_A中每个元素triple:
row_size[triple.col]++
// 计算B每行非零元素在elements_B中的初始下标
2、对row_start数组中的第i(i从1到col_num-1)个元素:
row_start[i] = row[start[i-1] + row_size[i-1]
// 遍历elements_A,将其放入elements_B中对应的桶中
3、对elements_A中的每个元素triple:
// B中对应三元组就是把triple的行号列号交换,值不变
elements_B[row_start[triple.col]].col = triple.row
elements_B[row_start[triple.col]].row = triple.col
elements_B[row_start[triple.col]].value = triple.value
// 桶中下一元素的下标
row_start[triple.col]++
代码
实现代码在这里的sparse_matrix_transpose.cpp,其中头文件是myheaders文件夹中的sparse_matrix.transpose.h
本文详细介绍了稀疏矩阵的三元组存储方式,以及如何利用该方式快速实现矩阵转置的算法。通过实例展示了三元组数组的构建与转置过程,解释了使用额外数组优化转置效率的方法。
1693

被折叠的 条评论
为什么被折叠?



