[图]python实现图的遍历、最小生成树、最短路径

目录

1、图遍历

2、最小生成树-Prime算法

3、最短路径-Dijkstra算法

图的两种常用的表示方式是邻接矩阵和邻接表。以下以邻接矩阵为例,图的初始化定义:

class Graph():
    def __init__(self,nodeNum,sides,direction=False):
        self.nodeNum = nodeNum #顶点
        self.amatrix = [[0]*(nodeNum+1) for i in range(nodeNum+1)]   #邻接矩阵
        for side in sides:
            u,v,w = side
            if(direction):
                self.amatrix[u][v]=w
            else:
                self.amatrix[u][v]=w
                self.amatrix[v][u]=w

1、图遍历

在图遍历时,有两种常用的访问顶点的顺序,深度优先遍历和广度优先遍历。以下图为例,深度优先遍历的结点为:1、2、3、4、6、5、7、8、9,广度优先遍历的结点为:1、2、3、5、4、7、8、6、9.

《[图]python实现图的遍历、最小生成树、最短路径》

深度优先遍历的迭代版本如下:

def dfs(graph,v):
    visitnodes.append(v)
    for j in range(graph.nodeNum+1):
        if((graph.amatrix[v][j]>0) and (j not in visitnodes)):
            dfs(graph,j)
            
graph = Graph(9,[[1,2,1],[2,3,1],[3,4,1],[2,5,1],[4,6,1],[5,7,1],[5,8,1],[8,9,1]])    
visitnodes = []
dfs(graph,1)
print(visitnodes)

[1, 2, 3, 4, 6, 5, 7, 8, 9]

 

2、最小生成树-Prime算法

生成树拥有最少的边,保持各顶点之间的连通性,如果区域中包含了n个顶点,生成树包含n-1条边。最小生成树,将生成树边的权重加和最小的生成树。Prime算法,从已连通区域和未连通区域链接的边中,选择一条权重最小的边,加入到生成树中,已下图为例,加入到生成树中的边以此为:1->2,1->3, 3->4, 4->6, 6->5.

《[图]python实现图的遍历、最小生成树、最短路径》

#最小生成树--prime算法(借用堆存储边)
import heapq

def getMinimumSpanningTree(graph,v):
    minimumSpanningTree = []
    visitnodes.append(v)
    edges = []
    for j in range(graph.nodeNum+1):  #从节点v出发的边入堆
        if(graph.amatrix[v][j]>0):
            heapq.heappush(edges,[graph.amatrix[v][j],v,j])
    k=1
    while(k < graph.nodeNum):
        w,vi,vj = heapq.heappop(edges)  #输出权重最小的一条边
        if (vj not in visitnodes):  #若该边链接的节点未被访问,将节点vj出发的边插入堆中
            minimumSpanningTree.append([vi,vj,w])
            visitnodes.append(vj)
            for i in range(graph.nodeNum+1):
                if(graph.amatrix[vj][i]>0):
                    heapq.heappush(edges,[graph.amatrix[vj][i],vj,i])
            k=k+1
    return minimumSpanningTree
        
    
graph = Graph(6,[[1,2,1],[1,3,2],[2,4,11],[2,3,6],[3,4,9],[3,5,13],[4,5,7],[4,6,3],[5,6,4]])
visitnodes = []
minimumSpanningTree = getMinimumSpanningTree(graph,1)
print(minimumSpanningTree)

[[1, 2, 1], [1, 3, 2], [3, 4, 9], [4, 6, 3], [6, 5, 4]]

 

3、最短路径-Dijkstra算法

该算法计算从源结点到图中所有其他顶点之间的最短路径的距离,重复地选取那些还没有被包含且具有最短路径距离的顶点。算法的输出是results是一维数组,元素值是下标对应顶点到源顶点的距离,还使用一个中间变量included,记录是否查找到对应顶点到源顶点的最短距离。

《[图]python实现图的遍历、最小生成树、最短路径》

#单源点的最短路径问题--dijkstra算法
import math

def getMinDistance(graph,v):
    #初始化results,included
    results = [math.inf] * (graph.nodeNum+1)
    results[v] = 0
    included = [False]*(graph.nodeNum+1)
    included[v] = True 
    for i in range(graph.nodeNum+1):
        if(graph.amatrix[v][i]>0):
            results[i] = graph.amatrix[v][i]
    
    while(included.count(True) < graph.nodeNum):
        mindata = math.inf
        includenode = 0    #选取未获得最短路径(include[v]=false)且results[v]最小的结点,源结点到该结点v的最短路径已找到
        for i in range(len(results)):
            if((not math.isinf(results[i])) and (not included[i]) and (mindata > results[i])):
                mindata = results[i]
                includenode = i
        included[includenode]=True
        
        for i in range(graph.nodeNum+1):   #根据结点v出发的边,更新源结点到v链接结点的距离。
            if(graph.amatrix[includenode][i] > 0):
                newdistance = results[includenode] + graph.amatrix[includenode][i]
                if(newdistance < results[i]):
                    results[i] = newdistance
   
    return results

graph = Graph(6,[[1,2,1],[1,3,12],[2,3,9],[2,4,3],[3,5,5],[4,3,4],[4,5,13],[4,6,15],[5,6,4]],True)
results = getMinDistance(graph,1)
print(results)

[inf, 0, 1, 8, 4, 13, 17]

 

 

参考资料:

数据结构《python语言描述》

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/woniu201411/article/details/84034971
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