Kruskal算法(python实现)

class Graph:
      def __init__(self,maps,unconn=0):
            vnum=len(maps)
            for x in maps:
                  if len(x)!=vnum:
                        raise ValueError
            self._maps=[maps[i][:] for i in range(vnum)]
            self._unconn=unconn
            self._vnum=vnum


      def vertex_num(self):
            return self._vnum


      def invalide(self):
            return  x<0 or x>=self._vnum
                 


      def add_vertex(self):
            raise GraphError


      def add_edges(self,x,y,weight):
            if self.invalide(x) or self.invalide(y) or x==y or weight<0:
                  raise Grapherror
            self._maps[x][y]=self._maps[y][x]=weight


      def get_edges(self,x,y):
            if self.invalide(x) or self.invalide(y):
                  raise GraphError
            return self._maps[x][y]


      def out_edges(self,x):
            #if self.invalide(x):
                  #raise GraphError
            return self._out_edges(self._maps[x], self._unconn)
      @staticmethod
      def _out_edges(row, unconn):
            edges=[]
            for i in range(len(row)):
                  if row[i]!=unconn:
                        edges.append((i,row[i]))
            return edges


def Kruskal(graph):
      vnum=graph.vertex_num()
      resp=[i for i in range(vnum)]
      mst=[]
      edges=[]
      for x in range(vnum):
            for y,w in graph.out_edges(x):
                  edges.append((w,x,y))
      edges.sort()
      for w,x,y in edges:
            if resp[x]!=resp[y]:
                  mst.append(((x,y),w))
                  if len(mst)==vnum-1:
                        break
                  rep,orep=resp[x],resp[y]
                  for i in range(vnum):
                        if resp[i]==orep:
                              resp[i]=rep
      return mst


inf=float("inf")
graph=Graph([[inf,5,11,5,inf,inf,inf],
            [5,inf,inf,3,9,inf,7],
            [11,inf,inf,7,inf,6,inf],
            [5,3,7,inf,inf,inf,20],
            [inf,9,inf,inf,inf,inf,8],
            [inf,inf,6,inf,inf,inf,8],
            [inf,7,inf,20,8,8,inf]])


print(Kruskal(graph))

输出说明:((i,j),weight)表示i到j的路径 权重为weight

[((1, 3), 3), ((0, 1), 5), ((2, 5), 6), ((1, 6), 7), ((2, 3), 7), ((4, 6), 8)]












猜你喜欢

转载自blog.csdn.net/you_er_yuan_da_lao/article/details/80377566