Python算法

      Prim算法  

一个图的生成树是以最少的边连通图中的所有顶点,且不产生回路的连通子图。如果一个图有n个顶点,那么生成树会含有图中全部的n个顶点,但只有n-1条边。如果为图的每条设置一个权重,这种图就叫加权图如图12.25所示

 

12.25  加权图

12.25所示的加权图中,一共4生成树,如图12.26所示

 

12.26  四个生成树

加权图所有生成树中,边的权重之和是所有生成树中最小的生成树叫最小生成树。例如,12.25所示的加权图的最小生成树如图12.27所示。

 

12.27  最小生成树

因为许多问题都可以用图来表示,因此在一个加权图中查找最小生成树的应用也比较广泛例如计算两地的最短距离。下面介绍获得加权图的最小生成树的两种算法Prim算法和Kruskal算法
Prim算法即普里姆算法通过该算法可以加权图中查找最小生成树。对于一个加权图G=(V,E),假设UV两个顶点的集合。其中V={1,2,…,n}U={1}VU差集所产生的集合中找出一个顶点集U最近(权重最小的一个顶点w构成权重最小的边,且不会产生回路就把该顶点w加入到U集合中。反复执行同样的步骤,直到U集合的顶点个数为n为止
下面以图12.28所示的加权图为例,介绍使用Prim算法查找图的最小生成树的过程。

 

12.28  加权图

由图12.28可知,顶点集合V={A,B,C,D,E,F}。假设以顶点A起始点U={A}
VU差集所产生的集合{B,C,D,E,F}从该集合中找出一个顶点与顶点A构成最小权重的边找到该顶点为B,效果如图12.29所示。

 

12.29  找到距离集合U最近的顶点B

把顶点B加入到U集合。此时U={A,B}VU差集所产生的集合{C,D,E,F}从该集合中找出一个顶点集合U的某个顶点构成最小权重的边找到该顶点为E,效果如图12.30所示。

 

12.30  找到距离集合U最近的顶点E

把顶点E加入到U集合。此时U={A,B,E}VU差集所产生的集合{C,D,F}从该集合中找出一个顶点集合U的某个顶点构成最小权重的边找到该顶点为C,效果如图12.31所示。

 

12.31  找到距离集合U最近的顶点C

把顶点C加入到U集合。此时U={A,B,C,E}VU差集所产生的集合{D,F}从该集合中找出一个顶点集合U的某个顶点构成最小权重的边找到该顶点为D,效果如图12.32所示。

 

12.32  找到距离集合U最近的顶点D

把顶点D加入到U集合。此时U={A,B,C,D,E}VU差集所产生的集合{F}。找出顶点F集合U的某个顶点构成最小权重的边,效果如图12.33所示。

 

12.33  图的最小生成树

把顶点F加入到U集合。此时U={A,B,C,D,E,F}U=V,这样就完成了查找图的最小生成树的过程

该例中应用Prim算法的代码如下:

01  def prim(graph,start):01      vertex_list = ["A","B","C","D","E","F"] #顶点列表02      tree_vertex_list = []                       #最小生成树顶点列表03      tree_vertex_list.append(start)              #最小生成树第一个顶点04      closest = []                                #最小生成树顶点索引列表05      lowcost = []                                #最小生成树各顶点与其他顶点的距离06      n = len(vertex_list)                        #图的顶点个数07      index = vertex_list.index(start)            #起始点的索引08      for i in range(0,n):09          lowcost.append(graph[index][i])         #初始化lowcost列表10          closest.append(index)                   #初始化closest列表11      for i in range(1,n):                        #插入n-1个顶点12          k = 013          min = maxValue14          for j in range(0,n):15              if(lowcost[j]!=0 and lowcost[j]<min):16                  min = lowcost[j]        #获取插入最小生成树的权重最小顶点的权重17                  k = j                   #获取插入最小生成树的权重最小顶点的索引18          tree_vertex_list.append(vertex_list[k]) #加入最小生成树顶点列表19          lowcost[k] = 0                          #最小生成树到该顶点距离20          for j in range(0,n):21              if(lowcost[j]!=0 and graph[k][j]<lowcost[j]):22                  lowcost[j] = graph[k][j]        #更新插入顶点后的lowcost列表23                  closest[j] = k                  #更新插入顶点后的closest列表

【实例12.3  通过Prim算法查找图的最小生成树

有一个加权图如图12.34所示。以顶点A为起始点通过Prim算法查找图的最小生成树

 

12.34  加权图

代码如下:
01 maxValue = float("inf")                         #设置最大值为无穷大02 graph = [[0,9,maxValue,maxValue,maxValue,8,5],    #图的权重列表03          [9,0,6,maxValue,maxValue,maxValue,maxValue],04          [maxValue,6,0,7,maxValue,maxValue,maxValue],05          [maxValue,maxValue,7,0,13,maxValue,10],06          [maxValue,maxValue,maxValue,13,0,12,15],07          [8,maxValue,maxValue,maxValue,12,0,maxValue],08          [5,maxValue,maxValue,10,15,maxValue,0]]09 def prim(graph,start):10     vertex_list = ["A","B","C","D","E","F","G"] #顶点列表11     tree_vertex_list = []                       #最小生成树顶点列表12     tree_vertex_list.append(start)              #最小生成树第一个顶点13     closest = []                                #最小生成树顶点索引列表14     lowcost = []                                #最小生成树各顶点与其他顶点的距离15     n = len(vertex_list)                        #图的顶点个数16     index = vertex_list.index(start)            #起始点的索引17     for i in range(0,n):18         lowcost.append(graph[index][i])         #初始化lowcost列表19         closest.append(index)                   #初始化closest列表20     for i in range(1,n):                        #插入n-1个顶点21         k = 022         min = maxValue23         for j in range(0,n):24             if(lowcost[j]!=0 and lowcost[j]<min):25                 min = lowcost[j]        #获取插入最小生成树的权重最小顶点的权重26                 k = j                   #获取插入最小生成树的权重最小顶点的索引27         tree_vertex_list.append(vertex_list[k]) #加入最小生成树顶点列表28         print(vertex_list[closest[k]]+'—'+vertex_list[k]+'权重:'+str(lowcost[k]))#打印边的权重29         lowcost[k] = 0                          #最小生成树到该顶点距离30         for j in range(0,n):31             if(lowcost[j]!=0 and graph[k][j]<lowcost[j]):32                 lowcost[j] = graph[k][j]        #更新插入顶点后的lowcost列表33                 closest[j] = k                  #更新插入顶点后的closest列表34     print("最小生成树顶点:"+str(tree_vertex_list)) #打印最小生成树各顶点35 prim(graph,"A")                                     #调用函数并设置起始顶点为A                               #调用函数并设置起始顶点为A
最终运行的结果如图12.35所示。

 

12.35  打印图的最小生成树边和顶点

 

 

 

原创文章,作者:guozi,如若转载,请注明出处:https://www.sudun.com/ask/81188.html

(0)
guozi's avatarguozi
上一篇 2024年5月31日 上午11:27
下一篇 2024年5月31日 上午11:28

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注