3.5 Graph - 3.5.2 Depth First Search(DFS)

2024. 1. 29. 02:29ใ†CS - Roadmap.sh/3. Common Algorithms

CS - 3. Common Algorithms - 3.5 Graph - 3.5.2 Depth First Search(DFS)

Depth First Search

๐Ÿ’กDepth first search is a graph traversal algorithm that starts at a root node and explores as far as possible along each branch before backtracking.

๊นŠ์ด ์šฐ์„  ๊ฒ€์ƒ‰์€ ๋ฃจํŠธ ๋…ธ๋“œ์—์„œ ์‹œ์ž‘ํ•˜์—ฌ ๊ฐ ๋ถ„๊ธฐ๋ฅผ ๋”ฐ๋ผ ๊ฐ€๋Šฅํ•œ ํ•œ ๋ฉ€๋ฆฌ ํƒ์ƒ‰ํ•œ ํ›„ ์—ญ์ถ”์ ํ•˜๋Š” ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค.

 


๋จผ์ €, ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰(Depth First Search, DFS)์— ๋Œ€ํ•ด ์„ค๋ช…๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

DFS๋Š” ๋ฃจํŠธ ๋…ธ๋“œ(ํ˜น์€ ๋‹ค๋ฅธ ์ž„์˜์˜ ๋…ธ๋“œ)์—์„œ ์‹œ์ž‘ํ•ด์„œ ๋‹ค์Œ ๋ถ„๊ธฐ(branch)๋กœ ๋„˜์–ด๊ฐ€๊ธฐ ์ „์— ํ•ด๋‹น ๋ถ„๊ธฐ๋ฅผ ์™„๋ฒฝํ•˜๊ฒŒ ํƒ์ƒ‰ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ์˜ ๊ตฌ์กฐ๊ฐ€ ํŠธ๋ฆฌ ํ˜น์€ ๊ทธ๋ž˜ํ”„ ํ˜•ํƒœ์ผ ๋•Œ ์‚ฌ์šฉํ•˜๋ฉฐ, ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒฝ์šฐ์— ์ด ๋ฐฉ๋ฒ•์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

DFS์˜ ๋™์ž‘ ๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค

1. ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์Šคํƒ์— ๋„ฃ์Šต๋‹ˆ๋‹ค.
2. ํ˜„์žฌ ์Šคํƒ์˜ ๋งจ ์œ„ ๋…ธ๋“œ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
3. ํ˜„์žฌ ๋…ธ๋“œ์— ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ์ธ์ ‘ ๋…ธ๋“œ๊ฐ€ ์žˆ์œผ๋ฉด ๊ทธ ๋…ธ๋“œ๋ฅผ ์Šคํƒ์— ๋„ฃ๊ณ  ๋ฐฉ๋ฌธ์ฒ˜๋ฆฌ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ์ธ์ ‘ ๋…ธ๋“œ๊ฐ€ ์—†์œผ๋ฉด ์Šคํƒ์—์„œ ๋งจ ์œ„ ๋…ธ๋“œ๋ฅผ ๊บผ๋ƒ…๋‹ˆ๋‹ค.
4. ๋” ์ด์ƒ 2๋ฒˆ์˜ ๊ณผ์ •์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์—†์„ ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค.

 

์ฃผ์˜์ ์€ ๊นŠ์ด๊ฐ€ ๋ฌดํ•œ๋Œ€๊ฐ€ ๋  ๋•Œ์ด๋‹ค. ํŠนํžˆ ๋ฃจํ”„(ํšŒ๋กœ)๊ฐ€ ์žˆ๋Š”๊ฒฝ์šฐ DFS๋Š” ์—ฃ์ง€๋ฅผ ํƒˆ์ถœํ• ์ˆ˜ ์—†๊ฒŒ ๋œ๋‹ค.

๊นŠ์ด๊ฐ€ ์•„์ฃผ ๊นŠ์–ด๋„ ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๊ฐ€ ๋ฐœ์ƒํ• ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ฃผ์˜ํ•ด์•ผํ•œ๋‹ค.

 

In Python

DFS๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š” ์Šคํƒ๋ฐฐ์—ด๊ณผ ์žฌ๊ท€(3.2. Recursion)๋ฅผ ์‚ฌ์šฉํ• ์ˆ˜๋„ ์žˆ๋‹ค.

 

3.5.2.1 DFS - ์Šคํƒ๋ฐฐ์—ด๋กœ ๊ตฌํ˜„ํ•˜๊ธฐ

 

def DFS(graph, root):
    visited = []
    stack = [root]

    while stack:
        n = stack.pop()
        if n not in visited:
            visited.append(n)
            stack += graph[n] - set(visited)
    return visited

 

๋ฆฌ์ŠคํŠธ์™€ set() ๊ฐ„์— - ์—ฐ์‚ฐ์ด ์ง€์›๋˜์ง€ ์•Š๋Š”๋‹ค. ์œ„์˜ ํ•จ์ˆ˜์—์„œ stack += graph[n] - set(visted) ์—์„œ

