首页 > 编程语言 > 详细

Implementation of Dijkstra in Python

时间:2015-06-18 22:10:18      阅读:281      评论:0      收藏:0      [点我收藏+]

    这么简单一个算法,懒得花时间去自己实现,然后就想在网上搜搜看是否有现成可用的。谁知试了几个,搞得一肚子气:写得真是太好(垃)用(圾)了。不是没有注释,就是不规范看起来巨不爽,更甚bug满天飞根本不能执行。也怪自己懒,算了不骂人了,因为下边我贴出的例子也是基于GitHub上一个写得较为顺眼的例子,然后自己包了一下,并解析了一下原作的返回内容,使得它符合我的需求:输入一个src-dst pair,返回他们之间的distance 与 path。废话不多说,有图有真相:可以运行。需要的拿走用就是了。

from collections import defaultdict
from heapq import *

def dijkstra_raw(edges, from_node, to_node):
	g = defaultdict(list)
	for l,r,c in edges:
		g[l].append((c,r))
	q, seen = [(0,from_node,())], set()
	while q:
		(cost,v1,path) = heappop(q)
		if v1 not in seen:
			seen.add(v1)
			path = (v1, path)
			if v1 == to_node:
				return cost,path
			for c, v2 in g.get(v1, ()):
				if v2 not in seen:
					heappush(q, (cost+c, v2, path))
	return float("inf"),[]

def dijkstra(edges, from_node, to_node):
	len_shortest_path = -1
	ret_path=[]
	length,path_queue = dijkstra_raw(edges, from_node, to_node)
	if len(path_queue)>0:
		len_shortest_path = length		## 1. Get the length firstly;
		## 2. Decompose the path_queue, to get the passing nodes in the shortest path.
		left = path_queue[0]
		ret_path.append(left)		## 2.1 Record the destination node firstly;
		right = path_queue[1]
		while len(right)>0:
			left = right[0]
			ret_path.append(left)	## 2.2 Record other nodes, till the source-node.
			right = right[1]
		ret_path.reverse()	## 3. Reverse the list finally, to make it be normal sequence.
	return len_shortest_path,ret_path	
				
			
### ==================== Given a list of nodes in topology.
list_nodes_id = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
### ==================== Given constants matrix of topology.
M=99999	# This represents a large distance. It means that there is no link.
M_topo = [
[M, 1,1,M,1,M, 1,1,1,M,M, M,M,M,M,M, M,M,M,M,M],
[1, M,1,M,M,1, M,M,M,M,M, M,M,M,M,M, M,M,M,M,M],
[1, 1,M,1,M,M, M,M,M,M,M, M,M,M,M,M, M,M,M,M,M],
[M, M,1,M,1,M, M,M,M,M,M, M,M,M,M,M, M,M,M,M,M],
[1, M,M,1,M,M, M,M,M,1,1, 1,M,M,M,M, M,M,M,M,M],
[M, 1,M,M,M,M, 1,M,M,M,M, M,M,M,M,M, M,M,M,M,M],
[1, M,M,M,M,1, M,1,M,M,M, M,M,M,M,M, M,M,M,M,M],
[1, M,M,M,M,M, 1,M,1,M,M, M,M,M,M,M, M,M,M,M,M],
[1, M,M,M,M,M, M,1,M,1,M, M,1,M,M,M, M,M,M,M,M],
[M, M,M,M,1,M, M,M,1,M,M, 1,M,M,M,M, M,M,M,M,M],
[M, M,M,M,1,M, M,M,M,M,M, 1,M,1,M,M, M,M,M,M,M],
[M, M,M,M,1,M, M,M,M,1,1, M,M,1,1,M, M,M,M,M,M],
[M, M,M,M,M,M, M,M,1,M,M, M,M,M,1,M, M,M,M,M,M],
[M, M,M,M,M,M, M,M,M,M,1, 1,M,M,1,M, M,1,1,M,M],
[M, M,M,M,M,M, M,M,M,M,M, 1,1,1,M,1, 1,M,M,M,M],
[M, M,M,M,M,M, M,M,M,M,M, M,M,M,1,M, 1,M,1,1,M],
[M, M,M,M,M,M, M,M,M,M,M, M,M,M,1,1, M,M,M,M,1],
[M, M,M,M,M,M, M,M,M,M,M, M,M,1,M,M, M,M,1,M,M],
[M, M,M,M,M,M, M,M,M,M,M, M,M,1,M,1, M,1,M,1,M],
[M, M,M,M,M,M, M,M,M,M,M, M,M,M,M,1, M,M,1,M,1],
[M, M,M,M,M,M, M,M,M,M,M, M,M,M,M,M, 1,M,M,1,M]
]	

### --- Read the topology, and generate all edges
edges = []	
for i in range(len(M_topo)):
	for j in range(len(M_topo[0])):
		if i!=j and M_topo[i][j]!=M:
			edges.append((i,j,M_topo[i][j]))

print "=== Dijkstra ==="
print "Let's find the shortest-path from 0 to 9:"
length,Shortest_path = dijkstra(edges, 0, 9)
print 'length = ',length
print 'The shortest path is ',Shortest_path

执行结果:

技术分享

Davy

2015--6-18

Implementation of Dijkstra in Python

原文:http://blog.csdn.net/davyhwang/article/details/46552655

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!