Dijkstra in python
下面是一段由python实现的Dijkstra算法,一些地方的处理实在非常棒,相比于C,代码的数量已经缩减到了60行,所以我想通过本文简单的介绍一下这段代码的细节之处,首先给出源程序:
from sys import argv def dijkstra_score(G, shortest_distances, v, w):
return shortest_distances[v] + G[v][w] def dijkstra(G, source):
unprocessed = set(G.keys()) # vertices whose shortest paths from source have not yet been calculated
unprocessed.remove(source)
shortest_distances = {source: 0} for i in xrange(len(G) - 1):
# find a vertex with the next shortest path, i.e. minimal Dijkstra score
m, closest_head = float('inf'), 0
for tail in shortest_distances:
for head in G[tail]:
if head in unprocessed:
d = dijkstra_score(G, shortest_distances, tail, head)
if d < m:
m, closest_head = d, head unprocessed.remove(closest_head)
shortest_distances[closest_head] = m # in case G is not fully connected
for vertex in unprocessed:
shortest_distances[vertex] = float('inf') return shortest_distances def get_graph():
filename = argv[1]
graph = {}
with open(filename) as g:
for line in g:
l = line.split()
vertex = int(l.pop(0))
graph[vertex] = {}
for x in l:
adj_vert, distance = map(int, x.split(","))
graph[vertex][adj_vert] = distance
print "Got graph. Ex: line 1:", graph[1]
return graph def main():
G = get_graph()
""" Input is adjacency list on vertices labelled 1 to n, including segment length. Example line of file:
1 3,45 92,4 This means that v. 1 is adjacent to v. 3 with edge length 45 and adjacent to v. 92 with edge length 4.
"""
source = int(raw_input("Enter source vertex: "))
destination_vertices = map(int, raw_input("List destination vertices:\n").split()) distances = dijkstra(G, source) print "From vertex %d:" % source
for vertex in destination_vertices:
print "The distance to vertex %d is %d." % (vertex, distances[vertex]) if __name__ == '__main__':
main()
使用方法:通过外部的文件定义图的构造,每一行的格式为:顶点 到达的顶点,距离 到达的顶点,距离
下面就从每一行值得注意的代码进行分析:
1、图的构造
def get_graph():
filename = argv[1]
graph = {}
with open(filename) as g:
for line in g:
l = line.split()
vertex = int(l.pop(0))
graph[vertex] = {}
for x in l:
adj_vert, distance = map(int, x.split(","))
graph[vertex][adj_vert] = distance
print "Got graph. Ex: line 1:", graph[1]
return graph
这里的图使用邻接表的形式存储,具体的实现采用的python当中的字典,一开始graph为空,graph={}
然后打开存储图的文件,注意这里采用了with语句,相当于try和finally的合体,open函数打开文件并将的返回值给了g。在文件g中的每一行使用split操作,去除空格,得到的l是一个列表,其中第一项就是原点,其余的各项就是原点达到的其他的顶点及其距离。所以将每一个原点放进图graph中作为字典下标,而字典的值仍旧是一个字典,包括了两项,第一项是原点到达的一个顶点,第二项是路径的权值,最后将这两项放入graph中对应的下标构成的字典中。
这样,图就算是构成了,得到的一个字典graph, 例如graph={1:{2,3}}表示的是顶点1到顶点2。
2、单源最短路径
接下来就是通过另一个函数来构造出最短路径了:
def dijkstra(G, source):
unprocessed = set(G.keys()) # vertices whose shortest paths from source have not yet been calculated
unprocessed.remove(source)
shortest_distances = {source: 0} for i in xrange(len(G) - 1):
# find a vertex with the next shortest path, i.e. minimal Dijkstra score
m, closest_head = float('inf'), 0
for tail in shortest_distances:
for head in G[tail]:
if head in unprocessed:
d = dijkstra_score(G, shortest_distances, tail, head)
if d < m:
m, closest_head = d, head unprocessed.remove(closest_head)
shortest_distances[closest_head] = m # in case G is not fully connected
for vertex in unprocessed:
shortest_distances[vertex] = float('inf') return shortest_distances
首先,unprocessed保存了图G中所有顶点的集合,用以表示还没有加入到路径中的顶点,初始化时就是全部的顶点,然后,通过传入函数的source确定开始的顶点,并将该顶点从unprocessed中移除。而记录最短路径的方式则通过shortest_distance这个字典,初始化将自己加入,距离为0。
接下来就是按照Dijkstra算法的步骤一步步进行了:对每一个新加入的顶点找到和这个顶点相邻的边,更新每个顶点的最短距离,这里的实现方式就是通过一个大循环i执行len(G)-1次将每一个顶点都进行处理,每一次处理的开始,将m初始化为无穷大,将closest_head初始化为0,注意,m将会被用来存储最短的距离,而closest_head将会被用来存储最短距离的顶点编号。这里,可以将已经处理好的顶点想象成一个相连的图,而下一个加入到这个图中的顶点就是从原点到剩余顶点距离最短的那一个,具体实现是通过遍历shortest_distance处理完成的顶点,这个字典中每一项都记录了从原点到那个顶点的最短路径,然后图中剩下的没有处理的并且相连的节点,通过dijkstra_score这个函数计算从原点到达那个顶点的距离,将其最小值保存在m中,于是,经过所有的顶点的遍历,找到距离最小的那个点,将其放在shortest_distance中,那么这个顶点就处理完了,接下来就是去处理其他剩余的顶点了。
算法同时也考虑了加入没有连通的情况下的距离,将其设置为无穷大,当然,这里所做的一切都假定所有边的权值为非负,因为假如存在负数的权值,那么最短距离可能不存在。
Dijkstra in python的更多相关文章
- Dijkstra算法 python实现
1.Dijkstra算法的基本实现 \(O(n^2)\) 简介: Dijkstra算法是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题.迪杰斯特拉算法主要特点是从起始点开始,采用贪 ...
- 写出优雅又地道的pythonic代码(转自网络)
本文是Raymond Hettinger在2013年美国PyCon演讲的笔记(视频, 幻灯片). 示例代码和引用的语录都来自Raymond的演讲.这是我按我的理解整理出来的,希望你们理解起来跟我一样顺 ...
- 图:无向图(Graph)基本方法及Dijkstra算法的实现 [Python]
一般来讲,实现图的过程中需要有两个自定义的类进行支撑:顶点(Vertex)类,和图(Graph)类.按照这一架构,Vertex类至少需要包含名称(或者某个代号.数据)和邻接顶点两个参数,前者作为顶点的 ...
- Dijkstra 调度场算法 Python实现 一
调度场算法(Shunting Yard Algorithm)是一个用于将中缀表达式转换为后缀表达式的经典算法,由 Edsger Wybe Dijkstra 引入,因其操作类似于火车编组场而得名. — ...
- python代码实现dijkstra算法
求解从1到6的最短路径. python代码实现:(以A-F代表1-6) # Dijkstra算法需要三张散列表和一个存储列表用于记录处理过的节点,如下: processed = [] def buil ...
- Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例
本文实例讲述了Python数据结构与算法之图的最短路径(Dijkstra算法).分享给大家供大家参考,具体如下: # coding:utf-8 # Dijkstra算法--通过边实现松弛 # 指定一个 ...
- python数据结构与算法——图的最短路径(Dijkstra算法)
# Dijkstra算法——通过边实现松弛 # 指定一个点到其他各顶点的路径——单源最短路径 # 初始化图参数 G = {1:{1:0, 2:1, 3:12}, 2:{2:0, 3:9, 4:3}, ...
- 【Python排序搜索基本算法】之Dijkstra算法
Dijkstra算法和前一篇的Prim算法非常像,区别就在于Dijkstra算法向最短路径树(SPT)中添加顶点的时候,是按照ta与源点的距离顺序进行的.OSPF动态路由协议就是用的Dijkstra算 ...
- python利用dijkstra算法求解图中最短距离
利用dijkstra算法,来完成图中两个顶点间最短的距离,可以直接复制使用,只需要修改参数即可 def dijkstra_raw(edges, from_node, to_node): "& ...
随机推荐
- 【原创】ZYNQ学习笔记(一) HelloWorld实现
拿过ZYNQ开发板,里面给了很多部件,果断从网上下载了手册,N多手册和原理图. 要比Spartan-6复杂多了,耐心地看了看,知道ZYNQ系列分为PS(系统)以及PL(逻辑)部分. 之前,自己一直在做 ...
- Android开发:向下一个activity传递数据,返回数据给上一个activity
1.向下一个activity传递数据 activity1 Button button=(Button) findViewById(R.id.button1); button.setOnClickLis ...
- 解决ImportError: cannot import name HTTPConnection的方法
在写python程序的时候,使用from httplib import HTTPConnection,在run的时候提示ImportError: cannot import name HTTPConn ...
- case语句居然还可以这么用的
直接上代码了 // switch case case语句测试.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<ios ...
- java参数传递时到底是值传递还是引用传递
java参数传递时到底是值传递还是引用传递(baidu搜集) 问”,很多人的BLOG里都引用这些面试题,最近因为工作内容比较枯燥,也来看看这些试题以调节一下口味,其中有一道题让我很费解. 原题是:当一 ...
- WindowsPhone8SDK重装后设计器加载异常的处理办法
Close all running instances of Visual Studio 2012 start cmd.exe (as admin/elevated) cd /d %windir%\i ...
- Repeater实例应用
在实际开发过程中,涉及到数据绑定,分页,以及一对多展示数据时,遇到这样的需求我们怎么解决呢?下面以帖子展示来逐一说明. 帖子主要由两部分组成,第一部分是发帖人的原创内容部分,第二部分是用户评论部分,这 ...
- 在SQL Server实现最短路径的搜索
开始 这是去年的问题了,今天在整理邮件的时候才发现这个问题,感觉顶有意思的,特记录下来. 在表RelationGraph中,有三个字段(ID,Node,RelatedNode),其中Node和Rela ...
- xml 实现圆形图 和 椭圆形图
1. 效果图 2.圆形图 <ImageView android:layout_width="wrap_content" android:layout_height=" ...
- Application Pool Identities
Whether you are running your site on your own server or in the cloud, security must be at the top of ...