Potato
μ•ˆλ…•ν•˜μ„Έμš”, κ°μž‘λ‹ˆλ‹€?πŸ₯” ^___^ 😺 github λ°”λ‘œκ°€κΈ° πŸ‘‰πŸ»

Algorithm/Basic

[μ•Œκ³ λ¦¬μ¦˜] 탐색 μ•Œκ³ λ¦¬μ¦˜ DFS, BFS

감자 πŸ₯” 2021. 7. 23. 19:26
λ°˜μ‘ν˜•

-- λ³Έ ν¬μŠ€νŒ…μ€ 이것이 취업을 μœ„ν•œ μ½”λ”© ν…ŒμŠ€νŠΈλ‹€ with 파이썬 책을 μ°Έκ³ ν•˜μ—¬ μž‘μ„±λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

 

1. DFS

  • Depth First Search, 깊이 μš°μ„  탐색
  • κ·Έλž˜ν”„μ˜ κΉŠμ€ 뢀뢄을 μš°μ„ μ μœΌλ‘œ νƒμƒ‰ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜
  • 주둜 μŠ€νƒμ„ ν™œμš©ν•˜λŠ” λ°©μ‹μž„
    • μŠ€νƒ : ν›„μž…ν›„μΆœ)
  • λ™μž‘λ°©μ‹
    1. 탐색 μ‹œμž‘ λ…Έλ“œλ₯Ό μŠ€νƒμ— μ‚½μž…ν•˜κ³  방문처리λ₯Ό ν•œλ‹€.
    2. μŠ€νƒμ˜ 졜 상단 λ…Έλ“œμ— λ°©λ¬Έν•˜μ§€ μ•Šμ€ μΈμ ‘λ…Έλ“œκ°€ μžˆλ‹€λ©΄ κ·Έ μΈμ ‘λ…Έλ“œλ₯Ό μŠ€νƒμ— λ„£κ³  방문처리λ₯Ό ν•œλ‹€. λ°©λ¬Έν•˜μ§€ μ•Šμ€ μΈμ ‘λ…Έλ“œκ°€ μ—†μœΌλ©΄ μŠ€νƒμ—μ„œ μ΅œμƒλ‹¨ λ…Έλ“œλ₯Ό κΊΌλ‚Έλ‹€.
    3. 2번의 과정을 더 이상 μˆ˜ν–‰ν•  수 없을 λ•ŒκΉŒμ§€ λ°˜λ³΅ν•œλ‹€.
  • λ™μž‘λ°©μ‹μ„ μ•„λž˜ κ·Έλž˜ν”„λ₯Ό μ˜ˆμ‹œλ‘œ μ‚΄νŽ΄λ³΄μž.

κ·Έλž˜ν”„ μ˜ˆμ‹œ

  • λ§ˆμ§€λ§‰μ— "μŠ€νƒμ΄ λ“€μ–΄κ°„ μˆœμ„œ" λ₯Ό ν•œλ° λͺ¨μ•„보면, 1,2,7,6,8,3,4,5 κ°€ λœλ‹€.

 

β–Ά  DFSλ₯Ό μ½”λ“œλ‘œ κ΅¬ν˜„ν•΄λ³΄κΈ°

  • μœ„μ™€ λ™μΌν•œ κ·Έλž˜ν”„λ₯Ό 가지고 DFSλ₯Ό ν”„λ‘œκ·Έλž˜λ° μ½”λ“œλ‘œ κ΅¬ν˜„ν•΄λ³΄μž.
  • μ€„κΈ€λ‘œ ν‘œν˜„λœ 것보닀 훨씬 κ°„λ‹¨ν•˜λ‹€.
  • λŒ€λΆ€λΆ„ μž¬κ·€ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œλ‹€. (λ™μž‘μ›λ¦¬λŠ” μŠ€νƒμ΄λ‹€)
#DFS λ©”μ„œλ“œ μ •μ˜
def DFS(graph, v, visited):
    # ν˜„μž¬ λ…Έλ“œλ₯Ό λ°©λ¬Έ 처리
    visited[v] = True
    # μŠ€νƒμ— λ“€μ–΄κ°„ λ…Έλ“œλ“€μ΄ μˆœμ„œλŒ€λ‘œ 좜λ ₯λœλ‹€.
    print(v, end='')
    # ν˜„μž¬ λ…Έλ“œμ™€ μ—°κ²°λœ λ‹€λ₯Έ λ…Έλ“œλ₯Ό μž¬κ·€μ μœΌλ‘œ λ°©λ¬Έ
    for i in graph[v]:
        if not visited[i]:
            DFS(graph, i, visited)

# 각 λ…Έλ“œκ°€ μ—°κ²°λœ 정보λ₯Ό 리슀트 μžλ£Œν˜•μœΌλ‘œ ν‘œν˜„ (2차원 리슀트)
graph = [
    [],
    [2,3,8],
    [1,7],
    [1,4,5],
    [3,5],
    [3,4],
    [7],
    [2,6,8],
    [1,7]
]

