我试图找到从节点 A 到节点 B 的路径长度的所有路径 < 10 using GraphFrames. I can do it using the following code, but, was wondering if there is a better way to do this.
val graph = GraphFrame(vertices, edges)
val motif1 = graph.find("(start)-[]->(d1)").select($"start.id".as("start_id"), $"d1.id".as("end_id"))
val motif2 = graph.find("(start)-[]->(d1); (d1)-[]->(d2)").select($"start.id".as("start_id"), $"d2.id".as("end_id"))
val motif3 = graph.find("(start)-[]->(d1); (d1)-[]->(d2); (d2)-[]->(d3)").select($"start.id".as("start_id"), $"d3.id".as("end_id"))
val motif4 = graph.find("(start)-[]->(d1); (d1)-[]->(d2); (d2)-[]->(d3); (d3)-[]->(d4)").select($"start.id".as("start_id"), $"d4.id".as("end_id"))
val motif5 = graph.find("(start)-[]->(d1); (d1)-[]->(d2); (d2)-[]->(d3); (d3)-[]->(d4) ; (d4)-[]->(d5) ").select($"start.id".as("start_id"), $"d5.id".as("end_id"))
val motif6 = graph.find("(start)-[]->(d1); (d1)-[]->(d2); (d2)-[]->(d3); (d3)-[]->(d4) ; (d4)-[]->(d5) ; (d5)-[]->(d6)").select($"start.id".as("start_id"), $"d6.id".as("end_id"))
val motif7 = graph.find("(start)-[]->(d1); (d1)-[]->(d2); (d2)-[]->(d3); (d3)-[]->(d4) ; (d4)-[]->(d5) ; (d5)-[]->(d6) ; (d6)-[]->(d7) ").select($"start.id".as("start_id"), $"d7.id".as("end_id"))
val motif8 = graph.find("(start)-[]->(d1); (d1)-[]->(d2); (d2)-[]->(d3); (d3)-[]->(d4) ; (d4)-[]->(d5) ; (d5)-[]->(d6) ; (d6)-[]->(d7) ; (d7)-[]->(d8) ").select($"start.id".as("start_id"), $"d8.id".as("end_id"))
val motif9 = graph.find("(start)-[]->(d1); (d1)-[]->(d2); (d2)-[]->(d3); (d3)-[]->(d4); (d4)-[]->(d5) ; (d5)-[]->(d6) ; (d6)-[]->(d7) ; (d7)-[]->(d8) ; (d8)-[]->(d9)").select($"start.id".as("start_id"), $"d9.id".as("end_id"))
val motif10 = graph.find("(start)-[]->(d1); (d1)-[]->(d2); (d2)-[]->(d3); (d3)-[]->(d4); (d4)-[]->(d5) ; (d5)-[]->(d6) ; (d6)-[]->(d7) ; (d7)-[]->(d8) ; (d8)-[]->(d9) ; (d9)-[]->(d10)").select($"start.id".as("start_id"), $"d10.id".as("end_id"))
val combined = motif1.union(motif2).union(motif3).union(motif4).union(motif5).union(motif6).union(motif7).union(motif8).union(motif9).union(motif10)
这是我在 pySpark 中的实现:
def createMotif(length):
motifPath = "(a)-[e0]->"
for i in range(1, length):
motifPath += "(n%s);(n%s)-[e%s]->" % (i - 1, i - 1, i)
motifPath += "(z)"
return motifPath
init_motifs = {}
for length in range(1, 11):
motifPath = createMotif(length)
current_motif = g.find(motifPath)
init_motifs[length] = current_motif
在 Scala 中:
val graph = GraphFrame(vertices, edges)
// Search from A to B.
val paths = g.bfs.fromExpr("name = 'A'").toExpr("name = 'B'").run()
paths.show()
// Specify edge filters or max path lengths.
val fancy_paths = { g.bfs.fromExpr("name = 'A'").toExpr("name = 'B'")
.edgeFilter("relationship != 'friend'")
.maxPathLength(10).run() }
或者更简单地说,在 Python 中:
# Search from A to B.
paths = g.bfs("name = 'A'", "name = 'B'")
paths.show()
# Specify edge filters or max path lengths.
fancy_paths = g.bfs("name = 'A'", "name = 'B'"),\
edgeFilter="relationship != 'friend'", maxPathLength=10)
请参阅this,了解有关我们为何使用 BFS 的更多信息。