簡體   English   中英

如何在Neo4j中找到關鍵節點?

[英]How to find critical nodes in Neo4j?

因此,假設一個非常簡單的圖形

(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) ,但是即使我能弄清楚如何使之工作,我也不知道路徑中的哪個節點是關鍵的。

我找到了這個博客,但似乎假設您已經了解關鍵節點。

我們可以通過其定義來解決這個問題:

圖中的關鍵節點是一個節點,如果將其刪除,則現在將擁有(至少)2個圖。

或換一種說法,如果所有節點最初都是彼此可達的,並且如果我們刪除一個節點,並且這更改了圖中任何其他節點可達的節點數,則該刪除的節點就是關鍵節點。

僅通過Cypher嘗試進行此操作的最大障礙是Cypher可變長度路徑匹配旨在查找所有可能的路徑,因此在查找所有可到達的節點方面效率低下。

使用APOC路徑擴展器過程,我們可以更改遍歷過程中使用的唯一性,因此我們只能找到到每個不同節點的一條路徑,而忽略所有其他節點,從而減少了需要探索的路徑數量,從而更快地找到了所有可達的路徑圖中的節點。

使用此方法,我們可以首先計算圖中的所有節點,然后對於每個節點,查看是否在擴展過程中將該節點列入黑名單(有效地查看了刪除節點后發生的情況),是否導致其他節點的擴展少於整個圖(- 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

首先,您需要確定圖中的節點類型:如果所有節點都是同一類型,則可以計算它們的所有關系(或特定關系); 如果一個節點具有多於n個關系(可能為2),則它可能是關鍵節點,否則此節點不是關鍵節點。

但是,如果您有不止一種類型的節點,則需要確定哪種類型的節點和關系更重要,然后查詢每種類型的節點和關系,最后計算它們與所有類型的關系(所有關系或特定關系)節點或特定節點的

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

並且如果該節點被認為不是很關鍵,則可以繼續刪除該節點。

我想出了如何進行基於路徑的過濾,其中條件在每個可能的路徑上都必須為真。 您可以在謂詞中使用模式識別來過濾所有路徑。 (我對我的集合使用了合理的路徑長度限制,以限制失控。如果圖形中存在替代路徑,則我希望繞道會很短。因此,請根據您的期望進行調整)

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM