外存图算法之单源最短路径的MapReduce算法

单源最短路径单机版的经典MapReduce算法是Dijkstra算法。算法每次沿着一个中间顶点遍历这个图,根据到源点的距离确定优先级。在算法运行过程中维护一个堆,每次取堆顶的顶点进行计算,这里没有并行化,因为每次取堆顶的元素,相当于沿着一个顶点进行计算。

Dijkstra算法考察每个顶点u,从而可以确定在堆顶的点可以安全删除,这是一个贪心算法。对应这一个过程,在并行算法进行的过程中,对每个顶点w考察所有前驱引起的源点到w最短距离的变化,根据Dijkstra算法的性质,在第i轮生成距离源的路径包含i条边的结点到源点的最短路径。

算法描述

初始化:

输入:图G(困中结点集合V,边权值邻接表E)

输出:建立键值对,(键:当前结点v的IDv,值:(源结点u到现结点v路径长度初始化为∞,u到v最短路径上前一个结点ID初始化为null,结点v的邻接表,二元组集合{<结点v可直接到达的后继结点IDsuccnode-ID,该边权值edge-cost>}))

过程:

for each v in V do

    输出<.id,(co,null,(sucenode-ID,edge-cosl})>

迭代过程:

Map函数

输入:(键:结点ID,值:(源点到该结点的当前最短路径长度dist,当前具有最小开销的前驱结点next,当前结点的邻接表,二元组集合P=(<结点可直接到达的后继结点ID suc-node-ID,该边权值edge-cost>)))

输出:(键:可达结点ID,值:(源到该结点的当前最短路径长度dist,当前最短路径上的前一个结点ID))

过程:

 for each<succnode-ID,edgecost>in P do

    输出suc-node-ID,(<ID,distance+edgecost>);//计算路径权值累加,更新distance

Reduce 函数

输入:(键:结点ID,值:S=(源点到该结点的当前最短路径长度dist,当前其有最小开销的前驱结点next))

输出:(键:结点ID,值:(源点到该结点的当前最短路径长度dist,当前具有最小开销的前驱结点next,当前结点的邻接表,二元组集合<结点可直接到达的后继结点IDsuccnode-ID,该边权值edge-cost>))

过程:

distance=∞

fnext=NULL

for each(dist,next)∈S do

    if dist < 当前ID记录的dist then

        distance=dist

        fnext=next

给出(ID,<dislance,nert,{<suc-node-ID,edgecost>}>)

迭代终止条件:两轮MapReduce的结果不发生变化;或者设定迭代次数

过程分析

  • 开始对于每个有唯一标记ID的结点v,mapper输人的键值对中键是ID,值是一个多元组(dist,next,<succnode-ID,edge-cost>})

  • 接下来在map阶段,对输入的每个对应键值对为(ID,<dist,next,1<succnode-ID,edge-cost>}>)的结点,需要得到的结果包括要传送它的下一个邻居w的ID,还有它本身记录的到源结点的最短路径加上边(v,u)的长度

  • 在map阶段传送每个结点υ的ID、它到源的路径以及它的邻接表。经过mapper和reducer之间的分组,就可以将经过上一轮前驱得到的源点到w的新路径长度和源到w之前的路径长度相比较选出最小的。

  • reducer传出来的信息包括每个点v的ID,上一轮选出来的源点到v的最短路径开销,以及源点到v最短路径上v的前驱。相当于在reducer里面进行选择。在map阶段要传送当前计算出的源点到w的最短路径开销,过程不断重复,一直到计算出的源点到v的最短路径不发生变化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值