图论相关算法:Dijkstra、Kruskal、Prim

图论常识汇总:
所有顶点之间都有边的图称为完全图
n个顶点的无向图有n(n-1)/2条边,n个顶点的有向图有n(n-1)条边
一个顶点的度数表示他的边的个数
所有顶点的度数除以二分之一就是边数。如果是有向图,那么还分出度和入度。
有根图表示存在一个顶点 到其他所有定点都有路径。根顶点不一定只有一个。
连通表示两个顶点之间存在路径。
连通无向图:任意两个顶点之间连通就是连通无向图
强连通有向图:对于有向图,任意两个顶点都双向连通就表示强连通有向图
完全图都是连通图。
带权连通无向图称为网络。
图可以用邻接矩阵来表示,矩阵一般比较稀疏,节省空间可以用字典存储。
生成树:从任意顶点出发遍历图的所有顶点可以构成生成树。
权值最小的生成树称为最小生成树 MST

图论相关算法:Dijkstra、Kruskal、Prim_第1张图片

图论相关算法:Dijkstra、Kruskal、Prim_第2张图片


class Gragh:
    def __init__(self,gragh):
        self.graph = gragh[:]
        self.point = ['A','B','C','D','E']

    def show(self):
        print(self.graph)

    def Kruskal(self):
        '''
        Kruskal用于生成 最小生成树
        在所有边中不停寻找最小边,直到所有顶点被连入连通分量
        '''
        graph = self.graph[:]
        lst = sorted(graph,key=lambda x: x[-1])#先把所有的边按从小到大排序
        d = {}
        for i in self.point:
            d[i] = -1
        path = []
        for loca in lst:
            d[loca[0]] = d.get(loca[0]) + 1
            d[loca[1]] = d.get(loca[1]) + 1
            if not d[loca[0]] or not d[loca[1]]:#如果有一个不存在就加入路径
                path.append(loca)
        print(path)
        return path

    def Prim(self):
        '''
        Prim 算法同样用于生成最小生成树
        随机确认一个初始顶点,查看其所有的边,找到最短的加到路径
        重复上述步骤 直到包含所有的顶点'''
        path = set()
        l = ['B']#这里初始点可以随便改
        graph = self.graph[:]
        lst = sorted(graph, key=lambda x: x[-1])  # 先把所有的边按从小到大排序
        while len(l)<5:#当所有顶点包含在内的时候就退出循环
            ll = [x for x in lst if x[0] in l or x[1] in l]
            for i in ll:
                if i[0] not in l or i[1] not in l:
                    path.add(i)
                    tar = i[0] if i[0] not in l else i[1]
                    l.append(tar)
                    break
        print(path)
        return path



    def Dijkstra(self,init_point):
        '''Dijkstra 用于寻找最短路径,类似于动态规划
        首先确认初始顶点,寻找下一个边界顶点,记录并更新最短的路径,直到所有顶点被遍历。'''

        #初始化
        graph = self.graph[:]
        path = [[x] for x in graph if x[0] == init_point]
        new_path = []#用于存放下一个边界的路径
        d = {}
        for i in path:
            d[''.join([i[0][0],i[0][1]])] = i[0][-1],i
        n = 0#用于记录是否还有节点
        t = 0
        #循环
        print('initial path ==={}   inital d{}'.format(path,d))
        while True:
            print('=====================================================')
            for i in path:#对于每个路径i,查找他的下一个节点,形成新路径 [(ab3),(bc2)],[bc2]
                point = i[-1][1]
                l = [x for x in graph if x[0]== point]
                print('当前路径{} 可供挑选的边界 :{}'.format(i,l))
                for j in l:#对于所有可能的下一节点j
                    if j[1] in [f[0] for f in i]:#假如形成了环路就跳过,这一点非常重要,否则无限循环。
                        continue
                    else:
                        n+=1
                        tarl = i[:]
                        tarl.append(j)
                        new_path.append(tarl)

            for i in new_path:
                stri = ''.join([i[0][0],i[-1][1]])
                distance = sum([j[-1] for j in i])
                print(stri,i,distance)
                if not d.get(stri,False):#假如是新路径,就添加路径
                    d[stri] = distance,i
                if d.get(stri,False):#假如已经存在路径就查看是否更小

                    if distance

你可能感兴趣的:(数据结构与算法,图论,python,数据结构与算法)