# 각 λ…Έλ“œκ°€ 방문된 정보λ₯Ό 리슀트 μžλ£Œν˜•μœΌλ‘œ ν‘œν˜„ (1차원 리슀트)
# 일단 9개λ₯Ό Fasle둜 ν‘œν˜„ν•˜κ³ , λ°©λ¬Έν• λ–„λ§ˆλ‹€ True둜 λ°”κΎΈμ–΄ 쀄 κ²ƒμž„.
# λ…Έλ“œ λ²ˆν˜Έμ™€ ν†΅μΌμ‹œν‚€κΈ° μœ„ν•΄ graph 에도 grpah[0]에 빈 리슀트λ₯Ό λ„£μ–΄μ£Όμ—ˆκ³ , μ—¬κΈ°μ„œλ„ 9개둜.
visited = [False] * 9

# μ •μ˜λœ DFSν•¨μˆ˜ 호좜
DFS(graph, 1, visited)
## 좜λ ₯κ°’ ---> 1 2 7 6 8 3 4 5

 

2. BFS

  • Breadth First Search, λ„ˆλΉ„ μš°μ„  탐색
  • κ°€κΉŒμš΄ λ…Έλ“œλΆ€ν„° νƒμƒ‰ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜
  • 주둜 큐λ₯Ό ν™œμš©ν•˜μ—¬ κ΅¬ν˜„λ¨.
    • 큐 : μ„ μž…μ„ μΆœ λ°©μ‹μ˜ 자료ꡬ쑰
  • λ™μž‘λ°©μ‹
    1. 탐색 μ‹œμž‘ λ…Έλ“œλ₯Ό 큐에 μ‚½μž…ν•˜κ³  방문처리λ₯Ό ν•œλ‹€.
    2. νμ—μ„œ λ…Έλ“œλ₯Ό κΊΌλ‚΄ ν•΄λ‹Ή λ…Έλ“œμ˜ 인접 λ…Έλ“œ 쀑 λ°©λ¬Έν•˜μ§€ μ•Šμ€ λ…Έλ“œλ₯Ό λͺ¨λ“  큐에 μ‚½μž…ν•˜κ³  방문처리λ₯Ό ν•œλ‹€.
    3. 2번 과정을 더 이상 μˆ˜ν–‰ν•  수 없을 λ•ŒκΉŒμ§€ μ§„ν–‰ν•œλ‹€.
  • λ™μž‘λ°©μ‹μ„ μ•„λž˜ κ·Έλž˜ν”„λ₯Ό μ˜ˆμ‹œλ‘œ μ΄ν•΄ν•΄λ³΄μž.

κ·Έλž˜ν”„ μ˜ˆμ‹œ

  • 큐에 λ“€μ–΄κ°„ μˆœμ„œλŠ” 1, 2, 3, 8, 7, 4, 5, 6 이 λœλ‹€.

 

β–Ά BFSλ₯Ό μ½”λ“œλ‘œ κ΅¬ν˜„ν•΄λ³΄κΈ°

  • μœ„μ—μ„œ 닀룬 λ™μΌν•œ κ·Έλž˜ν”„λ₯Ό 가지고 BFSμ½”λ“œλ₯Ό κ΅¬ν˜„ν•΄ 볼것이닀.
  • deque 라이브러리λ₯Ό μ‚¬μš©ν•  수 μžˆκΈ°μ— κ΅¬ν˜„μ΄ κ°„λ‹¨ν•˜λ‹€.
  • deque 라이브러리λ₯Ό μ‚¬μš©ν•˜λ©΄ O(N)의 μ‹œκ°„μ΄ μ†Œμš”λœλ‹€.
    • λ”°λΌμ„œ 일반적으둜 μž¬κ·€ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” DFS 보닀 μˆ˜ν–‰ μ‹œκ°„μ΄ 더 νš¨μœ¨μ μ΄λ‹€.
from collections import deque

# BFS λ©”μ„œλ“œ μ •μ˜
def BSF(graph, start, visited):
    # 큐 κ΅¬ν˜„μ„ μœ„ν•΄ deque 라이브러리λ₯Ό ν™œμš© ν•  것이닀.
    queue = deque([start])
    # ν˜„μž¬ λ…Έλ“œλ₯Ό 방문처리
    visited[start] = True
    # 큐가 빌 λ•ŒκΉŒμ§€ 반볡
    while queue:
        # 큐에 λ“€μ–΄κ°„ μ›μ†Œλ“€μ΄ μˆœμ„œλŒ€λ‘œ 좜λ ₯λœλ‹€.
        print(v, end=' ')
        # ν•΄λ‹Ή μ›μ†Œμ™€ μ—°κ²°λœ, 아직 λ°©λ¬Έν•˜μ§€ μ•Šμ€ μ›μ†Œλ“€μ„ 큐에 μ‚½μž…ν•˜μž.
        for i in graph[v]:
            if not visited[i]:
                queue.append(i)
                visited[i] = True

# 각 λ…Έλ“œκ°€ μ—°κ²°λœ 정보λ₯Ό μ—°κ²°λ¦¬μŠ€νŠΈ λ°©μ‹μœΌλ‘œ ν‘œν˜„
graph = [
    [],
    [2,3,8],
    [1,7],
    [1,4,5],
    [3,5],
    [3,4],
    [7],
    [2,6,8],
    [1,7]
]

# 각 λ…Έλ“œκ°€ 방문된 정보λ₯Ό 1차원 리슀트둜 ν‘œν˜„
visited = [False] * 9

# BFS 호좜
BFS(graph, 1, visited)

## 좜λ ₯될 κ²°κ³Ό ---> 1 2 3 8 7 4 5 6

 

λ°˜μ‘ν˜•