计算机是如何存储矩阵,如何存储稀疏邻接矩阵(How to store sparse adjacency matrix)

如何存储稀疏邻接矩阵(How to store sparse adjacency matrix)

我读了几个主题,但我迷路了。 我对此很陌生。 我想存储巨大的稀疏矩阵并有几个想法,但可以在它们之间进行选择。 这是我的需求:

邻接矩阵约。 5000万个顶点。

每个顶点的最大邻居数量 - 大约 10 000。

每个顶点的平均邻居数量 - 约。 200-300。

快速行查询 - 向量将乘以此矩阵。

O(1)增加边缘的复杂性。

最有可能的是,边缘不会被删除。

尽可能快地枚举与v相邻的顶点。

可移植性 - 必须有一种方法将基站从一台计算机转移到另一台计算机。

所以,这是我的想法:

巨大的桌子对(行,col)。 非常简单,但顶点的枚举将至少为O(log N),其中N - 表的大小。 我觉得它很慢。 此外,它必须编入索引。 每个RDBMS都会有所帮助。

大量的列表:每个顶点一个列表。 枚举速度非常快,但是存储它需要多少资源? 另外,我不确定在这种情况下使用哪个DBMS:也许是一些NoSql?

巨大的桌子(行|集合)。 上面两个组合。 我不确定是否有任何RDBMS支持任意集。 你知道任何? 也许NoSql在这里有用吗?

邻接列表的集合。 任何RDBMS都适用于此,并且复杂性方面的成本很高,但是对于一个顶点,它们可以被多个DB请求杀死。

HDF5 - 我认为由于I / O会很慢。

Neo4j - 据我所知,它将数据存储在双链表中,因此它实际上与№4相同,我是对的吗?

请帮助我选择或提供更好的决定。

如果我在某处估计错了,请纠正我。

I've read several topics, but I'm lost. I'm quite new to this. I want to store huge sparse matrix and have several idea's but can choose between them. Here's my needs:

Adjacency matrix of approx. 50 million vertices.

Maximum amount of neighbors per one vertex - approx. 10 000.

Average amount of neighbors per one vertex - approx. 200-300.

Fast row query - vector will be multiplied by this matrix.

O(1) complexity to add edge.

Most probably, edges will not be deleted.

Enumeration of the vertices adjacent to v - as fast as possible.

Portability - there must be a way to transfer base from one computer to another.

So, here's my ideas:

Huge table with pairs (row, col). Very simple, but enumeration of vertices will be at least O(log N), where N - size of table. It's quite slow as I think. Also, it must be indexed. Every RDBMS will be good for what.

Enormous amount of lists: one list per vertex. Very fast enumeration, but wouldn't it take much resources to storage this? Also, I'm not sure about which DBMS to use in this case: maybe some NoSql?

Huge table (row | set of cols). Combination of two above. I'm not sure is there any RDBMS to support arbitrary sets. Do you know any? Maybe NoSql will be useful here?

Collection of adjacency lists. Any RDBMS will be suitable for that, and costs in terms of complexity are good, but they can be killed by multiple request to DB for one vertex.

HDF5 - I think it will be slow due to I/O.

Neo4j - As far as I understand, it storages data in double-linked lists, so it will be practically the same as №4, am i right?

Please, help me to choose or offer a better decision.

If I'm wrong with estimates somewhere, please correct me.

原文:https://stackoverflow.com/questions/15003397

更新时间:2020-01-15 14:19

最满意答案

混合neo4j / hbase方法可以很好地运行,其中neo4j优化了图形处理方面,而hbase实现了繁重的可扩展性 - 例如,用于存储大量额外属性。

neo4j包含节点和关系。 它可能具有足够的可扩展性。 我在网上对独立的非neo4j站点进行的调查在单台机器上声称多达数十亿个节点/关系,在遍历上比RDBMS具有几个数量级更好的性能。

但是..如果需要更多的可扩展性,你可以引入hbase big iron来存储非关系/节点标识符的额外属性。 然后,只需将hbase rowkey添加到neo4j节点信息中,以便在应用程序需要时进行查找。

In the end, I've implemented solution number one.

I used PostgreSQL with two tables: one for edges with two columns - start/end, and another for vertices with unique serial for vertex number and some columns for vertex description.

I've implemented upsert based on pg_advisory_xact_lock. It was a bit slow, but it was enough for me.

Also, it's a pain to delete vertex from this configuration.

To speed up multiplication, I've exported edges table to file. It can even be placed in RAM on x64 machine.

