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

时间:2018-07-30 18:38:26

标签: neo4j cypher

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

(A)->(B)->(D)->(E) | (A)->(C)->(D)->(E)

如果您将其可视化,它将看起来像<>-

图形中的关键节点是一个节点,如果将其删除,则现在将有2个图形。 (又称单点故障)

因此,在此示例中,E不是关键的,因为它是叶子,而B和C也不重要,因为A和D仍然由另一个节点连接。尽管D是至关重要的,因为将其删除将使图的其余部分孤立E。

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


我的第一个直觉是走所有路径,并计算每个节点被触摸了多少次,但这将是非常低效且不可靠的。我的第二个本能是类似WHERE NONE (n in path WHERE NOT n in OTHER_PATHS)的东西,但是即使我能弄清楚该如何工作,我也不知道路径中的哪个节点很关键。

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

3 个答案:

答案 0 :(得分:1)

我们可以通过其定义来解决这个问题:

  

图形中的关键节点是一个节点,如果将其删除,则现在将(至少)具有2个图形。

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

仅通过Cypher尝试进行此操作的最大障碍是,Cypher可变长度路径匹配旨在查找所有可能的路径,因此查找所有可到达的节点效率低下。

使用APOC Path expander procedures,我们可以更改遍历过程中使用的唯一性,因此我们只能找到到达每个不同节点的一条路径,而忽略所有其他节点,从而减少了需要探索的路径数量,从而使其速度更快查找图中的所有可达节点。

使用此方法,我们可以首先计算图中的所有节点,然后针对每个节点,查看在扩展过程中将该节点列入黑名单(有效地查看移除该节点时发生的情况)是否会导致另一个节点的扩展查找少于整个节点图(当然,对于我们“删除”的节点为-1)。

您将需要使用比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

答案 1 :(得分:0)

首先,您需要确定图中具有的节点的类型:如果所有节点都是同一类型,则可以计算它们的所有关系(或特定关系);如果一个节点有n个以上的关系(可能是2个),则它可能是关键节点,否则该节点不是关键节点。

但是,如果节点类型不止一种,则需要确定哪种类型的节点和关系更重要,然后查询每种类型的节点和关系,最后计算它们的关系(所有关系或特定关系)所有类型的节点或特定节点

MATCH (n)-[r]->() RETURN COUNT(r)

如果该节点被认为不是关键节点,则可以继续删除该节点。

答案 2 :(得分:0)

我想出了如何进行基于路径的过滤,其中在每个可能的路径上都需要满足条件的情况。您可以在谓词中使用模式识别来过滤所有路径。 (我对我的集合使用了合理的路径长度限制,以限制失控。如果我的图形中存在替代路径,我希望绕道会很短。因此,请根据您的期望进行调整)

MATCH (a)-[*..10]->(c)-[*..10]->(b) 
WHERE ALL(p in (a)-[*..20]->(b) WHERE c in NODES(p)) 
RETURN DISTINCT c

我也尝试过使用allShortestPaths这样,但是在我的示例集中,性能实际上更差。你的里程是我的。

MATCH (a)-[*..10]->(c)-[*..10]->(b) 
WHERE ALL(p in allShortestPaths((a)-[*..20]->(b)) WHERE c in NODES(p)) 
RETURN DISTINCT c