在磁盘/流图形分区算法上存储非常大的图形?

时间:2010-01-28 11:02:29

标签: performance graph graph-databases

假设我有一个非常大的无向,未加权的图形(从数亿个顶点开始,每个顶点约10个边缘),非分布式和仅由单线程处理,并且我想要进行广度优先搜索它。我希望它们是I / O绑定的,因此我需要一个良好的BFS磁盘页面布局,磁盘空间不是问题。搜索可以以相同的概率在每个顶点上开始。直观地说,这意味着最小化不同磁盘页面上的顶点之间的边缘数量,这是一个图形分区问题。

图表本身看起来像一个意大利面条,想到随机互连的随机点集,偏向于较短的边缘。

问题是,一个分区图如何变大?我发现可用的图形分区器可以处理仅适合内存的图形。我找不到任何流图分区算法的描述和实现。

或者,为了获得适合BFS的磁盘布局,可能有一种分区图的替代方法吗?

现在作为近似,我使用这样的事实:顶点具有附加到它们的空间坐标,并以Hilbert排序顺序将顶点放在磁盘上。这种方式在空间上靠近顶点落在同一页面上,但它们之间的边缘的存在与否完全被忽略。我能做得更好吗?

作为替代方案,我可以使用顶点的希尔伯特排序顺序将图形拆分成碎片,对子图进行分区,将它们缝合并接受接缝处的不良分区。

我已经研究过的一些事情:

  1. How to store a large directed unweighted graph with billions of nodes and vertices
  2. http://neo4j.org/ - 我发现零信息如何在磁盘上进行图形布局
  3. 分区实现(除非我弄错了,所有这些都需要将图形放入内存中):

    1. http://glaros.dtc.umn.edu/gkhome/views/metis
    2. http://www.sandia.gov/~bahendr/chaco.html
    3. http://staffweb.cms.gre.ac.uk/~c.walshaw/jostle/
    4. http://www.cerfacs.fr/algor/Softs/MESHPART/
    5. 编辑:关于图表如何看起来以及BFS可以在任何地方开始的信息。 编辑:分区子图的想法

3 个答案:

答案 0 :(得分:3)

没有算法真正需要“适应内存” - 您可以随时根据需要对内容进行分页。但是你确实希望避免计算过长时间 - 并且通用情况下的全局图分区是一个NP完全问题,对于大多数甚至不适合内存的问题来说都是“不合理地长”。

幸运的是,您希望进行广度优先搜索,这意味着您需要一种格式,其中广度优先是简单的计算。我不知道有任何算法可以做到这一点,但如果你愿意允许一些额外的磁盘空间,你可以构建自己的广度优先布局。

如果边缘没有偏向局部相互作用,那么解开图形将很困难。如果他们偏向于本地交互,那么我建议使用如下算法:

  • 从整个数据集中选择一组随机顶点作为起点。
  • 对于每个顶点,收集所有相邻顶点(在数据集中扫描一次)。
  • 对于每组相邻顶点,收集邻居邻居集合,并根据连接到它们的边缘数量对它们进行排名。如果页面中没有空间来存储它们,请保留连接最多的顶点。如果你确实有足够的空间来保存它们,你可能希望抛弃最不实用的那些(例如,如果边缘的一部分保持在页面/需要存储比率的顶点的分数下降“太低” - 其中“太低”将取决于您的搜索真正需要多大的广度,以及您是否可以进行任何修剪等等 - 然后不要包括在附近的那些。
  • 重复收集和排列邻居的过程,直到您的邻居满员为止(例如,填写适合您的页面大小)。然后检查随机选择的开始之间的重复。如果两个顶点都出现了少量顶点,请将它们从一个或另一个中删除,以较少的边缘为准。如果两个顶点都出现了大量的顶点,那么保持邻域具有最佳(邻域/破碎边缘的顶点)比率,并抛弃另一个顶点。

现在你有一些本地社区最近的优势,因为广度优先搜索往往会落入其中。如果你的广度优先搜索非常有效地修剪非生产性分支,那么这可能就足够了。如果没有,您可能希望相邻的邻域聚类。

如果您不需要相邻的邻域聚类太多,则将您已分组的顶点放在邻域中,并对剩余数据重复该过程,直到考虑所有顶点。您将每个顶点标识符更改为(顶点,邻域),并且您已完成:当跟随边时,您确切地知道要抓取哪个页面,并且在给定构造的情况下,它们中的大多数将接近。

如果你确实需要邻近社区,那么你需要跟踪你不断增长的社区。你重复上一个过程(随机选择,增加邻域),但是现在按邻居在邻域中满足的边数对邻居进行排名离开邻域的边缘的哪一部分在现有组中。您可能需要加权因子,但类似

score = (# edges within) - (# neighborhoods outside) - (# neighborhoodless edges outside)

可能会成功。

现在,这是全局甚至是本地最优的,但是这个或类似它的东西应该提供一个很好的本地连接结构,并且应该让你产生一套覆盖的邻域互联性相对较高。

同样,这取决于你的广度优先搜索修剪分支。如果是这样,那么便宜的事情就是最大限度地提高局部互连性。如果不这样做,那就是尽量减少外部连接 - 在这种情况下,我建议只收集广度优先设置到某种尺寸并保存它们(在集合的边缘重复 - 你“不受硬盘空间的限制,不是吗?”。

答案 1 :(得分:2)

您可能需要查看HDF5。尽管H代表Hierarchical,但它可以存储图形,检查关键字“Groups”下的文档,它专为非常大的数据集而设计。如果我理解正确,HDF5'文件'可以分布在多个o / s'文件'中。现在,HDF5只是一种数据结构,加上一组用于数据结构的低级和高级操作的库。我不知道流式图分区算法,但我坚持认为,如果你得到正确的数据结构,算法就会变得更容易实现。

你对大型图有什么了解?它是否自然地划分为密集的子图本身稀疏连接?拓扑类型的图表是否比现有的空间排序更好地存储在磁盘上?

对这些问题没有清晰的答案,也许你只需要咬紧牙关并多次阅读图表来构建分区,在这种情况下,你只需要你能管理的最快的I / O,以及复杂的分区布局节点很好但不重要。如果您可以将图形划分为子图形,这些子图形本身与其他子图形具有单边缘,则可能使问题更容易处理。

您想要一个适合BFS的布局,但BFS通常应用于树。您的图表是否具有从中启动所有BFS的唯一根?如果没有,那么来自一个顶点的BFS布局对于来自另一个顶点的BFS来说将是次优的。

答案 2 :(得分:1)

查看此博文:

“使用迭代map-reduce算法进行广度优先图搜索”

http://www.johnandcailin.com/blog/cailin/breadth-first-graph-search-using-iterative-map-reduce-algorithm