'
我正在研究Graphx In Action和这本书 (其源代码在这里:https://github.com/insidedctm/spark-graphx-in-action) 讨论了两种计算距离的方法 树的根与所有节点之间的(边跳数) 到树叶。我了解使用提供的代码示例 gregationMessages。特别地,停止条件是有意义的(我有 通过包含以下内容的评论突出显示了该条件: 文字“ STOP CONDITION”,如下所示。) 图停止更改,继续运行算法不再有意义。
当我看着Pregel的计算方法时,我有点困惑 相同的结果(如下所示)。
尤其是在调用Pregel的apply方法时,maxIterations 是默认值Integer.MAX_VALUE(出于所有实际目的,“永远运行”。) 因此,似乎是“ sendMsg”函数,即:
(et:EdgeTriplet[Int,String]) =>
Iterator((et.dstId, et.srcAttr+1)),
即使在顶点上的值收敛后,也将被无限调用。
我是否忽略了某些机制 导致程序收敛后停止?
// aggregateMessages approach
// from: https://github.com/insidedctm/spark-graphx-in-action/blob/51e4c667b927466bd02a0a027ca36625b010e0d6/Chapter04/Listing4_10IteratedFurthestVertex.scala
def sendMsg(ec: EdgeContext[Int,String,Int]): Unit = {
ec.sendToDst(ec.srcAttr+1)
}
def mergeMsg(a: Int, b: Int): Int = {
math.max(a,b)
}
def propagateEdgeCount(g:Graph[Int,String])
:Graph[Int,String] = {
val verts =
g.aggregateMessages[Int](sendMsg, mergeMsg)
val g2 =
Graph(verts, g.edges)
val check =
g2.vertices.join(g.vertices).
map(x => x._2._1 – x._2._2).
reduce(_ + _)
// STOP CONDITION
// check here ensures stop if nothing changed (******)
if (check > 0)
propagateEdgeCount(g2)
else
g
}
// Pregel approach
val g = Pregel(myGraph.mapVertices((vid,vd) => 0), 0,
activeDirection = EdgeDirection.Out)(
(id:VertexId,vd:Int,a:Int) => math.max(vd,a),
(et:EdgeTriplet[Int,String]) =>
Iterator((et.dstId, et.srcAttr+1)),
(a:Int,b:Int) => math.max(a,b))
g.vertices.collect
答案 0 :(得分:0)
据我所知,如果所有节点都停止运行,则pregel将自行停止工作。
停止所有节点有两种方法,可以通过不再更改所有节点的属性来实现:
1。给出发送消息的条件,换言之,如果给定条件为假,节点将停止发送消息。
2。给出一个函数,该节点在多次迭代后将停止运行, 也就是说,尽管发送消息的条件仍然成立,但是所有节点的属性都不再更改。
val bfs2 = initialGraph2.pregel(Double.PositiveInfinity)(
(id, attr, msg) => math.min(attr, msg),
triplet => {
if (triplet.srcAttr != Double.PositiveInfinity && triplet.dstAttr ==
Double.PositiveInfinity) {Iterator((triplet.dstId, triplet.srcAttr+1))}
else {Iterator.empty}},
(a,b) => math.min(a,b) ).cache()
"triplet.dstAttr == Double.PositiveInfinity"
是继续条件。
如果所有节点的大小都小于Double.PositiveInfinity,则发送消息操作将停止,显然所有节点都将停止。