电子科技大学通信网理论基础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[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数据结构。