我目前正处理图表实施的性能问题。
用C ++编程。目前,图表是通过BGL实现的。
托管图表是动态且无向的。它有两种结构:很多完整的子图和很少的单边。唯一需要的信息是顶点的直接邻域。
一开始,完整的子图很小(大约10个顶点)和很多(大约13k)。邻接列表实现,BGL的实现,是完美的。但现在,要求管理5000个顶点的少数子图。这意味着5000x5000边缘。现在,时间和空间的表现非常差。
我的第一个想法是使用BGL提供的邻接矩阵实现。但它不允许动态图。要解决此约束,有两种解决方案:为动态图提供邻接矩阵的新实现,或在静态图中使用可用顶点池。经过反思,我认为这不是一个好主意:空间复杂度仍然是VxV / 2.
所以,这里是我的最终解决方案:不使用BGL,实现顶点袋来表示完整的子图(不需要边),并直接连接几个单边的顶点。通过这样做,最大子图的空间复杂度下降到它的顶点数,大约5000。
有关图表的更多信息: 该图具有~100k个顶点,~3k个约3个顶点的完整子图,以及~100个大小范围[10-5000]的完整子图。每条边都有捆绑属性。
我最近感谢Salim Jouilli,节点包是hypergraph的坦诚方法,其中超级节点包含节点的子集。
我已经完成了解决方案。我有效地获得了内存消耗和运行时间:从6GB到24MB,从50分钟到2分30秒。
答案 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
使用它有点烦人,因为它需要以有序的方式插入边缘,但可能没有办法显着提高效率(最多只有几个百分点)。