我非常接近自己实现这一点,但在此之前,我仍然想知道是否已经发明了这个轮子:我需要的是一个允许我代表DAG(有向无环图)的库和哪个将允许以非常高的性能对直接或间接连接的节点进行查询。到目前为止,我已经比较了两种方法。
图表将是数百万个节点,大约有1000万到2000万个边缘。大多数节点只有一个或两个边,但是几千个节点可能有10000个边或更多。
用例将是:创建图表的工作并不重要,一旦创建它就不需要更新,或者更新不需要很快。 然而,找到长度为2(一个中间节点)的直接连接或特定间接连接应该非常快并且边缘应该能够具有标签(例如,权重,计数等)。此外,内存占用量应该很小,查询应该是线程安全的。
我已经尝试过使用一些标准软件包,例如: Neo4J或关系数据库,但对于某些事情来说两者都太慢了:当涉及很多边缘的节点(巨大的连接集)时,关系数据库会爬行寻找间接关系。 Neo4j处理这种情况要好得多,但是找到直接连接的基本速度比关系数据库解决方案慢几千倍。在工作站上,关系数据库可以在不到5ms的时间内返回直接和间接查询的结果,但某些间接查询可能需要一分钟。在同一系统上使用Neo4j时,这些间接查询只需几秒钟,但直接查询都需要超过100毫秒。我希望能够将我的直接查询提供到1 ms以下,最差的间接查询不到1秒(平均)。
我认为,当巧妙地完成时,这可以在内存中只用几个堆空间来表示和执行,即使对于更大的图形,也可以通过巧妙的缓存和a来快速完成这些操作的策略如何将图形的一部分持久化到磁盘的巧妙方法。但我找不到任何提供此功能的解决方案或库(更好的开源)。我错过了什么吗?
答案 0 :(得分:1)
具有数百万个节点和数千万个边缘的图形将在本世纪任何台式计算机上简单地存储在内存中。我建议使用FORTRAN风格的
int ia[NVERT+1];
int ja[NEDGE];
其中边缘按尾部顶点排序,尾部位于v
的边缘的索引ia[v]
最多为ia[v+1]-1
,而ja[e]
列出了e
的前端{1}}边缘。请注意,这需要大约4(NVERT+NEDGE+1)
个字节的内存,这远远小于“仅仅几个演出。”
检查从一个顶点到另一个顶点是否有边缘很简单;你看看第一个顶点的外边缘。检查从一个顶点到另一个顶点是否存在双边路径也很简单;找到第一个顶点的所有邻居,并检查它们中是否有任何一个指向第二个顶点的外边缘。在最坏的情况下,这是扫描所有边缘。自己做这件事几乎肯定比连接数据库所需的代码少。
对于您所描述的任何类型的查询,任何需要超过几毫秒的软件都不值得用于此目的。
答案 1 :(得分:0)
我不确定它是否符合您的要求,因为我自己并没有使用这个库,但也许GUERY,我的新同事设计的框架值得一看:https://code.google.com/p/gueryframework/