graph ๋„ set()์„ ์”Œ์›Œ์ฃผ๋ฉด ๋œ๋‹ค.

 

def DFS(graph, root):
    visited = []
    stack = [root]

    while stack:
        n = stack.pop() 
        if n not in visited:
            visited.append(n)
            stack += set(graph[n]) - set(visited)
            # print("graph : ",  set(graph[n]), "visited : ", set(visited) ) # ์ ˆ์ฐจ ๋ณด์—ฌ์ฃผ๊ธฐ
    return visited

DFS ๋Œ€๋กœ ์ž˜ ๋ณด์ธ๋‹ค.

์•ž์žฅ์—์„œ ๊ทธ๋ž˜ํ”„๋ฅผ ์‹œ๊ฐํ™” ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ด์šฉํ•ด์„œ ์‹œ๊ฐํ™” ํ•ด๋ณด๋ฉด ์ด๋ ‡๋‹ค.

1 - 2,3 ์ด ์žˆ๋Š”๋ฐ 

์œ„์˜ ํ•จ์ˆ˜๋Š” ์‹œ์ž‘ ๋…ธ๋“œ์—์„œ ๊ฐ€์žฅ ๋ฉ€๋ฆฌ ์žˆ๋Š” ๋…ธ๋“œ๋ถ€ํ„ฐ ๋ฐฉ๋ฌธํ•˜๊ฒŒ ๋œ๋‹ค. (1-3-6)

๊ทธ๋Ÿฐ ์ˆœ์„œ๋Œ€๋กœ 1-2-5-7, 1-2-4 ๋ฅผ ๋ฐฉ๋ฌธํ•˜๊ฒŒ ๋œ๋‹ค.

 

์ง€๊ธˆ ์œ„์˜ ํ•จ์ˆ˜์—๋Š” ์‚ด์ง ์˜ค๋ฅ˜๊ฐ€์žˆ๋Š”๋ฐ,

์›๋ž˜๋ผ๋ฉด 1-2,3 ์—์„œ ์ž‘์€ ๋…ธ๋“œ ์ˆœ์„œ๋Œ€๋กœ ๋ฐฉ๋ฌธํ•ด์•ผ ํ•˜๋Š”๋ฐ, pop()์„ ์‚ฌ์šฉํ•ด์„œ {2,3}์—์„œ ์ œ์ผ ๋’ค์˜ 3๋ถ€ํ„ฐ ๋ฐฉ๋ฌธํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

( pop()์„ ์‚ฌ์šฉํ•œ ์ด์œ ๋Š” ์‹œ๊ฐ„ ๋ณต์žก๋„๊ฐ€ O(1) ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. pop(0)์„ ์‚ฌ์šฉํ•˜๊ฒŒ๋˜๋ฉด ๊ฐ€์žฅ ์•ž์˜ ์›์†Œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ ๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ์›์†Œ๋ฅผ ํ•œ์นธ์”ฉ ์ด๋™์‹œ์ผœ์•ผํ•˜๋ฏ€๋กœ ์‹œ๊ฐ„ ๋ณต์žก๋„๊ฐ€ O(n) ์ด ๋œ๋‹ค.)

 

pop(0)์„ ์‚ฌ์šฉํ•ด ์ œ๋Œ€๋กœ DFS๋ฅผ ๋งŒ๋“ ๋‹ค๋ฉด,

def DFS_pop0(graph, root):
    visited = []
    stack = [root]

    while stack:
        n = stack.pop(0) # pop(0)์„ ์‚ฌ์šฉํ•˜์—ฌ ์Šคํƒ์˜ ์ฒซ ๋ฒˆ์งธ ์š”์†Œ๋ฅผ ์ถ”์ถœ
        if n not in visited:
            visited.append(n)
            stack = list(set(graph[n]) - set(visited)) + stack # stack์˜ ์•ž์ชฝ์— ์•„์ง ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€
            # print("graph : ",  set(graph[n]), "visited : ", set(visited) )
    return visited

์ œ๋Œ€๋กœ 1-2,3 ์—์„œ 2 ๋…ธ๋“œ๋ถ€ํ„ฐ ํƒ์ƒ‰์„ ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

 

 

 

3.5.2.2 DFS - ์žฌ๊ท€ํ˜ธ์ถœ๋กœ ๊ตฌํ˜„ํ•˜๊ธฐ

 

def dfs_recursion(graph: dict, start: int):
    visited = {node: False for node in graph.keys()}
    result = []  # ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ฅผ ์ €์žฅํ•  ๋ฆฌ์ŠคํŠธ

    def search(current: int):
        visited[current] = True
        result.append(current)  # ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ฅผ result์— ์ถ”๊ฐ€

        for next_node in graph[current]:
            if not visited[next_node]:
                search(next_node)

    search(start)
    return result  # ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ์˜ ์ˆœ์„œ๋ฅผ ๋ฐ˜ํ™˜

 

search ํ•จ์ˆ˜ ๋‚ด์—์„œ search(next_node)๋กœ ์žฌ๊ท€ ํ˜ธ์ถœ๋กœ์จ ๊ตฌํ˜„ํ•œ๋‹ค.

