您好,登录后才能下订单哦!
这篇文章给大家分享的是有关Dijkstra算法与Prim算法有什么区别的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。
Dijkstra算法用于构建单源点的最短路径树(MST)——即树中某个点到任何其他点的距离都是最短的。例如,构建地图应用时查找自己的坐标离某个地标的最短距离。可以用于有向图,但是不能存在负权值(Bellman-Ford可以处理负权值)。
伪代码
Dijkstra() { for each u in G,V { //此处做初始化操作,给每个节点u赋键值+∞,设置空为父节点 u.key = +∞ u.parent = NULL } //选初始点r,Q是无向图G中所有点V的权值优先队列,key可看作源点到u的距离 r.key = 0 Q = G,V while(Q != ∅) { //取出Q中权值最小值的点u u = extractMin(Q) //取点u连接的所有节点(即无向图G的邻接表中的第u个链表) for each v ∈ G.Adj[u] { if (v ∈ Q) and (w(u, v) < key) { //若该节点仍在Q中且权值w(w,v)小于其原始权值,则进行松弛操作! v.parent = u v.key = w(u, v) + u.key } } } }
Prim算法用于构建最小生成树——即树中所有边的权值之和最小。例如,构建电路板,使所有边的和花费最少。只能用于无向图。
伪代码
//无向图G, 权值w, 起始点r MST(G, w, r) { for each u in G,V { //此处做初始化操作,给每个节点u赋键值+∞,设置空为父节点 u.key = +∞ u.parent = NULL } //选初始点r,Q是无向图G中所有点V的权值优先队列,key可看作u到下一个节点v的距离 r.key = 0 Q = G,V while(Q != ∅) { //取出Q中权值最小值的点u u = extractMin(Q) //取点u连接的所有节点(即无向图G的邻接表中的第u个链表) for each v ∈ G.Adj[u] { if (v ∈ Q) and (w(u, v) < key) { //若该节点仍在Q中且权值w(w,v)小于其原始权值,则进行松弛操作! v.parent = u v.key = w(u, v) } } } }
MST中任意AB两点之间的距离,并不比原始图中AB的距离短,即原始图中可能存在边E(A,B)**小于**MST中的E(A,B)。
注意上述两个伪算法的差别只在于最后循环体内的松弛操作。
最小生成树只关心所有边的和最小,所以有v.key = w(u, v),即每个点直连其他点的最小值(最多只有两个节点之间的权值和)
最短路径树只搜索权值最小,所以有v.key = w(u, v) + u.key,即每个点到其他点的最小值(最少是两个节之间的权值和)
简单总结就是,Dijkstra的松弛操作加上了到起点的距离,而Prim只有相邻节点的权值。
都是使用贪婪和线性规划,每一步都是选择权值/花费最小的边。
贪婪:一个局部最有解也是全局最优解;
线性规划:主问题包含n个子问题,而且其中有重叠的子问题。
Dijkstra算法通过线性规划缓存了最优子路径的解,每一步也通过贪婪算法来选择最小的边。
Prim算法通过贪婪来选择最小的边,而Prim的每个子树都是最小生成树说明满足线性规划的两个条件。
Time = θ( V * T1 + E * T2)
其中T1为取出键值最小点的时间,T2为降低键值的时间,取决于数据结构。
数组
T1= O(V), T2 = O(1), TIME = O(V * V + E) = O(V * V)
二叉堆
T1 = O(lgV), T2 = O(lgV), TIME = O(V * lgV + E * lgV)
斐波那契堆
T1 = O(lgV), T2 = O(1), TIME = O(V * lgV + E) = O(V * lgV)
对于稀疏图来说,E远小于V*V,所以二叉堆比较好;
而对于密集图来说,E=V*V,所以数组比较好;
斐波那契堆是最好的情况。
当边的权值都为1的时候,可以用DFS(广度优先搜索)优化时间复杂度。
使用FIFO(先进先出)队列代替优先队列,优化了降低键值T2的操作为O(1)
松弛操作改为
if d[v] = +∞ { d[v] = d[u] + 1 enqueue(Q, v) }
优化了取出键值最小点的时间T1 = O(1)
总的时间复杂度
TIME = V + E
感谢各位的阅读!关于“Dijkstra算法与Prim算法有什么区别”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。