稀疏矩阵之基于数组形式实现COO和CSR
前言
- 语言:Java
- 环境:IntelliJ IDEA
- JDK版本:1.8
- 源码:GitHub
- 参考文章:https://www.cnblogs.com/xbinworld/p/4273506.html
什么是稀疏矩阵
在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵;与之相反,若非0元素数目占大多数时,则称该矩阵为稠密矩阵。定义非零元素的总数比上矩阵所有元素的总数为矩阵的稠密度。
例如下面的矩阵:
由于稀疏矩阵中重复的0非常多,因此在存储稀疏矩阵时非常有必要对其压缩,下面介绍了几种常用的稀疏矩阵存储格式。
存储格式
COO格式
COO(Coordinate):仅存储非0数据的行、列、值 这种存储方式虽然简单,但会存在行或列重复出现的情况,这些重复值也需要被压缩。
编码流程:
- 压缩
- 遍历矩阵,获取所有非0数据个数
- 记录原矩阵的总行数、总列数、非0数据个数
- 通过获取的非0数据个数初始化压缩后的数据行数,列数为3,分别为row、column、value
- 再次遍历矩阵,将非0数据所在的行、列、值进行存储
- 解压
- 用记录的总行数、总列数初始化原矩阵
- 用非0数据个数为循环次数逐行还原矩阵
public class COO {
private int rows; //保存原矩阵总行数
private int columns; //保存原矩阵总列数
private int sum; //保存总有效数据个数
private int[][] data; //压缩后的数据
//省略get和set方法
}
public class COOUtils {
/**
* 通过COO将原矩阵压缩,并返回压缩后数据
*/
public static COO process(int rows,int columns,int[][] source){
COO coo = new COO(); //要返回的数据
coo.setRows(rows);
coo.setColumns(columns);
int count = 0;
for (int i = 0;i
CSR/CSC格式
CSR(Compressed Sparse Row):仅存储非0数据的列、值、行偏移。行偏移是指每行的第一个非0数在值(value)中的位置
CSC(Compressed Sparse Column):仅存储非0数据的行、值、列偏移。列偏移是指每列的第一个非0数在值(value)中的位置
当使用COO时,若重复行过多,则可以使用CSR来忽略行;若重复列过多,则可以使用CSC忽略列
编码流程:
- 压缩
- 遍历矩阵,获取所有非0数据个数
- 记录原矩阵的总行数、总列数、非0数据个数
- 通过获取的非0数据个数初始化压缩后的数据行数,列数为2,分别为column、value
- 再次遍历矩阵,将非0数据所在的行、列、值进行存储
- 通过value计算出行偏移并存储
- 解压
- 用记录的总行数、总列数初始化原矩阵
- 用非0数据个数为循环次数逐行还原矩阵,还原同时需要通过记录的行偏移控制行
行偏移在解压该过程中可以理解为:忽略行的存在,顺序还原数据,行偏移的值就是当循环到这个值时进行换行
public class CSR {
private int rows; //保存原矩阵总行数
private int columns; //保存原矩阵总列数
private int sum; //保存总有效数据个数
private int[] rowOffset; //保存行偏移
private int[][] data; //保存列、值
//get、set方法省略
}
public class CSRUtils {
/**
* 通过CSR将原矩阵压缩,并返回压缩后数据
*/
public static CSR process(int rows,int columns,int[][] source){
CSR csr = new CSR(); //要返回的数据
csr.setRows(rows);
csr.setColumns(columns);
int count = 0;
for (int i = 0;i