开篇
写了几篇记录学习图算法,Want先生很不耐烦的提出了自己的问题:他妈的,你扯了那么多算法,我的要求很简单,告诉我从点s到点v有几条路可以到达?其中那条路妹子最多?他妈的要是我敢时间那条路最快?
或许这篇文章可以回答want先生的问题,当然也有许多aspire先生,你写的这些文章对我一点用都没有,我希望的文章是能直接解决我遇到的问题,对此,我很抱歉,希望你能找到灵感,看到一坨屎也能产生灵感,如果是的,我很高兴这是那坨屎。
对加权有向图G=(V,E),对每个顶点v属于V,都设置一个属性d[v],用来描述从原点s到v的字段路径上权值的上届,称为最短路径估计(松弛技术的理论基础)
三角不等式性质:
对任意边(u,v)属于边集E,有 min(s,u) < = min(s,u) + w(u,v)
上届性质:
对任意顶点v属于V,有d[v] >= min(s,v),而且一旦d[v] 达到min(s,v)值就不在改变
无路径性质:
如果从s到v不存在路径,则总是有d[v] = min(s,v) =正无穷
收敛性质:-
如果路径(s,...,u,v)是s到v的最短路径,而且在松弛边(u,v)之前的任何时间d[u] = min(s,u),则在松弛边(u,v)后总有d[v] = min(s,v)
路径松弛性质(本人认为是最直观的性质,可以根据直接写出算法的性质):
如果路径p=(v1,...,vk)是v1到vk的最短路径,而且p按照(v1,v2)(v2,v3)...(Vk-1,Vk)的顺序进行松弛,那么d[k] = min(v1,vk)。这个性质保持并不受其他松弛操作的影响,即使他们与p的边上的松弛操作混合在一起也是一样的。
class G:
vector = []#数组,用邻接表方式存储图,用顶点在数组位置标识顶点
d = []#存储顶点的距离
p =[]#存储顶点的父母
2、初始化函数
#初始化,将所有顶点的父母置为NULL,将所有顶点v的d[v]设为无穷,将s的d[s]设为0
def Initialize_single_source(G1,s):
for u in range(0,len(G1.vector)):
G1.d.append(None)#adas
G1.p.append(None)
G1.d[s] = 0
return
3、松弛函数
#对边(u,v),进行松弛操作,w为计算边的权重函数
def relax(u,v,G1,w):
weight = w(u,v)
if comp_d(G1.d[u],weight,G1.d[v]):
G1.d[v] = G1.d[u] + weight
G1.p[v] = u
return
def bellman_ford(G1,w,s):
Initialize_single_source(G1,s)
for n in range(0,len(G1.vector)-1):
for u in range(0,len(G1.vector)):
for v in G1.vector[u]:
relax(u,v,G1,w)
for u in range(0,len(G1.vector)):
for v in G1.vector[u]:
weight = w(u,v)
if comp_d(G1.d[u],weight,G1.d[v]):
return False
return True
5、习题
3、有向无回路图中的单源最短路径---算法
def dag_top_sort(G1,w,s):
ret_sort = top_sort(G1)
Initialize_single_source(G1,s)
for u in ret_sort:
for v in G1.vector[u]:
relax(u,v,G1,w)
print G1.vector
print G1.p
print G1.d
4、习题
4.1、给出一个高效算法来统计有向无回路图中的全部路径数。分析所给的算法
2、Dijkstra 是典型的贪心算法,即这个性质路径p(v0,v1,...,vk)是v0到vk的最短路径,由于每条边的权重大于0所以,min(v0,vi)<= min(v0,vj),其中i < j。根据这一性质,我们每一步找出最优选择,最终就可以得到解
class node:
def __init__(self,key,index):
self.key1 = key
self.index = index
def cmpItem(x,y):
if x.key1 == None:
return False
if y.key1 == None:
return True
if x.key1 < y.key1:
return True
return False
def Dijkstra(G1,w,s):
Initialize_single_source(G1,s)
queue1 = prioty_queue(cmpItem)
for i in range(0,len(G1.vector)):
queue1.insert(node(G1.d[i],i))
while len(queue1.data):
u = queue1.getMin()
for v in G1.vector[u.index]:
relax(u.index,v,G1,w)
queue1.decrease(v,G1.d[v])
return
def newCmp(n1,n2):
if n1.key1 > n2.key1:
return True
return False
def get_max_access(G1,s,e):
for n in range(0,len(G1.vector)):
G1.p.append(None)
G1.d.append(0)
G1.d[s] = 1
queue1 = prioty_queue(newCmp)
for n in range(0,len(G1.vector)):
queue1.insert(node(G1.d[n],n))
while len(queue1.data):
u = queue1.getMin()
if u.index == e:
break
for v in G1.vector[u.index]:
newWeight = ((u.index + v)%5+1)/5.0
if newWeight > G1.d[v]:
G1.d[v] = newWeight
G1.p[v] = u.index
queue1.decrease(v,G1.d[v])
cc = e
print cc
while G1.p[cc] != None:
cc = G1.p[cc]
print cc
return