To be fair, the amount of data was less than I expected. Instead of 50 million vertices and average 200-300 edges for 1 vertex there were only 7 million vertices and 160 million edges total.

相关问答

你是什么意思'删除'? 如果您确实想要删除 - 删除,只需删除已删除节点的行和列,然后重新编号其余节点。 What do you mean 'delete'? If you really want to delete-delete, just delete the row and column for the node deleted, and renumber the remaining nodes.

在您的问题中的图算法中,如果给出权重,除了权重之外,通常不会明确地编码邻接。 相反,图形被认为是一个完整的图形(即evey顶点与任何其他顶点相邻),但对于非相邻顶点u , v在初始图形中,权重被编码为“无穷大”,编码为最大值所使用的数据类型,在计算等中识别的一些负值。 使用这种方法,不可行的边缘将永远不会被考虑,因为它们比最初问题的任何可行解决方案更昂贵。 In graph algorithms as in your question, if weights are given, usually

...

你仍然可以使用sparse但你将不得不做更多的工作。 首先,我们需要将X和Y的标签转换为唯一的整数ID。 尝试在组合的X和Y输入上使用unique ,以便您可以获得在两者之间共享的唯一整数ID。 具体来说, unique会给你一个输入的所有唯一条目列表(所以X和Y组合)。 我们结合X和Y的原因是因为X有某些令牌可能不会出现在Y ,反之亦然。 对组合输入进行此ID分配将确保一致性。 'stable'标志存在,因为默认情况下unique实际排序所有唯一条目。 如果输入是字符串的单元数组,则按照字典顺序

...

你必须创建你的邻接矩阵,因为如果2与3 : A(2,3) == 1相邻,那么3也必须与2 : A(3,2) == 1相邻。 您已经构建了邻接矩阵,使得每个边只有一个单向关系。 您可以通过将EdgeList的另一列附加到sparse每个输入来更正此问题: A = sparse([EdgeList(:,1); EdgeList(:,2)], [EdgeList(:,2); EdgeList(:,1)], 1);

或者,您可以转置A并使用逻辑或( | )将其与A的初始版本组合以强制它对称。 A = A

...

Cludgy,但嘿... gg1

gg1

gg1

gg1

...

混合neo4j / hbase方法可以很好地运行,其中neo4j优化了图形处理方面,而hbase实现了繁重的可扩展性 - 例如,用于存储大量额外属性。 neo4j包含节点和关系。 它可能具有足够的可扩展性。 我在网上对独立的非neo4j站点进行的调查在单台机器上声称多达数十亿个节点/关系,在遍历上比RDBMS具有几个数量级更好的性能。 但是..如果需要更多的可扩展性,你可以引入hbase big iron来存储非关系/节点标识符的额外属性。 然后,只需将hbase rowkey添加到neo4j节点

...

nnz :稀疏矩阵的非零数 row_size :矩阵行号 column_size :矩阵列号 它们的空间复杂性有很多种: 压缩稀疏行(CSR): 2*nnz + row_size内存数 压缩稀疏列(CSC): 2*nnz + column_size内存数 坐标格式(COO): 3*nnz内存数 对于空间复杂性: 如果row_size > column_size ,则使用CSC格式,否则,使用CSR格式。 对于时间复杂性: 对于CSR格式,Row将被O(1)时间索引,Column将被O(log(k)

...

scipy.sparse为你做的。 import numpy as np

from scipy.sparse import dok_matrix

your_data = [((2, 7), 1)]

XDIM, YDIM = 10, 10 # Replace with your values

dct = {}

for (row, col), weight in your_data:

dct[(row, col)] = weight

smat = dok_matrix((XDIM, Y

...

该错误来自于类spantree的对象上的使用函数as_adjacency_matrix ,当它需要igraph 。 由于您使用的是igraph ,一个简单的解决方案是使用igraph的函数mst从原始的“距离图”计算最小生成树。 以下是spantree如何计算最小生成树: require(vegan)

data(dune)

dis

tr

结果是以下树( plot(tr, type="t") ) : 只有igraph函数才能获得相

...

这是一个简单的矩阵乘法。 t(m) %*% m

a b c d e

a 2 1 1 0 0

b 1 2 1 0 0

c 1 1 3 1 0

d 0 0 1 1 0

e 0 0 0 0 0

使用这些数据: m = read.table(text = "ID a b c d e

1 1 0 1 0 0

2 0 1 1 0 0

3 0 0 1 1 0

4 1 1 0 0 0", header = T)

m = as.matrix(m[, -1])

这依赖于原始矩阵仅为1和0。 如果不是

...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值