[์๊ณ ๋ฆฌ์ฆ] ๊ทธ๋ํ
์๋ณธ ๊ฒ์๊ธ: https://velog.io/@euisuk-chung/์๊ณ ๋ฆฌ์ฆ-๊ทธ๋ํ
์ค๋์ ์๊ณ ๋ฆฌ์ฆ/์๋ฃ๊ตฌ์กฐ๋ฅผ ๊ณต๋ถํ๋ฉด์ ํ์ ๋๋ ค์์ ๋จ๋ฉฐ ์ ๋๋ก ๊ณต๋ถํ์ง ๋ชปํ๋ ๊ทธ๋ํ์ ๋ํด ๊ณต๋ถ๋ฅผ ํ๋ฉฐ ์ ๋ฆฌํด๋ณด์์ต๋๋ค. ๊ณต๋ถํ๋ฉฐ ์์ฑํ ๊ธ์ด๋ฏ๋ก ๋ฐ๋ง์ด์ด๋ ์ํด๋ถํ๋๋ฆฝ๋๋ค.
๊ทธ๋ํ
-
๊ทธ๋ํ๋?
๊ทธ๋ํ
๋ ๊ฐ์ฅ ์ผ๋ฐํ๋ ์๋ฃ๊ตฌ์กฐ๋ก, ์ฐ๊ฒฐ๋ ๊ฐ์ฒด๋ค ์ฌ์ด์ ๊ด๊ณ๋ฅผ ์ ํํํจ.
๊ทธ๋ํ ์ด๋ก
- ์ผ๋ฐ์ ์ผ๋ก ๊ทธ๋ํ์ ๊ด๋ จ๋ ๋ค์ํ ๋ฌธ์ ๋ฅผ ์ฐ๊ตฌํ๋ ํ๋ฌธ ๋ถ์ผ๋ฅผ
๊ทธ๋ํ ์ด๋ก
์ด๋ผ๊ณ ํจ. - ๊ทธ๋ํ๋ ์ํ์ ์ค์ผ๋ฌ์ ์ํด ์ฒ์ ๋ง๋ค์ด์ก์ผ๋ฉฐ,
๋ชจ๋ ๋ค๋ฆฌ๋ฅผ ํ๋ฒ๋ง ๊ฑด๋์ ์ถ๋ฐํ๋ ์ฅ์๋ก ๋์์ฌ ์ ์๋๊ฐ?
๋ผ๋ ๋ฌธ์ ๊ฐ ๋ต์ด ์กด์ฌํ์ง ์๋๋ค๋ ๊ฒ์ ๊ทธ๋ํ ์ด๋ก ์ ํตํด ์ฆ๋ช ํจ. - ์ผ๋ฐ์ ์ผ๋ก
๊ทธ๋ํ
๋ ์๋ ๋๊ฐ์ง(์ ์ , ๊ฐ์ )์ ์งํฉ์ผ๋ก ๊ตฌ์ฑ๋จ- ํ๊ธฐ : G=(V,E)G = (V, E)G=(V,E)
- ์ ์ (Node) : ์์น(๊ฐ์ฒด) V(G)V(G)V(G)
- ๊ฐ์ (Edge) : ์์น(๊ฐ์ฒด) ๊ฐ์ ๊ด๊ณ E(G)E(G)E(G)
๊ทธ๋ํ ์ข ๋ฅ
-
๋ฌด๋ฐฉํฅ ๊ทธ๋ํ (undirected graph)
- ๊ฐ์ ์ ๋ฐฉํฅ์ด ํ์๋์ง ์๋ ๊ทธ๋ํ
-
๋ฐฉํฅ ๊ทธ๋ํ (directed graph)
- ๊ฐ์ ์ ๋ฐฉํฅ์ฑ์ด ์กด์ฌํ๋ ๊ทธ๋ํ
-
๊ฐ์ค์น ๊ทธ๋ํ (weighted graph)
- ๊ฐ์ ์ ๋น์ฉ์ด๋ ๊ฐ์ค์น๊ฐ ํ ๋น๋ ๊ทธ๋ํ
-
๋ถ๋ถ ๊ทธ๋ํ (subgraph)
- ๊ทธ๋ํ๋ฅผ ๊ตฌ์ฑํ๋ ์ ์ ์ ์งํฉ๊ณผ ๊ฐ์ ์ ์งํฉ์ ๋ถ๋ถ ์งํฉ์ผ๋ก ์ด๋ฃจ์ด์ง ๊ทธ๋ํ
๊ทธ๋ํ ์ฉ์ด ์ ๋ฆฌ
- ์ ์ ์ ์ฐจ์ (degree)
- ์ ์ ์ ์ฐ๊ฒฐ๋ ๊ฐ์ ์ ์
- ์ธ์ ์ ์ (adjacent vertex)
- ๊ฐ์ ์ ์ํด ์ง์ ์ฐ๊ฒฐ๋ ์ ์
- ๊ฒฝ๋ก (path)
- ๊ฐ์ ์ ๋ฐ๋ผ ๊ฐ ์ ์๋ ๊ธธ, ํ ์ ์ ์์ ์์ํด์ ๋ค๋ฅธ ํ ์ ์ ์ผ๋ก ์ด๋ํ๋ ๊ฒฝ๋ก
- ๋จ์ ๊ฒฝ๋ก (simple path)
- ๊ฒฝ๋ก ์ค์ ๋ฐ๋ณต๋๋ ๊ฐ์ ์ด ์๋ ๊ฒฝ๋ก
- ์ธ์ดํด (cycle)
- ๋จ์ ๊ฒฝ๋ก์ ์์ ์ ์ ๊ณผ ์ข ๋ฃ ์ ์ ์ด ๋์ผํ์ฌ ํด๋น ์ ์ ์ผ๋ก ๋ค์ ๋์์ค๋ ๊ฒฝ๋ก
- ํธ๋ฆฌ (tree)
- ์ฌ์ดํด์ ๊ฐ์ง์ง ์๋ ์ฐ๊ฒฐ ๊ทธ๋ํ
- ์ฐ๊ฒฐ ๊ทธ๋ํ (connected graph)
- ๋ชจ๋ ์ ์ ๋ค ์ฌ์ด์ ๊ฒฝ๋ก๊ฐ ์กด์ฌํ๋ ๊ทธ๋ํ
- ์์ ๊ทธ๋ํ (complete graph)
- ๋ชจ๋ ์ ์ ๊ฐ์ ๊ฐ์ ์ด ์กด์ฌํ๋ ๊ทธ๋ํ
-
๊ทธ๋ํ์ ํํ
์ธ์ ํ๋ ฌ์ ์ด์ฉํ ํํ
- ๊ทธ๋ํ์์ ์ ์ ๋ค์ ์ฐ๊ฒฐ๊ด๊ณ๋ฅผ ํํํ๋ ๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ผ๋ก,
์ธ์ ํ๋ ฌ(Adjacency matrix)
์ ์ฌ์ฉํ์ฌ ํํํจ -
์ธ์ ํ๋ ฌ์ ์๋์ ๊ฐ์ ํน์ง๋ค์ด ์กด์ฌํ๋ค.
-
๋ ธ๋์ ๋ฒํธ๋ฅผ ์ธ๋ฑ์ค
-
๊ฐ์ ์ ์กด์ฌ์ ๋ฌด(๋๋ ๊ฐ์ค์น)๊ฐ ์ธ๋ฑ์ค์ ๊ฐ
-
๊ฐ์ ์ด ์๋ ๋ ธ๋์ ๋ํ ์ ๋ณด๋ ์ ์ง๋ฅผ ํด์ผํ๊ธฐ ๋๋ฌธ์ ๊ณต๊ฐ๋ณต์ก๋๊ฐ ์ข์ง ์์
-
์ธ์ ๋ฆฌ์คํธ๋ฅผ ์ด์ฉํ ํํ
- ๊ทธ๋ํ์ ๊ฐ ์ ์ ๊ณผ ์ฐ๊ฒฐ๋ ์ธ์ ์ ์ ๋ค์ ๊ฐ๊ฐ์ ๋ฆฌ์คํธ๋ก ํํํ ์ ์๋๋ฐ ์ด๋ฌํ ๋ฆฌ์คํธ๋ฅผ
์ธ์ ๋ฆฌ์คํธ(Adjacency list)
๋ผ๊ณ ํจ - ๊ฐ ์ ์ ์ ์ธ์ ๋ฆฌ์คํธ๋ฅผ ์ด์ฉํด ์์ ๊ณผ ๊ฐ์ ์ผ๋ก ์ฐ๊ฒฐ๋ ์ธ์ ์ ์ ๋ค์ ๊ด๋ฆฌํจ
-
์ธ์ ๋ฆฌ์คํธ๋ ์๋์ ๊ฐ์ ํน์ง๋ค์ด ์กด์ฌํ๋ค.
-
ํ์ด์ฌ์์๋ ๋์ ๋๋ฆฌ๋ฅผ ์ฃผ๋ก ์ด์ฉํจ
-
์ฐ๊ฒฐ๋ ์ ์ ์ ๋ํ ์ ๋ณด๋ง ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์, ๊ณต๊ฐ๋ณต์ก๋๊ฐ ์ธ์ ํ๋ ฌ์ ๋นํด์ ์ข์
-
๊ฐ์ค์น ์ ๋ณด๋ ๋ฐ์์ด ๋์ง ์์
-
-
๊ทธ๋ํ์ ํ์
๊ทธ๋ํ ํ์
์ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ์ฐ์ฐ์ผ๋ก ํ๋์ ์ ์ ์์ ์์ํ์ฌ ๋ชจ๋ ์ ์ ๋ค์ ํ๋ฒ์ฉ ๋ฐฉ๋ฌธํ๋ ์์ ์ ์๋ฏธํจ-
์ค์ ๋ก ๋ง์ ๊ทธ๋ํ ๋ฌธ์ ๋ค์ด ๋จ์ํ ์ ์ ๋ค์ ํ์ํ๋ ๊ฒ๋ง์ผ๋ก ํด๊ฒฐ๋จ
- Ex) ๋ฏธ๋ก ์ฐพ๊ธฐ ๋ฑ
- ๊ธฐ๋ณธ์ ์ธ ํ์ ์๊ณ ๋ฆฌ์ฆ์๋
๊น์ด ์ฐ์ ํ์
๊ณผ๋๋น ์ฐ์ ํ์
์ ๋๊ฐ์ง๊ฐ ์กด์ฌํจ
๐ ์ฌ๊ธฐ์ ์ ๊น!
ํ์ด์ฌ์ collections๋ผ๋ ๋ชจ๋์์ defaultdict, Counter, deque ๋ฑ์ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋๋ฐ, ์ด์ค
deque
์defaultdict
๋ฅผ ์ฌ์ฉํ๋ฉด ์ ์ฉํ๊ฒ ๊ฐ๊ฐ BFS์ DFS๋ฅผ ์ ์ํ ์ ์๋ค!
- deque : ์์ชฝ ๋์์ ๋น ๋ฅด๊ฒ ์ถ๊ฐ์ ์ญ์ ๋ฅผ ํ ์ ์๋ ๋ฆฌ์คํธ๋ฅ ์ปจํ ์ด๋
- Counter : ํด์ ๊ฐ๋ฅํ ๊ฐ์ฒด๋ฅผ ์ธ๋ ๋ฐ ์ฌ์ฉํ๋ ๋์ ๋๋ฆฌ ์๋ธ ํด๋์ค
- OrderedDict : ํญ๋ชฉ์ด ์ถ๊ฐ๋ ์์๋ฅผ ๊ธฐ์ตํ๋ ๋์ ๋๋ฆฌ ์๋ธ ํด๋์ค
- defaultdict : ๋๋ฝ๋ ๊ฐ์ ์ ๊ณตํ๊ธฐ ์ํด ํฉํ ๋ฆฌ ํจ์๋ฅผ ํธ์ถํ๋ ๋์ ๋๋ฆฌ ์๋ธ ํด๋์ค
1
2
3
4
5
6
7
8
from collections import deque
from collections import defaultdict
# defaultdict๋ฅผ ์ด์ฉํ๋ ๊ฒฝ์ฐ
a = defaultdict(list) # listํ์์ผ๋ก ์ ์ฅํด์ฃผ๊ฒ ๋ค๋ ๋ป
# ํ๋ฅผ ์ด์ฉํ๋ ๊ฒฝ์ฐ
q = deque()
๊น์ด ์ฐ์ ํ์ (DFS)
- ๊น์ด ์ฐ์ ํ์ (depth first search, DFS)์
์คํ
๋๋์ฌ๊ท
์ ์ด์ฉํ ๋ฏธ๋ก ํ์๊ณผ ์ ์ฌํจ - ๋ฏธ๋ก๋ฅผ ํ์ํ ๋ ํ ๋ฐฉํฅ์ผ๋ก ๊ฐ ์ ์๋ ๋ฐ๊น์ง ๊ณ์ ์งํํ๋ค๊ฐ, ๋ ์ด์ ์งํ์ด ๋ถ๊ฐ๋ฅํ๋ฉด ๋ค์ ๊ฐ๊น์ด ๊ฐ๋ฆผ๊ธธ๋ก ๋์์ ๋ค๋ฅธ ๋ฐฉํฅ์ผ๋ก ๋ค์ ํ์ํ๋ ๋ฐฉ๋ฒ
-
DFS ๊ณผ์ (์ถ์ฒ : https://gmlwjd9405.github.io/2018/08/14/algorithm-dfs.html)
์ฐธ๊ณ
- v : ์์ ๋ ธ๋
- n : ๋ ธ๋(node)์ ๊ฐ์
- m : ๊ฐ์ (edge)์ ๊ฐ์
- arr : ์ธ์ ํ๋ ฌ
- a : ์ธ์ ๋ฆฌ์คํธ
์ธ์ ํ๋ ฌ๊ณผ ์ฌ๊ท๋ฅผ ์ด์ฉํ DFS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# ์ด์ ๋ฐฉ๋ฌธ ์ฌ๋ถ ํ์ธ
check = [False] * (n+1)
# DFS ํจ์ ์ ์
def dfs(v):
check[v] = True # v๋
ธ๋๋ฅผ ๋ฐฉ๋ฌธํจ
# ๋ฐฉ๋ฌธ ๊ฐ๋ฅํ ๋ชจ๋ ๋
ธ๋๋ฅผ ์ ๋ถ ์ํ
for i in range(1, n+1):
# i ์กฐ๊ฑด : v์ ์ธ์ ํด์ผํจ + ์ด์ ์ ๋ฐฉ๋ฌธํ ์ ์ด ์์ด์ผ ํจ
if arr[v][i] == 1 and check[i] == False:
dfs(i)
# ํจ์ ์คํ
dfs(v)
์ธ์ ๋ฆฌ์คํธ์ ์ฌ๊ท๋ฅผ ์ด์ฉํ DFS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# ์ด์ ์ ๋ฐฉ๋ฌธํ์ ์ด ์์๋์ง ์ฒดํฌ
check = [False] * (n+1)
# DFS ํจ์ ์ ์
def dfs(v):
check[v] = True # v๋
ธ๋๋ฅผ ๋ฐฉ๋ฌธํจ
# ๋ฐฉ๋ฌธ ๊ฐ๋ฅํ ๋ชจ๋ ๋
ธ๋๋ฅผ ์ ๋ถ ์ํ
for i in a[v]:
# ์ธ์ ๋ฆฌ์คํธ๋ ์ธ์ ํ ์ ์ ์ ๋ํ ์ ๋ณด๋ง ๋ค์ด์๋ค.
# ๋ฐ๋ผ์, ์ด์ ์ ๋ฐฉ๋ฌธํ ์ ์ด ์์๋์ง๋ง ํ์ธํ๋ฉด ๋๋ค.
if check[i] == False:
dfs(i)
# ํจ์ ์คํ
dfs(v)
์ธ์ ํ๋ ฌ๊ณผ ์คํ์ ์ด์ฉํ DFS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# ์ด์ ๋ฐฉ๋ฌธ ์ฌ๋ถ ํ์ธ
check = [False] * (n+1)
stack = deque()
def dfs(start):
check[start] = True
stack.append(start)
# ์คํ์ด ๋น์ด์์ผ๋ฉด ์ข
๋ฃ
while stack:
v = stack.pop()
print(v)
for i in range(n, -1, -1):
if arr[v][i] == 1 and check[i] == False:
check[i] = True
stack.append(i)
dfs(v)
์ธ์ ๋ฆฌ์คํธ์ ์คํ์ ์ด์ฉํ DFS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# ์ด์ ์ ๋ฐฉ๋ฌธํ์ ์ด ์์๋์ง ์ฒดํฌ
check = [False] * (n+1)
stack = deque()
def dfs(start):
check[start] = True
stack.append(start)
# ์คํ์ด ๋น์ด์์ผ๋ฉด ์ข
๋ฃ
while stack:
v = stack.pop()
print(v)
for i in a[v]:
if check[i] == False:
check[i] = True
stack.append(i)
dfs(v)
๋๋น ์ฐ์ ํ์ (BFS)
- ๋๋น ์ฐ์ ํ์ (breadth first search, BFS)์ ์์ ์ ์ ์ผ๋ก๋ถํฐ ๊ฐ๊น์ด ์ ์ ์ ๋จผ์ ๋ฐฉ๋ฌธํ๊ณ , ๋ฉ๋ฆฌ ๋จ์ด์ ธ ์๋ ์ ์ ์๋ ๋์ค์ ๋ฐฉ๋ฌธํ๋ ์ํ ๋ฐฉ๋ฒ
- ๋๋น ์ด์ ํ์์ ์ํด์๋ ๊ฐ๊น์ด ๊ฑฐ๋ฆฌ์ ์๋ ์ ์ ๋ค์ ์ฐจ๋ก๋ก ์ ์ฅํ๊ณ , ๋ค์ด๊ฐ ์์๋๋ก ๊บผ๋ด๋ ๋ฐฉ์์ผ๋ก ์งํ๋๋ ๋ฐ ์ด๋ฅผ ์ํด ํ(Queue)๋ฅผ ์ฌ์ฉํจ.
- ํ๋ฅผ ์ด์ฉํด์ ํ์ฌ ๋ ธ๋์์ ๊ฐ ์ ์๋ ๋ชจ๋ ๋ ธ๋๋ฅผ ํ์ ๋ฃ๋ ๋ฐฉ์ (ํ์ ๋ค์ด๊ฐ๋ฉด, ๋ฐฉ๋ฌธํ ๊ฒ์ผ๋ก ๊ฐ์ฃผํจ)
- ๋ค์๋งํด, ์ ์ ๋ค์ด ๋ฐฉ๋ฌธ๋ ๋๋ง๋ค ํ์ ์ธ์ ์ ์ ์ ์ฝ์ ํ๊ณ , ๋ ์ด์ ๋ฐฉ๋ฌธํ ์ธ์ ์ ์ ์ด ์๋ ๊ฒฝ์ฐ ํ์ ๋งจ ์์ ์ ์ ์ ๊บผ๋ด ๊ทธ ์ ์ ๊ณผ ์ธ์ ํ ์ ์ ๋ค์ ์ฐจ๋ก๋๋ก ๋ฐฉ๋ฌธํจ
-
BFS ๊ณผ์ (์ถ์ฒ : https://gmlwjd9405.github.io/2018/08/15/algorithm-bfs.html)
์ฐธ๊ณ
- start : ์์ ๋ ธ๋
- n : ๋ ธ๋(node)์ ๊ฐ์
- m : ๊ฐ์ (edge)์ ๊ฐ์
- arr : ์ธ์ ํ๋ ฌ
- a : ์ธ์ ๋ฆฌ์คํธ
์ธ์ ํ๋ ฌ๊ณผ ํ๋ฅผ ์ด์ฉํ BFS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# ์ด์ ์ ๋ฐฉ๋ฌธํ์ ์ด ์์๋์ง ์ฒดํฌ
check = [False] * (n+1)
# ํ ์ ์ธ
q = deque()
# BFS์ ์
def bfs(v):
# ๋ฐฉ๋ฌธ ์ฒดํฌ
check[v] = True
# ํ์ ์ถ๊ฐ
q.append(v)
# ํ์ ๋ ์ด์ ๋ฐฉ๋ฌธํ ๋
ธ๋๊ฐ ์์ผ๋ฉด ์ข
๋ฃ
while q:
# FIFO
pop = q.popleft()
# ๋ฐฉ๋ฌธ ๊ฐ๋ฅํ ๋ชจ๋ ๋
ธ๋๋ฅผ ์ ๋ถ ์ํ
for i in range(1, n+1):
# i ์กฐ๊ฑด : pop๊ณผ ์ธ์ ํด์ผํจ + ์ด์ ์ ๋ฐฉ๋ฌธํ ์ ์ด ์์ด์ผ ํจ
if arr[pop][i] == 1 and check[i] == False:
check[i] = True
q.append(i)
# ํจ์ ์คํ
bfs(v)
์ธ์ ๋ฆฌ์คํธ์ ํ๋ฅผ ์ด์ฉํ BFS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# ์ด์ ์ ๋ฐฉ๋ฌธํ์ ์ด ์์๋์ง ์ฒดํฌ
check = [False] * (n+1)
# ํ ์ ์ธ
q = deque()
# BFS์ ์
def bfs(v):
# ๋ฐฉ๋ฌธ ์ฒดํฌ
check[v] = True
# ํ์ ์ถ๊ฐ
q.append(v)
# ํ์ ๋ ์ด์ ๋ฐฉ๋ฌธํ ๋
ธ๋๊ฐ ์์ผ๋ฉด ์ข
๋ฃ
while q:
# FIFO
pop = q.popleft()
# ์ธ์ ๋ฆฌ์คํธ๋ ์ธ์ ํ ์ ์ ์ ๋ํ ์ ๋ณด๋ง ๋ค์ด์๋ค.
# ๋ฐ๋ผ์, ์ด์ ์ ๋ฐฉ๋ฌธํ ์ ์ด ์์๋์ง๋ง ํ์ธํ๋ฉด ๋๋ค.
for i in a[v]:
if check[i] == False:
check[i] = True
q.append(i)
# ํจ์ ์คํ
bfs(v)
๊ธด ๊ธ ์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค ^~^