2015-12-02 119 views
5

我知道這個問題已經有好幾次了,但是我還沒有找到任何關於Tinkerpop(3.1)的最新版本的參考,它提供了許多我們可以使用的新的有用函數我們的遍歷。找到Tinkerpop中兩個節點之間最短路徑的最佳方法3.1

比方說,我必須找到a節點3和4之間的最短路徑。 這是遍歷聲音?

g.V(3).repeat(out()).until(id().is(4).and().simplePath()).path().limit(1) 

這裏我假定當我循環一個BFS執行搜索(因此,第一個結果是最短的路徑)作爲it seems that this was the case with the loop() function

此外,是否有任何方法在until步驟中包含以前綁定的變量(通過使用as步驟)? 更確切地說,我試圖在穿越過程中選擇兩個節點,然後發現它們之間的最短路徑,例如,

g.V().match(
__as('e0').out('Feedbacks').as('e1'), 
__as('e0').repeat(out('Meets')).until(<I reach e1>).path().<get_length>.as('len') 
).select('e0', 'e1', 'len') 

最後,從先前的遍歷中可以看出,目前還不清楚到我如何才能獲得最短路徑的長度。 使用類似

g.V(3).repeat(out()).until(id().is(4).and().simplePath()).path().size() 

返回結果(返回的行數)的大小,而

g.V(3).repeat(out()).until(id().is(4).and().simplePath()).path().by(__size()) 

返回一個錯誤。

下面是我正在試驗的圖表,如果有人想玩一下。

graph = TinkerGraph.open() 
e0 = graph.addVertex(T.id, 0, label, "User", "name", "e0") 
e1 = graph.addVertex(T.id, 1, label, "User", "name", "e1") 
e2 = graph.addVertex(T.id, 2, label, "User", "name", "e2") 
e3 = graph.addVertex(T.id, 3, label, "User", "name", "e3") 
e4 = graph.addVertex(T.id, 4, label, "User", "name", "e4") 
e0.addEdge("Feedbacks", e2) 
e0.addEdge("Meets", e1) 
e2.addEdge("Feedbacks", e4) 
e2.addEdge("Meets", e4) 
e3.addEdge("Feedbacks", e0) 
e3.addEdge("Meets", e2) 
e4.addEdge("Feedbacks", e0) 
g = graph.traversal() 

回答

8

有對你的最短路徑查詢略短的變體:

g.V(3).repeat(out().simplePath()).until(hasId(4)).path().limit(1) 

你的假設,第一路徑總是最短路徑,是正確的。 要獲得路徑長度,你可以使用count(local)

g.V(3).repeat(out().simplePath()).until(hasId(4)).path().count(local) 

UPDATE

關於你更新的查詢,這一個應該解決的問題:

g.V().as("e0").out("Feedbacks").as("e1").select("e0"). 
     repeat(out("Meets")).until(where(eq("e1"))).path(). 
     map(union(count(local), constant(-2)).sum()).as("len"). 
     select("e0","e1","len") 

我從減去2總體路徑長度,因爲我認爲你只對repeat()塊所穿過的路徑長度感興趣,而out().select()一開始不應該是包括在內。如果情況並非如此,那麼你可以簡單地用count(local).as("len").替換第三條線。

+0

謝謝@Daniel Kuppitz。當你在寫你的答案時,我修改了這個問題。您是否有一點時間來檢查新的請求,也就是說,我如何參考'until()'步驟中以前的別名節點? – Alberto

+0

再次感謝丹尼爾 – Alberto

+0

對不起,再次困擾,但..我現在試圖通過計算'Meets'*無向*('兩個('Meets')')最短路徑的長度合併兩個問題的結果連接由反饋邊緣連接的兩個頂點。這並不是微不足道的,因爲我不能使用'as('e0')''''select('e0')'模式在'repeat()'裏面使用'simplePath()',我不能選擇第一個路徑在'until()'之後有一個'limit(1)',否則我會失去解決方案。你有什麼想法如何解決這個問題? – Alberto

相關問題