๐น 6. Graphs
04. ํธ๋ฆฌ์ ๊ทธ๋ํ
[ ๊ทธ๋ํ ]
: ๋จ์ํ ๋ ธ๋์ ๊ทธ ๋ ธ๋๋ฅผ ์ฐ๊ฒฐํ๋ ๊ฐ์ ์ ํ๋๋ก ๋ชจ์ ๋์๊ฒ
โ ํธ๋ฆฌ๋ ๊ทธ๋ํ์ ํ ์ข ๋ฅ์ด๋ค. ์ฌ์ดํด์ด ์๋ ํ๋์ ์ฐ๊ฒฐ ๊ทธ๋ํ์ด๋ค.
- ๊ทธ๋ํ๋ ๋ฐฉํฅ์ฑ์ด ์๋ ๊ทธ๋ํ์ ์๋ ๊ทธ๋ํ๊ฐ ์๋ค.
- ๊ทธ๋ํ๋ ์ฌ๋ฌ ๊ฐ์ ๊ณ ๋ฆฝ๋ ๋ถ๋ถ ๊ทธ๋ํ๋ก ๊ตฌ์ฑ๋ ์ ์๋๋ฐ, ๋ชจ๋ ์ ์ ์ ๊ฐ์ ๊ฒฝ๋ก๊ฐ ์กด์ฌํ๋ ๊ทธ๋ํ๋ โ์ฐ๊ฒฐ ๊ทธ๋ํโ๋ผ๊ณ ๋ถ๋ฅธ๋ค.
- ๊ทธ๋ํ์๋ ์ฌ์ดํด์ด ์กด์ฌํ ์๋ ์๊ณ ์กด์ฌํ์ง ์์ ์๋ ์๋ค. ์ฌ์ดํด์ด ์๋ ๊ทธ๋ํ๋ โ๋น์ํ ๊ทธ๋ํโ๋ผ๊ณ ๋ถ๋ฅธ๋ค.
์ธ์ ๋ฆฌ์คํธ(adjacency list)
๋ชจ๋ ์ ์ (ํน์ ๋ ธ๋)๋ฅผ ์ธ์ ๋ฆฌ์คํธ์ ์ ์ฅํ๋ค.
โ ๋ฌด๋ฐฉํฅ ๊ทธ๋ํ์์๋ (a, b)๊ฐ์ ์ ๋ ๋ฒ ์ ์ฅํ๋ค. ํ ๋ฒ์ a ์ ์ ์ ์ธ์ ํ ๊ฐ์ ์ ์ ์ฅํ๊ณ ๋ค๋ฅธ ํ ๋ฒ์ b์ ์ธ์ ํ ๊ฐ์ ์ ์ ์ฅํ๋ค.
1
2
3
4
5
6
7
8
class Graph {
public Node[] nodes;
}
class Node {
public String name;
public Node[] children;
}
- ํธ๋ฆฌ : ํน์ ๋ ธ๋ ํ๋(๋ฃจํธ ๋ ธ๋)์์ ๋ค๋ฅธ ๋ชจ๋ ๋ ธ๋๋ก ์ ๊ทผ์ด ๊ฐ๋ฅ
- ๊ทธ๋ํ : ํธ๋ฆฌ์ ๋ฌ๋ฆฌ ํน์ ๋ ธ๋์์ ๋ค๋ฅธ ๋ชจ๋ ๋ ธ๋๋ก ์ ๊ทผ์ด ๋ถ๊ฐ๋ฅ โ Graph๋ผ๋ ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ค.
๊ทธ๋ํ๋ฅผ ์ํ ์ถ๊ฐ์ ์ธ ํด๋์ค๋ฅผ ๋ฐ๋ก ๊ตฌํํ ํ์ ์๋ค. ๋ฐฐ์ด(ํน์ ํด์ํ ์ด๋ธ)๊ณผ ๋ฐฐ์ด์ ๊ฐ ์ธ๋ฑ์ค๋ง๋ค ์กด์ฌํ๋ ๋ ๋ค๋ฅธ ๋ฆฌ์คํธ(๋ฐฐ์ด, ๋์ ๊ฐ๋ณ ํฌ๊ธฐ ๋ฐฐ์ด(arraylist), ์ฐ๊ฒฐ๋ฆฌ์คํธ(linked list) ๋ฑ)๋ฅผ ์ด์ฉํด ์ธ์ ๋ฆฌ์คํธ๋ฅผ ํํํ ์ ์๋ค.
1
2
3
4
5
6
7
0: 1
1: 2
2: 0, 3
3: 2
4: 6
5: 4
6: 5
์ธ์ ํ๋ ฌ(adjacency matrix)
: N*N boolean ํ๋ ฌ๋ก matrix[i][j]๊ฐ true๋ผ๋ฉด i์์ j๋ก์ ๊ฐ์ ์ด ์๋ค๋ ๋ป์ด๋ค.
๋ฌด๋ฐฉํฅ ๊ทธ๋ํ๋ ์ธ์ ํ๋ ฌ๋ก ํํํ๋ค๋ฉด ์ด ํ๋ ฌ์ ๋์นญํ๋ ฌ(symmetric matrix)์ด ๋๋ค.
์ธ์ ๋ฆฌ์คํธ๋ฅผ ์ฌ์ฉํ ๊ทธ๋ํ ์๊ณ ๋ฆฌ์ฆ(ex. bfs)์ ์ธ์ ํ๋ ฌ๋ก๋ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค. ํ์ง๋ง ์ธ์ ํ๋ ฌ์ ํจ์จ์ฑ์ด ๋จ์ด์ง๋ค.
โ ์ธ์ ๋ฆฌ์คํธ์์๋ ์ด๋ค ๋ ธ๋์ ์ธ์ ํ ๋ ธ๋๋ค์ ์ฝ๊ฒ ์ฐพ์ ์ ์์ง๋ง, ์ธ์ ํ๋ ฌ์์๋ ์ด๋ค ๋ ธ๋์ ์ธ์ ํ ๋ ธ๋๋ฅผ ์ฐพ๊ธฐ ์ํด์๋ ๋ชจ๋ ๋ ธ๋๋ฅผ ์ ๋ถ ์ํํด์ผ ์ ์ ์๋ค.
๊ทธ๋ํ ํ์
์ผ๋ฐ์ ์ผ๋ก ๊น์ด ์ฐ์ ํ์(depth-first search)๊ณผ ๋๋น ์ฐ์ ํ์(breadth-first search)์ด ์๋ค.
๊น์ด ์ฐ์ ํ์(DFS)
: ๋ฃจํธ ๋ ธ๋(ํน์ ๋ค๋ฅธ ์์์ ๋ ธ๋)์์ ์์ํด์ ๋ค์ ๋ถ๊ธฐ(branch)๋ก ๋์ด๊ฐ๊ธฐ ์ ์ ํด๋น ๋ถ๊ธฐ๋ฅผ ์๋ฒฝํ๊ฒ ํ์ํ๋ ๋ฐฉ๋ฒ
โ ๋ชจ๋ ๋ ธ๋๋ฅผ ๋ฐฉ๋ฌธํ๊ณ ์ ํ ๋
๋๋น ์ฐ์ ํ์(BFS)
: ๋ฃจํธ ๋ ธ๋(ํน์ ๋ค๋ฅธ ์์์ ๋ ธ๋)์์ ์์ํด์ ์ธ์ ํ ๋ ธ๋๋ฅผ ๋จผ์ ํ์ํ๋ ๋ฐฉ๋ฒ
โ ๋ ๋ ธ๋ ์ฌ์ด์ ์ต๋จ ๊ฒฝ๋ก ํน์ ์์์ ๊ฒฝ๋ก๋ฅผ ์ฐพ๊ณ ์ถ์ ๋
๊น์ด ์ฐ์ ํ์(DFS)
DFS๋ a ๋ ธ๋๋ฅผ ๋ฐฉ๋ฌธํ ๋ค a์ ์ธ์ ํ ๋ ธ๋๋ค์ ์ฐจ๋ก๋ก ์ํํ๋ค. a์ ์ด์ํ ๋ ธ๋ b๋ฅผ ๋ฐฉ๋ฌธํ๋ค๋ฉด, a์ ์ธ์ ํ ๋ ๋ค๋ฅธ ๋ ธ๋๋ฅผ ๋ฐฉ๋ฌธํ๊ธฐ ์ด์ ์ b์ ์ด์ ๋ ธ๋๋ค์ ์ ๋ถ ๋ฐฉ๋ฌธํด์ผ ํ๋ค.
โ b์ ๋ถ๊ธฐ๋ฅผ ์ ๋ถ ์๋ฒฝํ๊ฒ ํ์ํ ๋ค์์ผ a์ ๋ค๋ฅธ ์ด์ ๋ ธ๋๋ฅผ ๋ฐฉ๋ฌธํ ์ ์๋ค.
- DFS ์ข ๋ฅ : ์ ์ ์ํ๋ฅผ ํฌํจํ ๋ค๋ฅธ ํํ์ ํธ๋ฆฌ ์ํ
1
2
3
4
5
6
7
8
9
10
void search(Node root) {
if (root == null) return;
visit(root);
root.visited = true;
foreach (Node n in root.adjacent) {
if (n.visited == false) {
search(n);
}
}
}
๋๋น ์ฐ์ ํ์(BFS)
BFS๋ ์ฌ๊ท์ ์ผ๋ก ๋์ํ์ง ์๊ณ ํ(queue)๋ฅผ ์ฌ์ฉํ๋ค.
a ๋ ธ๋์์ ์์ํ๋ค๊ณ ํ์ ๋, BFS๋ a ๋ ธ๋์ ์ด์ ๋ ธ๋๋ฅผ ๋ชจ๋ ๋ฐฉ๋ฌธํ ๋ค์์ ์ด์์ ์ด์๋ค์ ๋ฐฉ๋ฌธํ๋ค.
โ a์์ ์์ํด์ ๊ฑฐ๋ฆฌ์ ๋ฐ๋ผ ๋จ๊ณ๋ณ๋ก ํ์ํ๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void search(Node root) {
Queue queue = new Queue();
root.marked = true;
queue.enqueue(root); // ํ์ ๋์ ์ถ๊ฐ
while (!queue.isEmpty()) {
Node r = queue.dequeue(); // ํ์ ์์์ ๋ฝ์๋
visit(r);
foreach (Node n in r.adjacent) {
if (n.marked == false) {
n.marked = true;
queue.enqueue(n);
}
}
}
}
์๋ฐฉํฅ ํ์(bidirectional search)
โ ์ถ๋ฐ์ง์ ๋์ฐฉ์ง ์ฌ์ด์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ์ฐพ์ ๋ ์ฌ์ฉ
์ถ๋ฐ์ง์ ๋์ฐฉ์ง ๋ ๋ ธ๋์์ ๋์์ ๋๋น ์ฐ์ ํ์์ ์ํํ ๋ค, ๋ ํ์ ์ง์ ์ด ์ถฉ๋ํ๋ ๊ฒฝ์ฐ์ ๊ฒฝ๋ก๋ฅผ ์ฐพ๋๋ค.
์๋ฐฉํฅ ํ์ ๋ฐฉ์์ด ์ ๋ ๋น ๋ฅผ๊น?
๋ชจ๋ ๋ ธ๋๊ฐ ์ ์ด๋ k๊ฐ์ ์ด์ ๋ ธ๋์ ์ฐ๊ฒฐ๋์ด ์๊ณ s์์ t๋ก์ ์ต๋จ ๊ฑฐ๋ฆฌ๊ฐ d๊ฐ ๋๋ ๊ทธ๋ํ๋ฅผ ์๊ฐํด๋ณด์.
๋๋น ์ฐ์ ํ์
์ ํต์ ์ธ ๋๋น ์ฐ์ ํ์์ ์ฌ์ฉํ๋ฉด ์ฒซ ๋จ๊ณ์์ k๊ฐ์ ๋ ธ๋๋ฅผ ํ์ํด์ผ ํ๋ค. ๋ค์ ๋จ๊ณ์์ k๊ฐ์ ๋ ธ๋๋ค ๋ํ ์ด์ํ k๊ฐ์ ๋ ธ๋๋ฅผ ํ์ํด์ผ ํ๋ฏ๋ก ์ด $k^2$๊ฐ์ ๋ ธ๋๋ฅผ ํ์ํด์ผ ํ๋ค.
โ ์ด๋ฅผ d๋ฒ ๋ฐ๋ณตํ๋ฉด ์ด $O(k^d)$๊ฐ์ ๋ ธ๋๋ฅผ ํ์ํด์ผ ํ๋ค.
์๋ฐฉํฅ ํ์
๋ ํ์ ์๊ณ ๋ฆฌ์ฆ์ด ๋๋ต d/2๋จ๊ณ(s์ t ์ฌ์ด์ ์ค๊ฐ ์ง์ )๊น์ง ํ์ํ ํ์ ์ถฉ๋ํ ๊ฒ์ด๋ค. ๋ฐ๋ผ์ s์ t ๊ฐ๊ฐ์์ ๋ฐฉ๋ฌธํ๊ฒ ๋ ๋ ธ๋์ ์๋ ๋๋ต $k^{d/2}$๊ฐ๊ฐ ๋ ๊ฒ์ด๋ค.
โ ๋ฐฉ๋ฌธํ๊ฒ ๋ ์ ์ฒด ๋ ธ๋๋ ๋๋ต $2*k^{d/2}$, $O(k^{d/2})$๊ฐ๊ฐ ๋๋ค.