图论(四)------非负权有向图的单源最短路径问题,Dijkstra算法
Dijkstra算法解决了有向图G=(V,E)上带权的单源最短路径问题,但要求所有边的权值非负。
Dijkstra算法是贪婪算法的一个很好的例子。设置一顶点集合S,从源点s到集合中的顶点的最终最短路径的权值均已确定。算法反复选择具有最短路径估计的顶点u,并将u加入到S中,对u
的所有出边进行松弛。如果可以经过u来改进到顶点v的最短路径的话,就对顶点v的估计值进行更新。

如上图,u为源点,顶点全加入到优先队列中。

,队列中最小值为u(值为0),u出队列,对u的出边进行松弛(x、v、w),队列最小值为x。

将x出列加入S,将x的出边松弛(v、y、w),其中w的值需要更新(4<5),队列最小值为v。

将v出列,加入到S中,将v的出边松弛(w),因x已在S中,故不做松弛。队列中的最小值为y。

将y出列,y加入到S,松弛y的出边(w、z),更新w的值(3<4),队列最小值为w。

将w出列,加入到S中,松弛w的出边(z),队列最小值为z。

将z出列,加入到S中。将z的出边松弛(无),此时队列为空,算法结束。
Dijkstra算法的运行时间依赖于最小优先队列的具体实现。如果简单的运用数组实现求最小值,运行时间为O(V2+E)=O(V2)。
如果图比较稀疏,E=o(V2/lgV),如果用二叉最小堆实现,则为O((V+E)lgV)。
如果用斐波那契堆实现,可以提升到O(VlgV+E)。
import sys
class Vertex(object):
def __init__(self,key):
self.id=key
self.adj={}
def addNeighbor(self,nbr,weight=0):
self.adj[nbr]=weight
def getNeighbors(self):
return self.adj.keys()
def getId(self):
return self.id
def getWeight(self,key):
return self.adj[key]
class Graph(object):
def __init__(self):
self.vertexlist={}
self.size=0
def addVertex(self,key):
vertex=Vertex(key)
self.vertexlist[key]=vertex
self.size+=1
return vertex
def getVertex(self,key):
return self.vertexlist.get(key)
def __contains__(self,key):
if key in self.vertexlist:
return True
else:
return False
def addEdge(self,f,t,weight=0):
if f not in self.vertexlist:
self.addVertex(f)
if t not in self.vertexlist:
self.addVertex(t)
self.vertexlist[f].addNeighbor(self.vertexlist[t],weight)
def getVertices(self):
return self.vertexlist.keys()
def __iter__(self):
return iter(self.vertexlist.values())
def Dijkstra(G,s):
path={}
vertexlist=[]
for v in G:
vertexlist.append(v)
path[v]=sys.maxsize
path[s]=0
queue=PriorityQueue(path)
queue.buildHeap(vertexlist)
while queue.size>0:
vertex=queue.delMin()
for v in vertex.getNeighbors():
newpath=path[vertex]+vertex.getWeight(v)
if newpath<path[v]:
path[v]=newpath
queue.perUp(v)
return path
class PriorityQueue(object):
def __init__(self,path):
self.path=path
self.queue=[]
self.size=0
def buildHeap(self,alist):
self.queue=alist
self.size=len(alist)
for i in xrange(self.size/2-1,0,-1):
self._perDown(i)
def delMin(self):
self.queue[0],self.queue[-1]=self.queue[-1],self.queue[0]
minvertex=self.queue.pop()
self.size-=1
self._perDown(0)
return minvertex def perUp(self,v):
i=self.queue.index(v)
self._perUp(i)
def _perUp(self,i):
if i>0:
if self.path[self.queue[i]]<=self.path[self.queue[(i-1)/2]]:
self.queue[i],self.queue[(i-1)/2]=self.queue[(i-1)/2],self.queue[i]
self._perUp((i-1)/2)
def _perDown(self,i):
left=2*i+1
right=2*i+2
little=i
if left<=self.size-1 and self.path[self.queue[left]]<=self.path[self.queue[i]]:
little=left
if right<=self.size-1 and self.path[self.queue[right]]<=self.path[self.queue[little]]:
little=right
if little!=i:
self.queue[i],self.queue[little]=self.queue[little],self.queue[i]
self._perDown(little) if __name__=='__main__':
g= Graph()
g.addEdge('u','x',1)
g.addEdge('u','v',2)
g.addEdge('u','w',5)
g.addEdge('x','v',2)
g.addEdge('x','y',1)
g.addEdge('x','w',3)
g.addEdge('v','w',3)
g.addEdge('y','w',1)
g.addEdge('y','z',1)
g.addEdge('w','z',5)
u=g.getVertex('u')
path=Dijkstra(g,u)
for v in path:
print v.id,path[v]
图论(四)------非负权有向图的单源最短路径问题,Dijkstra算法的更多相关文章
- 单源最短路径(dijkstra算法)php实现
做一个医学项目,当中在病例评分时会用到单源最短路径的算法.单源最短路径的dijkstra算法的思路例如以下: 如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点.那么( ...
- 【算法导论】单源最短路径之Dijkstra算法
Dijkstra算法解决了有向图上带正权值的单源最短路径问题,其运行时间要比Bellman-Ford算法低,但适用范围比Bellman-Ford算法窄. 迪杰斯特拉提出的按路径长度递增次序来产生源点到 ...
- 0016:单源最短路径(dijkstra算法)
题目链接:https://www.luogu.com.cn/problem/P4779 题目描述:给定一个 n 个点,m 条有向边的带非负权图,计算从 s 出发,到每个点的距离. 这道题就是一个单源最 ...
- 单源最短路径:Dijkstra算法(堆优化)
前言:趁着对Dijkstra还有点印象,赶快写一篇笔记. 注意:本文章面向已有Dijkstra算法基础的童鞋. 简介 单源最短路径,在我的理解里就是求从一个源点(起点)到其它点的最短路径的长度. 当然 ...
- 单源最短路径问题-Dijkstra算法
同样是层序遍历,在每次迭代中挑出最小的设置为已知 ===================================== 2017年9月18日10:00:03 dijkstra并不是完全的层序遍历 ...
- 单源最短路径问题(dijkstra算法 及其 优化算法(优先队列实现))
#define _CRT_SECURE_NO_WARNINGS /* 7 10 0 1 5 0 2 2 1 2 4 1 3 2 2 3 6 2 4 10 3 5 1 4 5 3 4 6 5 5 6 9 ...
- 【算法设计与分析基础】25、单起点最短路径的dijkstra算法
首先看看这换个数据图 邻接矩阵 dijkstra算法的寻找最短路径的核心就是对于这个节点的数据结构的设计 1.节点中保存有已经加入最短路径的集合中到当前节点的最短路径的节点 2.从起点经过或者不经过 ...
- 单源最短路——dijkstra算法
Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 问 ...
- 【模板】单源最短路径(Dijkstra)/洛谷P4779
题目链接 https://www.luogu.com.cn/problem/P4779 题目大意 给定一个 \(n\) 个点 \(m\) 条边有向图,每个点有一个非负权值,求从 \(s\) 点出发,到 ...
随机推荐
- MySQL监控模板说明-Percona MySQL Monitoring Template for Cacti
http://blog.chinaunix.net/uid-16844903-id-3535535.html https://www.percona.com/doc/percona-monitorin ...
- 进程环境之C程序的存储空间布局
从历史上讲,C程序一直由下面几部分组成: 正文段.这是由CPU执行的机器指令部分.通常,正文段是可共享的,所以即使是频繁执行的程序(如文本编辑器.C编译器和shell等)在存储器中也只需有一个副本,另 ...
- PAT 1009
1009. Product of Polynomials (25) This time, you are supposed to find A*B where A and B are two poly ...
- ajax_for example
asp.net mvc 使用Ajax调用Action 返回数据. 使用asp.net mvc 调用Action方法很简单. 一.无参数方法. 1.首先,引入jquery-1.5.1.min.js ...
- 我的第二篇--nginx安装问题之路径问题
这几天还是一直在搭建nginx,并且要在nginx的基础之上配置naxsi(WAF防火墙)并使它生效,但是随之而来的问题也会有很多,也许因为我是个新手,所以遇到的问题要多,不解的问题也要很多,不知道又 ...
- jquery animate() 防止多次执行
参考:关于jquery 怎样让 animate不多次执行呢 当click方法里面,执行animate时,然后点击的比较频繁,那么animate()的动画也会比较多次滚动. 如: function sc ...
- yii下使用oracle中文都变成问号乱码的解决方法
在配置文件中,一般会用以下配置: 'db_oracle'=>array( 'class' => 'CDbConnection', 'connectionString'=>'oci:d ...
- Lodop实现web套打
WEB套打可选方案不多,理想的更少,利用免费控件Lodop+JavaScript实现精确套打,算是较为经典的选择.这种方案其实比较简单,利用一个htm文件就可以实现模板设计过程,几乎是“空手套”式的开 ...
- 冒泡排序小实例 php
源代码如下,仅用于参考: <?php$a = array(10,2,36,14,10,25,23,85,99,45); for($j=0;$j<9;$j++){ for($i=0;$i&l ...
- ASP判断文件地址是否有效
<% Response.Write("<head><style><!--span{ font-size: 9pt }--></style> ...