如何用很多大的完整子图有效地实现图形?

时间:2011-08-04 10:43:18

标签: c++ graph boost-graph

我目前正处理图表实施的性能问题。

使用的技术

用C ++编程。目前,图表是通过BGL实现的。

关于图表

托管图表是动态且无向的。它有两种结构:很多完整的子图和很少的单边。唯一需要的信息是顶点的直接邻域。

问题陈述

一开始,完整的子图很小(大约10个顶点)和很多(大约13k)。邻接列表实现,BGL的实现,是完美的。但现在,要求管理5000个顶点的少数子图。这意味着5000x5000边缘。现在,时间和空间的表现非常差。

拒绝解决方案

我的第一个想法是使用BGL提供的邻接矩阵实现。但它不允许动态图。要解决此约束,有两种解决方案:为动态图提供邻接矩阵的新实现,或在静态图中使用可用顶点池。经过反思,我认为这不是一个好主意:空间复杂度仍然是VxV / 2.

最终解决方案和问题

所以,这里是我的最终解决方案:不使用BGL,实现顶点袋来表示完整的子图(不需要边),并直接连接几个单边的顶点。通过这样做,最大子图的空间复杂度下降到它的顶点数,大约5000。

  1. 您认为最后一个解决方案是好的解决方案吗?
  2. 如果没有,我可以使用哪种实现方式?为什么?
  3. 更新1

    有关图表的更多信息: 该图具有~100k个顶点,~3k个约3个顶点的完整子图,以及~100个大小范围[10-5000]的完整子图。每条边都有捆绑属性。

    更新2

    我最近感谢Salim Jouilli,节点包是hypergraph的坦诚方法,其中超级节点包含节点的子集。

    更新3

    我已经完成了解决方案。我有效地获得了内存消耗和运行时间:从6GB到24MB,从50分钟到2分30秒。

3 个答案:

答案 0 :(得分:1)

你最终的解决方案是我本人应该去的那个。它听起来尽可能高效。

答案 1 :(得分:1)

如果您的问题将来(再次)扩大,可能值得使用graph database。这样,您就可以解耦存储和业务逻辑,并将它们视为单独的问题。

答案 2 :(得分:0)

一般来说,拥有25M边缘并不是什么大问题。但我只在具有大量节点的稀疏图上使用它(街道网络)。

如果内存使用和访问时间对您的需求变得至关重要,请尝试使用boost压缩稀疏图http://www.boost.org/doc/libs/1_46_1/libs/graph/doc/compressed_sparse_row.html

使用它有点烦人,因为它需要以有序的方式插入边缘,但可能没有办法显着提高效率(最多只有几个百分点)。