【算法】python实现无环加权有向图的最短(长)路径算法AcyclicLP

# -*- 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()

你可能感兴趣的:(Python,算法,python,图论)