开篇
写了几篇记录学习图算法,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 return3、松弛函数
#对边(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 True5、习题
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.d4、习题
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