如何在Neo4j中找到关键节点?

所以,假设一个非常简单的图表

(A) – >(B) – >(D) – >(E)| (A) – >(C) – >(d) – >(E)

如果您想象它,它看起来像<> – .

图中的一个关键节点是一个如果你删除它,你现在将有2个图. (AKA,单点故障)

所以在这个例子中,E并不重要,因为它是一个叶子,而B和C并不重要,因为A和D仍然由另一个节点连接. D是至关重要的,因为删除它将从图的其余部分孤立E.

使用Cypher,我如何找到关键节点? (在这种情况下,D)

我的第一直觉是采取所有路径,并计算每个节点被触摸的次数,但这将是非常低效和不可靠的.我的第二直觉就像WHERE NONE(在OTHER_PATHS中的路径中没有n),但即使我能弄清楚如何使其工作,我也不知道路径中的哪个节点是关键的.

我找到了this博客,但它似乎假设你已经了解了一些关键节点.

最佳答案 我们可以通过定义来解决这个问题:

A critical node in a graph is one where if you remove it, you will now have (at least) 2 graphs.

或者换句话说,如果所有节点最初都可以相互访问,并且如果我们删除一个节点,并且这改变了从图中任何其他节点可到达的节点数,那么该被删除的节点就是一个关键节点.

仅通过Cypher尝试这一点的一大障碍是,Cypher可变长度路径匹配旨在找到所有可能的路径,因此在查找所有可到达节点时效率很低.

使用APOC Path expander procedures我们可以改变遍历期间使用的唯一性,因此我们只找到每个不同节点的单一路径并忽略所有其他节点,减少我们需要探索的路径数量,使得查找所有可到达节点的速度更快图形.

使用这个,我们可以首先计算图中的所有节点,然后对于每个节点,看看在扩展期间是否将该节点列入黑名单(有效地查看当我们删除节点时会发生什么)导致从另一个节点扩展以找到少于整个图( – 1当然,对于我们“删除”的节点.

您需要使用比Summer 2018版本更新的APOC版本(3.3.x线上的> = 3.3.0.4,或3.4.x线上的> = 3.4.0.2)才能使用此方法,如我们需要的blacklistNodes功能已添加到此版本中.

这是一般方法,假设我们正在考虑所有节点,并且图中的所有节点最初都可以相互访问.

MATCH (n)
WITH collect(n) as allNodes
WITH allNodes, size(allNodes) - 1 as totalNodes, allNodes[..2] as startNodes
// using total as one less than the actual total since we're 'removing' a node.
// 2 potential start nodes so we always have one if the other is to be removed.
UNWIND allNodes as nodeToRemove
// we now have each node in the graph on its row, we'll try removing each one
WITH [node in startNodes WHERE node <> nodeToRemove][0] as startNode, nodeToRemove, totalNodes
CALL apoc.path.subgraphNodes(startNode, {blacklistNodes:[nodeToRemove]}) YIELD node
WITH totalNodes, nodeToRemove, count(node) as reachableNodes
WHERE totalNodes <> reachableNodes
RETURN nodeToRemove as criticalNode
点赞