COO、CSR、adj_coo、adj_csr详解:稀疏矩阵与稀疏邻接矩阵的存储格式及转换

2023-10-04 15:16

本文主要是介绍COO、CSR、adj_coo、adj_csr详解:稀疏矩阵与稀疏邻接矩阵的存储格式及转换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 一、COO
  • 二、CSR
  • 三、adj_coo
  • 四、adj_csr
  • 五、格式转换代码

稀疏图:数据结构中对于稀疏图的定义为:有很少条边或弧(边的条数 ∣ E ∣ |E| E 远小于 ∣ V ∣ 2 |V|^2 V2)的图称为稀疏图,反之边的条数 ∣ E ∣ |E| E 接近 ∣ V ∣ 2 |V|^2 V2,称为稠密图。采用直观的办法来存储图往往会造成极大的空间浪费,因此需要采取其他方式压缩存储空间。

一、COO

  1. 对于稠密图,我们往往以矩阵的方式存储结点的连接关系。如图1a所示,对于矩阵 matrixmatrix[i][j] = x 表示结点 i 与结点 j 之间的边的长度为 x。我们可以看到在图1a的矩阵 matrix 中,除了少数结点间有边相连,大多数的存储空间都浪费了
  2. 对于稀疏图,最直观的压缩存储方式是只存储矩阵 matrix 中的非零元素以及这些元素的位置,也就是以三元组的方式存储 (i, j, x)(i, j, x) 同样表示结点 i 与结点 j 之间的边的长度为 x,如图1b所示。
  3. 使所有三元组的横坐标单独组成 row 数组,纵坐标单独组成 column 数组,数值单独组成 data 数组就形成了稀疏矩阵的 COO表示,如图1c所示。

图1

图1 COO表示

二、CSR

  1. 对于结点数量比较多,并且远大于边数量的稀疏矩阵,上一小节中介绍的COO表示已经能够节省很多存储空间了,那我们还能不能进一步节省更多的空间呢?
  2. 当然可以!我们观察上一小节中得到的 COO表示(如图2b所示),row 数组中各三元组的横坐标 按序排列,因此 相同的横坐标会连在一起,这何尝不是一种 数据重复
  3. 我们保持 column 数组和 data 数组 不变。将 row 数组改为 row offsets:不再记录每一个元素的横坐标,只记录每一行的第一个元素在 data 数组中的下标,最后再额外记录总的元素个数。如图2c所示。
    • 新的数组 row offsets 就像书签一样,其中的第 i 个元素 ro[i]就代表了 data[ro[i]]data[ro[i+1]] 之间的元素的横坐标为 i(包括data[ro[i]] 但不包括 data[ro[i+1]])。
    • 如图2中,我们分别用蓝、黄、绿、橙代表不同的四行的元素。
      0 行的第一个元素为6,data 数组中其下标为 0,故 ro[0]=0
      1 行的第一个元素为3,data 数组中其下标为 2,故 ro[1]=2
      2 行的第一个元素为5,data 数组中其下标为 4,故 ro[2]=4
      3 行的第一个元素为7,data 数组中其下标为 5,故 ro[3]=5
      data 数组中共有 7 个元素,故 ro[4]=7

图2

图2 CSR表示

三、adj_coo

第一小节中我们讨论了普通稀疏图的矩阵转化为COO表示。但如果邻接矩阵中只记录了两个结点是否相连,并没有记录边的信息(如图3a),我们便不需要记录 data 数据,如此可以进一步压缩存储空间。
图3

图3 adj_coo表示

四、adj_csr

与adj_coo情况类似,如果邻接矩阵中只记录了两个结点是否相连,并没有记录边的信息(如图4a),我们便不需要记录 data 数据,如此可以进一步压缩存储空间。
图4

图4 adj_csr表示

五、格式转换代码

这里仅展示 adj_coo 转 adj_csr 的代码:

def adjcoo2adjcsr(adj_coo, node_count):sour = adj_coo[0]dist = adj_coo[1]adjs = []last = -1for i in range(node_count):try:index = sour.index(i)except:index = last + 1else:last = indexfinally:adjs.append(index)adjs.append(len(dist))print(adjs)print(dist)adj_coo = [[0, 0, 1, 1, 2, 3, 3],[0, 1, 1, 2, 0, 2, 3]]
adjcoo2adjcsr(adj_coo, 4)

运行结果如下图所示:
图五

这篇关于COO、CSR、adj_coo、adj_csr详解:稀疏矩阵与稀疏邻接矩阵的存储格式及转换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/2259

相关文章

PHP轻松处理千万行数据的方法详解

《PHP轻松处理千万行数据的方法详解》说到处理大数据集,PHP通常不是第一个想到的语言,但如果你曾经需要处理数百万行数据而不让服务器崩溃或内存耗尽,你就会知道PHP用对了工具有多强大,下面小编就... 目录问题的本质php 中的数据流处理:为什么必不可少生成器:内存高效的迭代方式流量控制:避免系统过载一次性

MySQL的JDBC编程详解

《MySQL的JDBC编程详解》:本文主要介绍MySQL的JDBC编程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、前置知识1. 引入依赖2. 认识 url二、JDBC 操作流程1. JDBC 的写操作2. JDBC 的读操作总结前言本文介绍了mysq

Redis 的 SUBSCRIBE命令详解

《Redis的SUBSCRIBE命令详解》Redis的SUBSCRIBE命令用于订阅一个或多个频道,以便接收发送到这些频道的消息,本文给大家介绍Redis的SUBSCRIBE命令,感兴趣的朋友跟随... 目录基本语法工作原理示例消息格式相关命令python 示例Redis 的 SUBSCRIBE 命令用于订

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Python中 try / except / else / finally 异常处理方法详解

《Python中try/except/else/finally异常处理方法详解》:本文主要介绍Python中try/except/else/finally异常处理方法的相关资料,涵... 目录1. 基本结构2. 各部分的作用tryexceptelsefinally3. 执行流程总结4. 常见用法(1)多个e

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

SpringBoot日志级别与日志分组详解

《SpringBoot日志级别与日志分组详解》文章介绍了日志级别(ALL至OFF)及其作用,说明SpringBoot默认日志级别为INFO,可通过application.properties调整全局或... 目录日志级别1、级别内容2、调整日志级别调整默认日志级别调整指定类的日志级别项目开发过程中,利用日志

Java中的抽象类与abstract 关键字使用详解

《Java中的抽象类与abstract关键字使用详解》:本文主要介绍Java中的抽象类与abstract关键字使用详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、抽象类的概念二、使用 abstract2.1 修饰类 => 抽象类2.2 修饰方法 => 抽象方法,没有

MySQL8 密码强度评估与配置详解

《MySQL8密码强度评估与配置详解》MySQL8默认启用密码强度插件,实施MEDIUM策略(长度8、含数字/字母/特殊字符),支持动态调整与配置文件设置,推荐使用STRONG策略并定期更新密码以提... 目录一、mysql 8 密码强度评估机制1.核心插件:validate_password2.密码策略级

MyBatis-plus处理存储json数据过程

《MyBatis-plus处理存储json数据过程》文章介绍MyBatis-Plus3.4.21处理对象与集合的差异:对象可用内置Handler配合autoResultMap,集合需自定义处理器继承F... 目录1、如果是对象2、如果需要转换的是List集合总结对象和集合分两种情况处理,目前我用的MP的版本