簡體   English   中英

找到排除特定邊緣的最短路徑?

[英]finding shortest path that excludes particular edges?

我正在使用 Py2neo,但這可能無關緊要,因為這很可能需要通過編寫 Cypher 查詢來完成。

本質上,我想在子圖中找到最短路徑,其中子圖是整個圖中的大部分,但去除了很小的一部分(百萬分之一或更少)的邊。

例如,假設我有節點 A、B 和 C,以及邊 (A->B)、(A->C)、(B->C)。 當然,從 A 到 C 的最短路徑是通過直接連接。 但是,如果我想找到使用該邊的最短路徑,則必須是 AB C。

此外,這將是用戶可以在多用戶(Web)應用程序中指定的內容。 所以我不能真正改變數據庫本身......如果這不是問題,我可以在邊緣“允許:真/假”上創建一個屬性並將其設置為假,但這會擾亂應用程序的行為所有當前用戶。

對此的一個變體是“禁止:sessionID1、sessionID230、sessionID1010”,即實際存儲哪些應用程序會話想要在邊緣本身中排除該邊緣,但這似乎也不理想。

當然,我實際上可以在 python 中實現 BFS,方法是根據需要從 neo4j 獲取節點並將它們保留在隊列中,而不是讓 neo4j 進行搜索,但這肯定會慢得多,對吧?

有什么想法嗎? 謝謝

編輯:請求查看代碼。

下面是我目前如何獲得我首先在索引中查找的兩個節點之間的最短路徑。 現在圖像還有一個在最短路徑搜索中必須忽略的邊緣列表(即唯一關系)。

from py2neo import neo4j

g = neo4j.GraphDatabaseService()

def shortest_path(a, b):
    a = g.get_indexed_node("worddex", "word", a)
    b = g.get_indexed_node("worddex", "word", b)
    if not a and b: return None
    query_string = "START beginning=node(%d), end=node(%d) MATCH p = shortestPath(beginning-[*..100]-end) RETURN p" % (a._id, b._id)
    result = neo4j.CypherQuery(g, query_string).execute()
    if not len(result): return None
    p = result[0].p
    ret = []
    for node in p.nodes:
        ret.append(node["word"])
    return ret

編輯 2:示例控制台: http : //console.neo4j.org/r/3c1rgn

很容易找到任何兩個人之間最短的“友誼路徑”,但是如果我們想找到一條最短的友誼路徑,它不涉及特定的友誼關系(或特定的友誼關系集合),但不先修改數據庫呢? ? 例如,我們想要找到從 bob 到 joe 的最短友誼路徑,其中我們暫時假設 bob 和 joe 本身不是朋友,alice 和 janet 也不是朋友。

您不能在cypher 中使用“ allShortestPaths ”選項並使用它來拒絕包含使用 python 的某些特定 rel 類型或節點類型的路徑嗎? 我想這將取決於您想要限制結果的方式和參數,以及是否可以僅使用密碼以路徑形式返回給 python 來檢測它們。

另一種方法是指示 Cypher 將所有可能的路徑從一個節點返回到另一個節點(可以在此處的查詢本身中應用一些智能限制)。

然后基於 Cypher 返回的路徑集合,您可以運行一些 Python 代碼來拒絕包含您不感興趣的特定 rel 類型或節點類型的路徑。然后您將得到一組可能的路徑符合您的驗收標准(最短條件除外)。 然后,您可以簡單地使用 python 計算路徑的長度並使用最小的。

實際上,對於所有路徑,Cypher 本身都可以返回路徑的長度。 之前已經問過這個問題,所以這里是您參考的問題 這個問題的公認答案就是我正在談論的。

暫無
暫無

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

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