Kruskal Algorithm(크루스칼 알고리즘)

2021. 7. 21. 15:01·Algorithm

크루스칼 알고리즘이란? 

최소 신장 트리를 구하기 위한 알고리즘이다. 크루스칼 알고리즘은 그리디 알고리즘의 일종이다. 즉, 그래프의 간선을 오름차순으로 정렬한 후, 최소 비용의 간선을 선택한다. 

 

최소 신장 트리

모든 정점을 포함하고 사이클이 없는 연결 선을 그렸을 때, 가중치의 합이 최소가 되는 그래프

 

Kruskal 알고리즘 동작

 

1. 그래프 간선들을 가중치의 오름차순으로 정렬한다. 
2. 정렬된 간선 리스트에서 사이클이 생성되지 않는 간선을 순서대로 선택한다.
    2.1. 가장 작은 가중치를 먼저 선택한다.
    2.2. 사이클을 형성하는 간선은 제외한다. 
3. 해당 간선을 현재의 MST(Minimum Spanning Tree 최소 신장 트리)에 추가한다. 

 

사이클 생성 여부를 확인하는 방법

추가하고자 하는 간선의 양끝 정점이 같은 집합에 속해 있는지 먼저 검사해야 한다. 검사를 위해서 'union-find' 알고리즘을 이용한다.

 

union-find 알고리즘

union-find란 Disjoint Set을 표현할 때 사용하는 알고리즘이다. 집합을 구현하는데 비트 벡터, 배열, 연결 리스트를 이용할 수 있으나 그 중 가장 효율적인 트리 구조를 이용하여 구현한다. 아래의 3가지 연산을 이용하여 Disjoint Set을 표한한다. 

make-set(x) 
x를 유일한 원소로 하는 새로운 집합을 만든다.
union(x,y) 
x가 속한 집합과 y가 속한 집합을 합친다. 
find(x) 
x가 속한 집합의 대표값(루트  노드 값)을 반환한다. 즉, x가 어떤 집합에 속해 있는지 찾는 연산이다.

 

예제

큰 수 만들기(프로그래머스) 

#전형적인 크루스칼 알고리즘 문제였다. 크루스칼 알고리즘은 가장 적은 비용으로 모든 노드를 연결하기 위해 사용하는 알고리즘이다. 다시 말해 최소 신장 트리를 만들기 위한 알고리즘이다.
#find와 union을 통해 부모노드를 찾고 연결시킨다. 부모노드가 서로 같으면 사이클이 생성되므로 union하지 않는다. 

def solution(n, costs):
    answer = 0

    #parent set
    parent=[k for k in range(n)]
    print(parent)
    #costs sort
    costs.sort(key=lambda x: x[2])

    #find 메소드
    def find(v): 
        if parent[v]==v: 
            return v
        parent[v]=find(parent[v]) #경로 압축
        return parent[v]
      
            
    #union 메소드
    def union(v1,v2): 
        parent[find(v2)]=parent[find(v1)]

    for cost in costs:
        #부모가 같으면 사이클 생성을 의미하므로, 부모가 다르면 union해서 parent을 갱신한다(노드 간 연결을 의미한다).
        if find(cost[0])!= find(cost[1]): 
            union(cost[0], cost[1])
            answer+=cost[2]


    
    print(answer)
    return answer

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

 

'Algorithm' 카테고리의 다른 글

Quick Sort(퀵 정렬)  (0) 2022.03.11
다익스트라(Dijkstra)  (0) 2021.06.20
'Algorithm' 카테고리의 다른 글
  • Quick Sort(퀵 정렬)
  • 다익스트라(Dijkstra)
사랑우주인
사랑우주인
  • 사랑우주인
    lovelyAlien
    사랑우주인
  • 전체
    오늘
    어제
  • 글쓰기
    관리
    • 분류 전체보기 (209)
      • Programming (4)
        • Spring (28)
        • Java (46)
        • JPA (2)
        • 디자인 패턴 (5)
        • 개발&아키텍처 (0)
      • Network (14)
      • OS (19)
      • Database (1)
      • Kubernetes (0)
      • Kafka (2)
      • Algorithm (49)
        • BaekJoon (1)
        • Programmers (19)
        • Algorithm (5)
        • Socar (2)
        • LeetCode (19)
      • Interview (2)
      • Issues (2)
      • DotJoin (1)
      • Git (4)
      • 독서 (3)
      • 끄적끄적 (1)
      • 외부활동 (26)
        • 항해플러스 (2)
        • JSCODE 네트워크 (19)
        • JSCODE 자바 (5)
      • SQL (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • GitHub
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    LinkedList
    BFS
    운영체제
    트랜잭션
    @JsonProperty
    OS
    rotting oranges
    Climbing Stairs
    socar
    디자인 패턴
    clone graph
    @JsonNaming
    준영속 엔티티
    Thread
    runner 기법
    AuthenticationSuccessHandler
    pacific atlantic water flow
    JSCode
    algorithm
    제네릭
    추상화 클래스
    RR
    Generic
    Reorder List
    Process
    fcfs
    minimum number of arrows to burst balloons
    wildcards
    lower bounded wildcards
    Oauth2
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.1
사랑우주인
Kruskal Algorithm(크루스칼 알고리즘)
상단으로

티스토리툴바