그래프
2021, Mar 23
그래프
-
다대다 관계로 표현할 수 있다
-
트리는 그래프의 특별한 형태 (1:N 관계)
- 그래프는 정점들의 집합과 이들을 연결하는 간선들의 집합으로 구성된 자료 구조
- 정점: 그래프의 구성요소로 하나의 연결점
-
간선: 두 정점에 연결된 간선의 수
- v개의 정점을 가지는 그래프는 최대 v*(v-1)/2 간선 가능 (무향그래프인경우) v*(v-1) 간선 가능 (유향그래프 가능)
-
인접 (Adjacency) : 두 개의 정점에 간선이 존재하면 서로 인접해 있다
- 연결되어 있다, 관계가 있다 ( = 다 같은 말)
-
경로 : 어떤 정점(A)에서 시작하며 다른 정점(B)로 끝나는 순회로 두 정점 사이를 잇는 간선들을 순서대로 나열한 것
- 단순 경로 : 경로 중 한 정점을 최대 한 번만 지나는 경로
- 순환 경로 : 단순 경로가 아닌 경우
- 경로의 시작점과 끝점이 같음
- 경로에서 어떤 정점을 2번이상 거치는 경우
그래프의 종류
- 무향그래프(양방향관계) vs 유향그래프(단방향관계)
- 가중치그래프 : 관계의 정도를 수치로 표현한 그래프
- 사이클 없는 방향 그래프 (DAG, Directed Acyclic Graph)
- 완전 그래프 : 정점들에 대해 가능한 모든 간선들을 가진 그래프 ( v*v-1)
- 트리는 싸이클이 없는 무향 연결 그래프이다
- 두 노드 사이에는 유일한 경로가 존재한다
- 각 노드는 최대 하나의 부모 노드가 존재할 수 있다
- 각 노드는 자식 노드가 없거나 하나 이상이 존재할 수 있다.
그래프 표현의 방법
-
인접 행렬 (정점중심) : v*v 크기의 2차원 배열을 이용해서 간선 정보 저장
-
단점
- 희소 그래프 : 그래프 정점은 상대적으로 많고 정점은 그에 비해 적다 ; 공간낭비가 발생한다 ; 탐색을 할 때도 비효율적이다 ;
- 밀집 그래프 : 정점과 그에 따른 간선의 개수가 비례해서 많다 (= 완전그래프) ; 자기 자신만 빼고 다 채워져있다 ; 어쩔 수 없이 다 탐색을 해야 하므로 공간적인 측면에서 크기상 배열을 만들 수 있는지만 검사한다
-
-
인접 리스트 (정점중심) : 각 정점마다 다른 정점으로 나가는 간선의 정보를 목록으로 저장
- 희소 그래프의 단점을 해결 => 공간, 시간 복잡도가 인접행렬보다 훨씬 효율적
- 하나의 정점에 대한 인접 정점들을 각각 노드로 하는 연결 리스트로 저장 (연결 리스트도 가능)
- ⭐**포인터의 역할일 뿐이지 이어져있다고 연결된게 아니다 **⭐
- 노드들의 순서는 상관이 없다
- 정점개수 만큼 연결리스트를 가지고 있고 , 연결리스트 안에 head만 갖고 있다
- ArrayList로 할 경우 안에 ArrayList안에 ArrayList[] 가 있다
- 하지만 LinkedList는 head노드만 있으면 되므로 ArrayList보다 성능 더 좋다
-
간선 리스트 (간선중심) : 간선(시작 정점, 끝 정점)의 정보를 객체로 표현하여 리스트에 저장
- N개의 간선 / [from , to] / 가중치
- class Edge{}를 만들어서 구현
그래프 탐색
- BFS
- 트리는 싸이클을 갖고 있지 않는 무향 그래프이기 때문에 visited[] 를 쓰지 않았다
- 그래프는 다대다 관계이기 때문에 한 번만 탐색해야하므로 visited[] 가 필요하다
- while( isEmpty() ){ size = que.size(); while ( size>0 ) { } }
- 위 방법을 써서 같은 level에 있는 값만 빼오는 BFS코드를 짤 수 있다
- DFS
서로소 집합
- 서로소 또는 상호 배타 집합들은 서로 중복 포함된 원소가 없는 집합들이다 => 교집합이 없다
- 대표자 : 집합에 속한 하나의 특정 멤버를 통해 각 집합들을 구분한다
- 서로소 집합을 표현하는 방법
- 연결 리스트
- 트리
- 서로소 집합 연산
- Make-Set() :: 단위집합 (크기가 1인집합) 을 만든다; 최초로 한번만 실행한다
- Find-Set(x) :: x가 속한 집합을 찾는다
- Union(x,y) :: x와 y의 집합을 합친다
- 문제점
- 계속 아래로 합쳐질 수가 있다 , Depth가 깊어진다
- 해결방법
- Rank를 이용한 Union
- 대표자의 rank를 비교해서 높은 대표자 집합에 낮은 대표자의 집합을 추가하여 depth를 깊어지지 않게 한다
- Path compression (패스압축)
- return parents[a]=findSet(parents[a])
- 대표자들끼리 그룹을 합치면 pass compression이 안이루어진다
- 구성원이 대표자를 찾으러 가는 과정에서는 pass compression이 이뤄진다
- 그래서 rank 관리를 하면서 Depth가 깊어지는 문제를 방지한다
- Rank를 이용한 Union
최소신장트리 (MST)
-
그래프에서 최소 비용 문제
- 모든 정점을 연결하는 간선들의 가중치의 합이 최소가 되는 트리
- 두 정점 사이의 최소 비용의 경로 찾기
-
최소 신장 트리 (Minimum Spanning Tree)
- 무향 가중치 그래프에서 신장 트리를 구성하는 간선들의 가중치의 합이 최소인 신장 트리
- 크루스칼 알고리즘 ( 간선중심 )
- 간선을 하나씩 선택해서 MST를 찾는 알고리즘
- 최초, 모든 간선을 가중치에 따라 오름차순으로 정렬
- 가중치가 가장 낮은 간선부터 선택하면서 트리를 증가시킨다
- 사이클이 존재하면 다음으로 가중치가 낮은 간선 선택
- 의미 있는 n-1개의 간선이 선택될 때까지 2를 반복
- unoin-find 알고리즘으로 간선을 쓸지 말지(사이클)을 검사한다
- 프림 알고리즘 ( 정점중심 )
- 이미 그룹이 된 친구들은 안보기 때문에 사이클이 발생하지 않는다
- N개의 정점을 모두 고립되지 않도록 연결, 가중치의 합 “최소”
최단경로 알고리즘
- 간선의 가중치가 있는 그래프에서 두 정점 사이의 경로들 중에 가선의 가중치의 합이 최소인 경로
- 하나의 시작 정점에서 끝 정점까지의 최단 경로 (인접정렬, 인접리스트 사용)
- 다익스트라 알고리즘 => 음의 가중치를 허용하지 않음
- MST의 프림 알고리즘과 유사하다
- 벨만 포드 알고리즘 => 음의 가중치 허용
- 다익스트라 알고리즘 => 음의 가중치를 허용하지 않음
- 모든 정점들에 대한 최단 경로
- 플로이드-워샬 알고리즘 (DP)