优化Cypher查询以分析网络拓扑

问题描述

我有一个网络(例如水网络),我想找到拓扑结构:簇(圆形路径),桥梁(连接簇的关系)和树木(其余)。

network

创建示例网络的Cypher语句在这里。(https://www.dropbox.com/s/e1gtqxlm9ngaau5/Cypher%20to%20create%20example%20network.cql?dl=0)蓝色关系是我要寻找的群集,红色关系是桥梁,绿色关系是树。

要找到聚类,我有两种方法,两种方法都返回正确的结果。但是两者都太慢了。

方法1: 从关系开始,查看起点和终点之间是否存在第二条路径。 这需要大约1000万次数据库点击次数

MATCH (n:WN)-[r:PIPE]->(m:WN) 
WHERE EXISTS((n)-[r]->(m)-[:PIPE*2..]-(n))
RETURN r

方法2: 从寻找圆形路径开始,忽略方向。 (大约12000),然后提取唯一关系。 这需要大约2000万次数据库匹配。

MATCH path=(n:WN)-[:PIPE*..]-(n)
RETURN 
     apoc.coll.subtract(
          apoc.coll.flatten(COLLECT(relationships(path))
          ),[]
     )
    AS clusterRelationships

有没有更聪明的方法,可以更快地返回结果?

解决方法

您可以使用GDS库中可用的Strongly connected component algorithm检测群集。我认为它符合您对集群的定义,并且也适用于您的示例。

“强连接组件”(SCC)算法查找以下集合: 有向图中的连接节点,其中每个节点均可到达 来自同一集合中任何其他节点的两个方向。

要检测网桥,您可以使用Betweenness centrality algorithm查找连接了网桥关系的潜在网桥节点。这将限制您在计算哪些边缘是桥时需要考虑的边缘数量。不幸的是,这种解决方案并不完美,因为对于某些非常小的网桥而言,假设它们仅是一个到单个或两个节点的网桥,中间性不会那么高。而且,由于理论上所有信息都将通过它们,因此图中间的某些节点将具有较高的中间性得分。

我有另一个想法,可能很快就会奏效。运行强连接组件算法,并将结果存储回Neo4j。然后尝试找到连接不同节点群集的边。这将同时包括树木和桥梁,然后您必须确定将关系分类为两个选项中的哪个。