最短路径 Dijkstra算法
# coding: utf-8
#shortest_path.py
## 最短路径
## 使用Dijkstra算法找给定结点到图上其它各点的最短路径
##
##参数g是被遍历的图, A是给定结点的名字
##Dijkstra算法的思想是:
##起初,只有一个结点A,此结点到自己的最短路径确定,值为0
##下一步,扩展此结点的所有相邻结点,形成集合{}。
##
##因为相邻结点都在{}了,所以最近相邻的那个结点B的最短路径也确定,就是AB
##否则,A到B的最短路径必经过C,C属于{},且AC大于AB;故AB一定是到B的肯定最短路径
##
##其它结点的最短路径尚不能确定,因为信息还没完全掌握
##但它们有临时最短路径AC
##
##扩展B的所有相邻结点(未被扩展过的和已经扩展过的)
##刷新临时最短路径(当然已找到肯定最短路径的那些结点不必刷新)
##在所有临时最短路径中找到最短的那个,为肯定最短路径,原因前面论证过
##再扩展,在刷新,再取最小,重复这个循环(实际上我现在已经讲到第二次循环了)
##
##在以后的每步过程中,我们会保证,找到肯定最短路径的所有点都紧紧粘成一团
##且外面裹着一层临时最短路径结点
##注意:
##第一,只有一层,这使得不确定性只有一层,而不会层层传播
##(所谓一层指的是,它必与某个肯定结点直接相连)
##第二,裸露的肯定最短路径点马上要被包起来,不得延迟
##
##我们还保证了,通过所有已知的肯定结点,那些临时点的值都是最优的
##
##因此,我们保证了,这些临时点中最小的那一个一定是肯定结点:
##从里面走最优的;没有更优的办法冲出包围
##当所有结点都加进去时,信息已经完全
##我们做最后一次刷新,这时,所有临时结点也变成肯定结点
##
##错错错,必须使得所有结点都标记为肯定结点
##否则,循环不应退出
INFINITE=1000
from tulei import *
#参数g表示所给图,A表示给定图上的一结点
def Dijkstra_sp(g,A):
#初始化解
answer={}
for i in g.nodes.keys():
#第一位表示路径,第二位表示距离值,第三位表示肯定值
answer=[[],INFINITE,0]
#初始化局部信息图结点列表
part_nodes=[A]
now = A
answer[A]=[[],0,1]
#循环,控制条件是信息图的不完整性
sp=1
## while len(part_nodes) len(g.nodes):
while sp len(g.nodes):
for i in g.who_is(now).neighbors:
## if i not in part_nodes:
## part_nodes.append(i)
new=answer[now][1]+ g.who_is(now).neighbors
if not answer[2] and answer[1]>new:
answer[1]=new
answer[0]=answer[now][0]+[now]
#找出最小的那个临时结点,把它标记成肯定结点
min_value=INFINITE
mi=now
for i in answer:
if not answer[2]:
if answer[1]min_value: mi,min_value=i,answer[1]
now=mi
answer[now][2]=1
sp += 1
print
print "the answer to sp problem"
print "----------------------------------------------------"
for i in answer:
print i," : ",answer
g1=graph('g2')
g1=g1.out()
g1.show()
Dijkstra_sp(g1,'a')
#coding: utf-8
#tulei.py
##一个图中有若干结点,他们的集合称为nodes;
##每个结点(node)有自己的名字,还有邻居,并有到各邻居的权值
import cPickle as p
class node:
def __init__(self,name):
self.name=name
self.father=None
self.neighbors={}
def __repr__(self):
return self.name
def join(self, cost, node_b):
self.neighbors[node_b.name]=cost
node_b.neighbors[self.name]=cost
class graph:
def __init__(self,name):
self.name=name
self.nodes={}
def who_is(self,name):
try:
return self.nodes[name]
except:
return None
def add(self,name_a,cost,name_b):
# 扩充图内容
if not self.who_is(name_a):
a=node(name_a)
self.nodes[name_a]=a
if not self.who_is(name_b):
b=node(name_b)
self.nodes[name_b]=b
self.nodes[name_a].join(cost,self.nodes[name_b])
def save(self):
# 写入文件
yes_or_no = raw_input('save or not(s/n): ')
if yes_or_no == 's':
f = file(self.name+'.data', 'w')
p.dump(self, f) # dump the object to a file
f.close()
def out(self):
# 从文件读出
try:
f = file(self.name+'.data')
return p.load(f)
except:
print self.name+'.data', "NOT found !"
def show(self):
# 显示图内容
print
print "this is ", self.name
print "---------------------------------------------------"
for i in self.nodes.values():
print i, i.neighbors
##g1=graph('g1')
##s1='a,15,b'
##while s1 != 'end':
## s2=s1.split(',')
## g1.add(s2[0],float(s2[1]),s2[2])
## s1=raw_input(':')
##g1.show()
##g1.save()