Post

๐Ÿน 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);
            }
        }
    }
}

โ†’ ์ถœ๋ฐœ์ง€์™€ ๋„์ฐฉ์ง€ ์‚ฌ์ด์— ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ฐพ์„ ๋•Œ ์‚ฌ์šฉ

์ถœ๋ฐœ์ง€์™€ ๋„์ฐฉ์ง€ ๋‘ ๋…ธ๋“œ์—์„œ ๋™์‹œ์— ๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰์„ ์ˆ˜ํ–‰ํ•œ ๋’ค, ๋‘ ํƒ์ƒ‰ ์ง€์ ์ด ์ถฉ๋Œํ•˜๋Š” ๊ฒฝ์šฐ์— ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š”๋‹ค.

์–‘๋ฐฉํ–ฅ ํƒ์ƒ‰ ๋ฐฉ์‹์ด ์™œ ๋” ๋น ๋ฅผ๊นŒ?

๋ชจ๋“  ๋…ธ๋“œ๊ฐ€ ์ ์–ด๋„ 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})$๊ฐœ๊ฐ€ ๋œ๋‹ค.

This post is licensed under CC BY 4.0 by the author.