我想找到连接到特定节点的间接节点。 我尝试使用Graph的连通组件类,如下所示......
graph.connectedComponents
然而,它正在为所有图表提供..但我想要一个特定的节点。
我也试过这样做。
graph.edges.filter(_.srcId == x).map(_.dstId)
这给出了特定节点的直接节点,我必须通过仅使用RDD操作来递归它。 有人可以帮忙吗?
答案 0 :(得分:1)
尝试这样的事情:
graph.edges.filter(_.srcId == x).map(e => (e.dstId, null)).join(
graph.collectNeighborIds(EdgeDirection.Either)
).flatMap{t => t._2._2}.collect.toSet
如果你想要比这更深入,我会使用像 Pregel API 这样的东西。从本质上讲,它允许您重复从节点到节点发送消息并聚合结果。
编辑:Pregel解决方案
我终于让迭代停止了。 编辑以下。鉴于此图:
graph.vertices.collect
res46: Array[(org.apache.spark.graphx.VertexId, Array[Long])] = Array((4,Array()), (8,Array()), (1,Array()), (9,Array()), (5,Array()), (6,Array()), (2,Array()), (3,Array()), (7,Array()))
graph.edges.collect
res47: Array[org.apache.spark.graphx.Edge[Double]] = Array(Edge(1,2,0.0), Edge(2,3,0.0), Edge(3,4,0.0), Edge(5,6,0.0), Edge(6,7,0.0), Edge(7,8,0.0), Edge(8,9,0.0), Edge(4,2,0.0), Edge(6,9,0.0), Edge(7,9,0.0))
我们将发送类型为Array[Long]
的消息 - 所有VertexIds
个已连接节点的数组。消息将上行 - dst
将src
发送VertexId
以及所有其他下游VertexIds
。如果上游节点已经知道连接,则不会发送任何消息。最终,每个节点都知道每个连接的节点,不再发送消息。
首先我们定义vprog
。根据文件:
用户定义的顶点程序,它运行在每个顶点上并接收 入站消息并计算新的顶点值。在第一个 迭代顶点程序在所有顶点上调用并传递 默认消息。在后续迭代中,顶点程序是 仅在接收消息的那些顶点上调用。
def vprog(id: VertexId, orig: Array[Long], newly: Array[Long]) : Array[Long] = {
(orig ++ newly).toSet.toArray
}
然后我们定义sendMsg
- 已修改:已交换src
& dst
用户提供的函数,应用于顶点的边缘 在当前迭代中收到消息
def sendMsg(trip: EdgeTriplet[Array[Long],Double]) : Iterator[(VertexId, Array[Long])] = {
if (trip.srcAttr.intersect(trip.dstAttr ++ Array(trip.dstId)).length != (trip.dstAttr ++ Array(trip.dstId)).toSet.size) {
Iterator((trip.srcId, (Array(trip.dstId) ++ trip.dstAttr).toSet.toArray ))
} else Iterator.empty }
接下来我们的mergeMsg
:
用户提供的函数,它接收两个类型为A的传入消息 并将它们合并为一个类型为A的消息。此函数必须是 交换和联想,理想情况下A的大小不应该 增加。
不幸的是,我们打算在上面的最后一句中违反规则:
def mergeMsg(a: Array[Long], b: Array[Long]) : Array[Long] = {
(a ++ b).toSet.toArray
}
然后我们运行pregel
- 已修改:已移除maxIterations
,默认为Int.MaxValue
val result = graph.pregel(Array[Long]())(vprog, sendMsg, mergeMsg)
你可以看看结果:
result.vertices.collect
res48: Array[(org.apache.spark.graphx.VertexId, Array[Long])] = Array((4,Array(4, 2, 3)), (8,Array(8, 9)), (1,Array(1, 2, 3, 4)), (9,Array(9)), (5,Array(5, 6, 9, 7, 8)), (6,Array(6, 7, 9, 8)), (2,Array(2, 3, 4)), (3,Array(3, 4, 2)), (7,Array(7, 8, 9)))