稀疏矩阵之基于数组形式实现COO和CSR

稀疏矩阵之基于数组形式实现COO和CSR

前言

  • 语言:Java
  • 环境:IntelliJ IDEA
  • JDK版本:1.8
  • 源码:GitHub
  • 参考文章:https://www.cnblogs.com/xbinworld/p/4273506.html

什么是稀疏矩阵

在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵;与之相反,若非0元素数目占大多数时,则称该矩阵为稠密矩阵。定义非零元素的总数比上矩阵所有元素的总数为矩阵的稠密度。

例如下面的矩阵:

稀疏矩阵之基于数组形式实现COO和CSR_第1张图片

由于稀疏矩阵中重复的0非常多,因此在存储稀疏矩阵时非常有必要对其压缩,下面介绍了几种常用的稀疏矩阵存储格式。

存储格式

COO格式

COO(Coordinate):仅存储非0数据的行、列、值 这种存储方式虽然简单,但会存在行或列重复出现的情况,这些重复值也需要被压缩。

稀疏矩阵之基于数组形式实现COO和CSR_第2张图片

编码流程:

  • 压缩
    1. 遍历矩阵,获取所有非0数据个数
    2. 记录原矩阵的总行数、总列数、非0数据个数
    3. 通过获取的非0数据个数初始化压缩后的数据行数,列数为3,分别为row、column、value
    4. 再次遍历矩阵,将非0数据所在的行、列、值进行存储
  • 解压
    1. 用记录的总行数、总列数初始化原矩阵
    2. 用非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_第3张图片

当使用COO时,若重复行过多,则可以使用CSR来忽略行;若重复列过多,则可以使用CSC忽略列

编码流程:

  • 压缩
    1. 遍历矩阵,获取所有非0数据个数
    2. 记录原矩阵的总行数、总列数、非0数据个数
    3. 通过获取的非0数据个数初始化压缩后的数据行数,列数为2,分别为column、value
    4. 再次遍历矩阵,将非0数据所在的行、列、值进行存储
    5. 通过value计算出行偏移并存储
  • 解压
    1. 用记录的总行数、总列数初始化原矩阵
    2. 用非0数据个数为循环次数逐行还原矩阵,还原同时需要通过记录的行偏移控制行

行偏移在解压该过程中可以理解为:忽略行的存在,顺序还原数据,行偏移的值就是当循环到这个值时进行换行

稀疏矩阵之基于数组形式实现COO和CSR_第4张图片

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

转载于:https://my.oschina.net/rawlins/blog/3101192

你可能感兴趣的:(稀疏矩阵之基于数组形式实现COO和CSR)