基于union-find的Kruskal算法(读取给定图边权值)

电子科技大学通信网理论基础project2中的基于union-find的Kruskal算法

# -*- coding: utf-8 -*-
"""
Created on Wed May 23 09:31:49 2018

@author: 15193
"""
import numpy as np
import time
start=time.clock()
class Graph(object):
    def __init__(self):       #初始化
        self.nodes=[]
        self.edge={}
    def insert(self,a,b,c):     #添加相应的边
        if not(a in self.nodes):
            self.nodes.append(a)
            self.edge[a]={}
        if not(b in self.nodes):
            self.nodes.append(b)
            self.edge[b]={}
        self.edge[a][b]=c
        self.edge[b][a]=c
    def succ(self,a):     #返回点的有关的边
        return self.edge[a]
    def getnodes(self):    #返回点集
            return self.nodes  
class union_find(object):      #搭建union-find数据结构
    def __init__(self,size):
        self.parent=[]
        self.rank=[]
        self.count=size
        for i in range(0,size):
            self.parent.append(i)
            self.rank.append(1)
    def find(self,i):
        if self.parent[i]!=i:
            self.parent[i]=self.find(self.parent[i])
        return self.parent[i]
    def union(self,i,j):
        p=self.find(i)
        q=self.find(j)
        if p==q:
            return False
        if self.rank[p]<self.rank[q]:   #根据树的大小进行合并,尽量使得小树并到大树上
            self.parent[p]=q
            self.rank[q]=self.rank[q]+self.rank[p]
        elif self.rank[p]>self.rank[q]:
            self.parent[q]=p
            self.rank[p]=self.rank[p]+self.rank[q]
        else:
            self.parent[q]=p
            self.rank[p]=self.rank[p]+self.rank[q]
        self.count=self.count-1
        return True
f=open('D:\graph_1.txt','r')   #打开D盘的graph文件,用f表示
graph=Graph() 
lineList = f.readlines()
length=len(lineList)      #读取的行数
i=0
for line in lineList: #一行读取点的关系
    if line in lineList[0]:
        n,m=line.split()
        print("该图有",n,"个点")
        print("该图有",m,"条边")
        nodes_list=np.zeros((length-1,3), dtype=np.int16)
    else:
        a,b,c=line.split()
        nodes_list[i,0]=a
        nodes_list[i,1]=b
        nodes_list[i,2]=c
        i=i+1
        graph.insert(a,b,c)    #将图结构的相关信息读进去
f.close()     #将读取得到的图关掉
#print(graph.getnodes())
##接下来将图中所有边的权值进行排序
nodes_list=nodes_list[nodes_list[:,2].argsort()] #按照第3列对行排序
#print(nodes_list)
nodes=graph.getnodes()
world=union_find(int(n))
T=0   #T作为记录MST的标志
j=0   #j作为按照降序排列的边序号
while(world.count!=1):
    if world.union(int(nodes_list[j,0]),int(nodes_list[j,1]))==True:
        T=T+nodes_list[j,2]
    else:
        pass
    j=j+1
print("MST:",T)
end=time.clock()
total_time=end-start
print("总耗时:"+str(total_time))   #整个算法的运行时间

在完成了整个算法的实现,最后得到相应算法的验证和仿真,我感觉我收获了很多。

集中体现在几个方面:

   1 对python的代码功底得到提升,动手能力和逻辑思考能力得到锻炼。

   2 在编程的时候,寻找合适的数据结构,对于算法的优化很有帮助。

   3  kruskal的调试过程中,还算简单,相比于难受的prim算法,我用了四个小时用在了调试上,这一点上,还是得说kruskal选取了一个合适的union_find数据结构。

猜你喜欢

转载自blog.csdn.net/lzj_1314/article/details/80506363