# -*- coding: utf-8 -*-
# /usr/bin/python
# 作者:kimicr
# 实验日期:20190827
# Python版本:3.6.3
# 无环加权有向图的“最长路径”算法(含“负权重”边)
'''
思路:寻找的起点到各点的最长路径,其实修改最短路径算法AcyclicLP就可以得到
主要变化为:设把初始起点到各顶点的距离从“inf”变 "-inf"; 边松弛条件改变,变为与求最短路径相反。
'''
inf = float("-inf")
class AcyclicLP(object):
def __init__(self,Graph,s):
self.Graph = Graph
self.marked = []
self.path = []
self.s = s
for i in range(len(self.Graph[0])):
self.marked.append(0)
#深度优先搜索
def dfs(self,v):
if self.marked[v] == 1:
return
else:
self.path.append(v)
self.marked[v] = 1
count = 0
for key in self.Graph[v]:
if key != inf:
self.dfs(count)
count += 1
#打印顶点S到某一点的最短路径
def PrintPath(self,edgeTo,end):
road = [end]
while edgeTo[end] != None:
road.insert(0,edgeTo[end])
end = edgeTo[end]
return road
#无环有向图最短路径算法
def acycliclp(self):
#初始化、准备阶段
self.dfs(self.s)
deque = self.path[:] #初始化
edgeTo = []
distTo = []
for i in range(len(self.marked)):
edgeTo.append(None)
distTo.append(inf)
distTo[self.s] = 0
self.s = deque.pop(0)
count = 0
for i in self.Graph[self.s]:
if i != inf:
distTo[count] = i
edgeTo[count] =self.s
count += 1
#开始求解阶段
while deque:
count = 0
self.s = deque.pop(0)
for i in self.Graph[self.s]:
if i != inf:
if distTo[self.s] + i > distTo[count]:
distTo[count] = distTo[self.s] + i
distTo[count] =round(distTo[count],2)
edgeTo[count] = self.s
else:
self.Graph[self.s][count] = inf
count += 1
#打印结果
print('最短路径树:',edgeTo,'\n最短距离:',distTo)
for i in range(len(self.Graph[0])):
print("%d to %d(%.2f):" %(self.path[0],i,distTo[i]),end="")
PATH = self.PrintPath(edgeTo[:],i)
if len(PATH) == 1 and PATH[0] == self.path[0]:
print('')
else:
for i in PATH[:-1]:
print('%d->' %(i),end = "")
print(PATH[-1])
if __name__ == "__main__":
Graph = [[inf,inf,0.26,inf,inf,inf,inf,inf],
[inf,inf,inf,0.29,inf,inf,inf,inf],
[inf,inf,inf,inf,inf,inf,inf,inf],
[inf,inf,inf,inf,inf,inf,0.52,0.39],
[0.38,inf,inf,inf,inf,inf,inf,0.37],
[inf,0.32,inf,inf,0.35,inf,inf,0.28],
[0.58,inf,0.40,inf,0.93,inf,inf,inf],
[inf,inf,0.34,inf,inf,inf,inf,inf],
]
F = AcyclicLP(Graph,5)
F.acycliclp()