ํ˜„์žฌ ๋…ธ๋“œ์˜ ์ธ์ ‘ ๋…ธ๋“œ๋“ค ์ค‘ ์•„์ง ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ๊ฐ€ ์žˆ๋‹ค๋ฉด, ๊ทธ ๋…ธ๋“œ๋ฅผ ๋‹ค์‹œ search ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ๋„ฃ์–ด์„œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

 

 

 

 

 

BFS ์™€ DFS

 

๋ฐฑํŠธ๋ž˜ํ‚น(Backtracking).

๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ์ „๋ถ€ ๊ณ ๋ คํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์— ์ ํ•ฉํ•œ ๋ฐฉ์‹๋“ค์ด๋‹ค.

๊ฒฝ์šฐ์— ๋”ฐ๋ผ ๋‹ค๋ฅด์ง€๋งŒ, ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฒฝ์šฐ์˜ ์ˆ˜์—์„œ๋Š” DFS๊ฐ€ ์œ ๋ฆฌํ•˜๋‹ค. 

 

1. ๋ชจ๋“  ๊ฐ€๋Šฅ์„ฑ ํƒ์ƒ‰ 

- DFS ๋Š” ํ•œ๋ฐฉํ–ฅ์œผ๋กœ ๋๊นŒ์ง€ ํƒ์ƒ‰ํ•œ ํ›„ ๋‹ค๋ฅธ ๋ฐฉํ–ฅ์œผ๋กœ ํƒ์ƒ‰์„ ์ง„ํ–‰ํ•˜๊ธฐ์— ๋ฐฑํŠธ๋ž˜ํ‚น ๋ฌธ์ œ์ธ ๋ชจ๋“  ๊ฐ€๋Šฅ์„ฑ์„ ํƒ์ƒ‰ํ•˜๋Š”๋ฐ ์œ ๋ฆฌํ•Ÿ.

 

2. ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์„ฑ

- BFS๋Š” ํ๋ฅผ ์‚ฌ์šฉํ•ด ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ์ €์žฅํ•œ๋‹ค.

  ๋ฐ˜๋ฉด DFS๋Š” ์Šคํƒ์„ ์‚ฌ์šฉํ•ด ํ˜„์žฌ ๊ฒฝ๋กœ์ƒ์˜ ๋…ธ๋“œ๋งŒ์„ ์ €์žฅํ•˜๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ์ ๋‹ค.

 

3. ํ•ด๋‹ต ๋„๋‹ฌ ์‹œ ๋น ๋ฅธ ์ข…๋ฃŒ

- DFS๋Š” ํ•ด๋‹ต์— ๋„๋‹ฌํ•˜๋ฉด ์ฆ‰์‹œ ํƒ์ƒ‰์„ ์ข…๋ฃŒํ•  ์ˆ˜ ์žˆ๋‹ค.

  ๋ฐ˜๋ฉด BFS๋Š” ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์ข…๋ฃŒ ์‹œ์ ์ด ๋Šฆ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค.

 

 

DFS ์‚ฌ์šฉ์‹œ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ์€ ์•„์ฃผ ์น˜๋ช…์ ์ธ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋ฏ€๋กœ ์•ž์—์„œ๋„ ๋‹ค๋ค˜์—ˆ๋‹ค.

๋‹ค์‹œ ์ •๋ฆฌํ•ด๋ณด์ž๋ฉด,

 

1. ๋ฌดํ•œ ๋ฃจํ”„

- DFS๋Š” ์žฌ๊ท€ ํ˜ธ์ถœ์„ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ, ์ž˜๋ชป ๊ตฌํ˜„์‹œ ๋ฌดํ•œ ๋ฃจํ”„์— ๋น ์งˆ ์ˆ˜ ์žˆ๋‹ค.

 ๋”ฐ๋ผ์„œ ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ฅผ ์ฒดํฌํ•ด์•ผ ํ•˜๋ฉฐ, ์žฌ๊ท€ ํ˜ธ์ถœ์˜ ์ข…๋ฃŒ ์กฐ๊ฑด์„ ๋ช…ํ™•ํžˆ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค.

 

2. ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ

- ์žฌ๊ท€ ํ˜ธ์ถœ์˜ ๊นŠ์ด๊ฐ€ ๋„ˆ๋ฌด ๊นŠ์–ด์ง€๋ฉด ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‰ฝ๋‹ค.

์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ์œ„ํ•ด ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•œ DFS ๊ตฌํ˜„์„ ๊ณ ๋ คํ•  ์ˆ˜ ๋„ ์žˆ๋‹ค.

 

728x90

'CS - Roadmap.sh > 3. Common Algorithms' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

3.5 Graph - 3.5.4 Dijkstraโ€™s Algorithm  (2) 2024.01.30
3.5 Graph - 3.5.3 Bellman Fordโ€™s Algorithm  (1) 2024.01.29
3.5 Graph - 3.5.1 Breadth First Search(BFS)  (0) 2024.01.28
3.5 Graph & 3.6 Tree  (0) 2024.01.27
3.4. Cache - 3.4.3 MFU Cache  (0) 2024.01.27