2015-12-02 10 views
5

Ich weiß, dass dies mehrere Male gefragt wurde, aber ich habe keinen Hinweis auf die letzte Version von Tinkerpop (3.1) gefunden, mit vielen neuen nützlichen Funktionen, die wir verwenden können unsere Durchquerungen.Der beste Weg, um einen kürzesten Weg zwischen zwei Knoten in Tinkerpop zu finden 3.1

Angenommen, ich muss einen kürzesten Weg zwischen den Knoten 3 und 4 finden. Ist dieser Traversal Sound?

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

Hier gehe ich davon aus, dass, wenn ich ein BFS-Such bin Looping ausgeführt wird (also ist das erste Ergebnis der kürzeste Weg) als it seems that this was the case with the loop() function.

Gibt es außerdem eine Möglichkeit, eine zuvor gebundene Variable (unter Verwendung eines as-Schritts) in den Schritt until einzuschließen? Genauer gesagt, ich versuche zwei Knoten während der Traversal zu wählen, und dann zwischen ihnen den kürzesten Weg zu finden, zum Beispiel

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') 

Schließlich wird, wie aus dem vorherigen Traversal gesehen werden kann, ist es nicht klar ist, zu mir, wie ich die Länge des kürzesten Weges bekommen kann. mit so etwas wie

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

gibt die Größe des Ergebnisses (Anzahl der zurückgegebenen Zeilen), während

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

einen Fehler zurückgibt.

Hier ist der Graph, mit dem ich experimentiere, sollte jemand ein bisschen spielen wollen.

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() 

Antwort

8

Es gibt eine etwas kürzere Variante für Ihre kürzesten Weg Abfrage:

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

Ihre Annahme, dass der erste Weg ist immer der kürzeste Weg ist richtig. Um die Weglängen, können Sie verwenden count(local):

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

UPDATE

In Bezug auf Ihre aktualisierte Abfrage sollte diese ein, das Problem lösen:

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") 

ich subtrahieren 2 von der Gesamtweglänge, weil ich denke, dass Sie nur an der Länge des Weges interessiert sind, der durch den Block repeat() durchlaufen wird und der out().select() am Anfang nicht sein sollte inbegriffen. Wenn das nicht der Fall ist, können Sie einfach die 3. Zeile durch ersetzen.

+0

Dank @Daniel Kuppitz. Während du deine Antwort geschrieben hast, habe ich die Frage modifiziert. Haben Sie etwas Zeit, um die neue Anfrage zu überprüfen, dh, wie ich im 'bis()' Schritt auf einen zuvor aliasierten Knoten referenziere? – Alberto

+0

Nochmals vielen Dank, Daniel – Alberto

+0

Tut mir leid, dass ich mich wieder ärgere, aber .. Ich versuche nun, die Ergebnisse der beiden Fragen zusammenzuführen, indem ich die Länge des 'meets' * ungerichteten * ('meets ') kürzesten Pfads berechne Verbinden von zwei Eckpunkten, die durch eine Feedback-Kante verbunden sind.Es ist nicht so trivial, da ich 'simplePath()' nicht innerhalb der 'repeat()' wegen der 'as ('e0')' - select ('e0') 'Muster verwenden kann, und ich kann den ersten Pfad nicht mit auswählen a 'limit (1)' nach 'bis()' da ich sonst die Lösung verliere. Hast du eine Idee, wie du das angehen kannst? – Alberto