最近有个需求,求图节点到其他节点的所有路径或者前几条最短路径,发现官方例子只有求最短路径而已,还有一个变种就是把最短路径的节点给保存下来而已。
- 基于此既然能把中间节点保留下来,那么按道理来说保留前几个最短路径也是可行的
- 仔细研究了pregel的过程,理解各个过程的作用
a.vprog,作用是处理到达顶点的参数,取较小的那个作为顶点的值
b. sendMsg,计算权重,如果邻居节点的属性加上边上的距离小于该节点的属性,说明从源节点比从邻居节点到该顶点的距离更小,更新值
c.mergeMsg,合并到达顶点的所有信息
3. 仿照最短路,设置求所有路径msg
/**
* 最短路径
*
* @param sourceId 源节点Id
* @param current 当前节点的距离
* @param values 接受点的距离
* @param max_n 最大接受点个数
* @param routes 接受点的路径
*/
case class AcceptRoutes(sourceId: Long, current: Double, values: Array[Double], routes: Array[List[VertexId]], max_n: Int = 5) {
override def toString: String = s"AcceptRoutes($sourceId,$current,Array(${values.mkString(",")}),Array(${routes.mkString(",")}),$max_n)"
}
其中max_n,是保留当前节点最大来源路径。
vprog的改写:
(vertexId, vertexValue, msg) => {
//if (vertexValue.current < msg.current) vertexValue else msg
val min = math.min(vertexValue.current, msg.current)
val left = vertexValue.values.zip(vertexValue.routes)
val right = msg.values.zip(msg.routes)
val union = left.union(right).distinct.filter(y => y._1 < Double.PositiveInfinity).sortBy(_._1).take(vertexValue.max_n)
AcceptRoutes(vertexId, min, union.map(_._1), union.map(_._2), vertexValue.max_n)
},
sendMsg的改写:
triplet => { //s