python 최소 생 성 트 리 kruskal 과 prim 알고리즘 상세 설명

kruskal 알고리즘 기본 적 인 사고:먼저 가중치 에 따라 작은 것 에서 큰 것 으로 정렬 하고 가중치 가 가장 작은 한 변 을 선택 합 니 다.만약 에 이 변 의 두 노드 가 모두 다른 분량 이 라면 최소 생 성 트 리 에 가입 합 니 다.그렇지 않 으 면 다음 변 을 계산 하여 모든 변 을 옮 겨 다 닐 때 까지 합 니 다.
prim 알고리즘 기본 사고:모든 노드 는 두 개의 group 로 나 뉘 는데 하 나 는 이미 선택 한 selected 입 니 다.node(list 형식),하 나 는 candidatenode,우선 하나의 노드 를 선택 하여 selected 에 가입 합 니 다.node,그리고 머리 노드 를 옮 겨 다 니 며 selectednode,꼬리 노드 는 candidatenode 의 변,이 조건 에 맞 는 변 의 가중치 가 가장 작은 변 을 선택 하여 최소 생 성 트 리 에 가입 하고 선택 한 변 의 끝 노드 를 selected 에 추가 합 니 다.node,그리고 candidatenode 삭제.candidate 까지node 에 예비 노드 가 없습니다.(이 순환 조건 은 모든 노드 에 사 이 드 연결 이 있어 야 합 니 다.즉,사 이 드 수 는 노드 수-1 보다 크 고 순환 시작 전에 이 조건 을 추가 하여 판단 해 야 합 니 다.그렇지 않 으 면 노드 가 계속 candidate 에 있어 서 사 순환 을 초래 할 수 있 습 니 다)

#coding=utf-8
class Graph(object):
  def __init__(self, maps):
    self.maps = maps
    self.nodenum = self.get_nodenum()
    self.edgenum = self.get_edgenum()
 
  def get_nodenum(self):
    return len(self.maps)
 
  def get_edgenum(self):
    count = 0
    for i in range(self.nodenum):
      for j in range(i):
        if self.maps[i][j] > 0 and self.maps[i][j] < 9999:
          count += 1
    return count
 
  def kruskal(self):
    res = []
    if self.nodenum <= 0 or self.edgenum < self.nodenum-1:
      return res
    edge_list = []
    for i in range(self.nodenum):
      for j in range(i,self.nodenum):
        if self.maps[i][j] < 9999:
          edge_list.append([i, j, self.maps[i][j]])# [begin, end, weight]    
    edge_list.sort(key=lambda a:a[2])#         
    
    group = [[i] for i in range(self.nodenum)]
    for edge in edge_list:
      for i in range(len(group)):
        if edge[0] in group[i]:
          m = i
        if edge[1] in group[i]:
          n = i
      if m != n:
        res.append(edge)
        group[m] = group[m] + group[n]
        group[n] = []
    return res
 
  def prim(self):
    res = []
    if self.nodenum <= 0 or self.edgenum < self.nodenum-1:
      return res
    res = []
    seleted_node = [0]
    candidate_node = [i for i in range(1, self.nodenum)]
    
    while len(candidate_node) > 0:
      begin, end, minweight = 0, 0, 9999
      for i in seleted_node:
        for j in candidate_node:
          if self.maps[i][j] < minweight:
            minweight = self.maps[i][j]
            begin = i
            end = j
      res.append([begin, end, minweight])
      seleted_node.append(end)
      candidate_node.remove(end)
    return res
 
max_value = 9999
row0 = [0,7,max_value,max_value,max_value,5]
row1 = [7,0,9,max_value,3,max_value]
row2 = [max_value,9,0,6,max_value,max_value]
row3 = [max_value,max_value,6,0,8,10]
row4 = [max_value,3,max_value,8,0,4]
row5 = [5,max_value,max_value,10,4,0]
maps = [row0, row1, row2,row3, row4, row5]
graph = Graph(maps)
print('     
%s'%graph.maps) print(' %d, %d
'%(graph.nodenum, graph.edgenum)) print('------ kruskal ------') print(graph.kruskal()) print('------ prim ') print(graph.prim())
최초의 그림 은 다음 과 같다.

운행 결 과 는 다음 과 같다.

이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기