μμ½
- DFSλ μμ λ Έλμμ μμ λ Έλλ₯Ό κΉμ΄ μ°μ μΌλ‘ νμνλ©° μ£Όλ‘ μ€νμ΄λ μ¬κ· ν¨μλ₯Ό ν΅ν΄ ꡬννλ λ°©μμ λλ€.
- μ΄ λ°©μμ λ©λͺ¨λ¦¬ ν¨μ¨μ΄ μ’κ³ κ·Έλν μν κ°μ§μ μ 리νμ§λ§ μ΅λ¨ κ²½λ‘ νμμλ μ ν©νμ§ μμΌλ©° 무ν 루νμ μνμ΄ μμ΅λλ€.
- BFSλ μΈμ ν λ Έλλ€μ λ¨Όμ νμνλ λλΉ μ°μ λ°©μμΌλ‘ μ μ μ μΆ κ΅¬μ‘°μΈ νλ₯Ό νμ©νμ¬ κ΅¬νν©λλ€.
- κ°μ€μΉκ° μλ κ·Έλνμμ μ΅λ¨ κ²½λ‘λ₯Ό μ°Ύλ λ° νμνμ§λ§ λ Έλ μκ° λ§κ±°λ λΆκΈ° κ³μκ° ν΄μλ‘ λ©λͺ¨λ¦¬ μλͺ¨κ° μ¬ν©λλ€.
- λ°λΌμ λͺ¨λ λ Έλλ₯Ό λ°©λ¬Ένκ±°λ κΉμ νμμ΄ νμνλ©΄ DFSλ₯Ό, μ΅λ¨ 거리λ₯Ό ꡬν΄μΌ νλ€λ©΄ BFSλ₯Ό μ ννλ κ²μ΄ μ€μν©λλ€.
1. DFS (Depth-First Search, κΉμ΄ μ°μ νμ)
1. 1 κ°λ
μμ λ Έλμμ μμ λ Έλλ€μ κΉμ΄λ₯Ό μ°μ μΌλ‘ μμλλ‘ νμνλ μκ³ λ¦¬μ¦
κΉμ΄ μ°μ μΌλ‘ λͺ¨λ κ²½μ°μ μλ₯Ό νμνλ μμ νμ μκ³ λ¦¬μ¦μ μνμ§λ§, νμ κ·Έλ μ§λ μλ€. Stackμ νμ©ν λ°λ³΅λ¬Έμ μ°μ΄κ±°λ, μ¬κ·λ¬Έμ ν΅ν΄ ꡬνλλ€.
1.2 νμκ³Όμ
DFSμ κΈ°λ³Έ νμκ³Όμ μ νΉμ λ Έλμμ μμνμ¬ μμΆμ (Backtracking) νκΈ° μ μ κ°λ₯ν μμ λ Έλλ€μ λ©λ¦¬ νμνλ€.
- νΉμ λ Έλλ₯Ό λ°©λ¬ΈνμΌλ©΄, λ°©λ¬Ένλ€κ³ νμ
- ν΄λΉ λ Έλμ μμ λ Έλλ₯Ό νμ
- λμ΄μ μμ λ Έλκ° μμΌλ©΄ μμΆμ
- λ°©λ¬Έν μ μ΄ μλ λ Έλλ₯Ό νμ
- λͺ¨λ λ Έλλ₯Ό λ°©λ¬Έν λ κΉμ§ μ νλ‘μΈμ€ λ°λ³΅
1.3 νΉμ§
μ₯μ
- DFSλ νμ¬ μν μ€μΈ λ Έλλ§ μ μ₯νλ μ€ν λ°μ΄ν° ꡬ쑰λ₯Ό μ¬μ©νκΈ° λλ¬Έμ BFSμ λΉν΄ λ©λͺ¨λ¦¬ κ³΅κ° λ μ°¨μ§νλ€.
- νΉμ λ Έλ λλ λͺ¨λ λ Έλλ₯Ό νμνλ κ²μ΄ λͺ©μ μ΄λΌλ©΄ μ μ©νλ€.
- κ·Έλν μν κ°μ§κ° κ°λ₯νλ€.
λ¨μ
- κ·Έλν κ΅¬μ‘°κ° μνμΈ κ²½μ°, 무ν 루νμ λΉ μ§ μ μλ€.
- λ λ Έλ μ¬μ΄μ μ΅λ¨ κ²½λ‘λ₯Ό μ°ΎμΌλ €λ κ²½μ° μ ν©νμ§ μμ μκ³ λ¦¬μ¦
1.4 ꡬν λ°©λ²
# μμ κ·Έλν
graph = {
1 : [2,3,4],
2 : [5],
3 : [5],
4 : [],
5 : [6,7],
6 : [],
7 : [3]
}λ°λ³΅ ꡬν (stack)
μ°Έκ³ ( λ°μ΄ν° μ€ν ꡬ쑰λ?)
- λ°μ΄ν°κ° 차곑차곑 μμ μ¬λ¦¬λ ννλ‘, κ°μ₯ λ§μ§λ§μ μ½μ λ λ°μ΄ν°κ° κ°μ₯ λ¨Όμ μμ λλ ꡬ쑰
pushΒ : μλ‘μ΄ λ°μ΄ν°λ₯Ό κ°μ₯ 맨 μ(top)μμΉμ μ½μpop: 맨 μ(top) λ°μ΄ν°λ₯Ό μ κ±°
μ€ν λ°μ΄ν° ꡬ쑰λ₯Ό μ¬μ©νμ¬ λ°λ³΅ ꡬνμ ν΅ν΄ λ°©λ¬Έν λ Έλλ₯Ό μΆμ νλ€.
- μμμ λ
Έλλ₯Ό μμμ μΌλ‘ λ°©λ¬Έν κ²μΌλ‘ νμνκ³ μ€νμ
push topμ μμΉν λ Έλλ₯Ό κ°μ Έμ¨λ€.- λ°©λ¬Ένμ§ μμ λͺ¨λ μΈμ λ
Έλλ₯Ό λ°©λ¬Έν ν λ°©λ¬Έν νμλ₯Ό μ€νμ
push - μ€νμ΄ λΉμμ§ λ κΉμ§ λ°λ³΅
def stack_dfs(root):
visited = []
stack = [root]
while stack:
v = stack.pop()
if v not in visited:
visited.append(v)
for w in graph[v]:
stack.append(w)
return visited
print(stack_dfs(1)) #[1,4,3,5,7,6,2]μ¬κ· ꡬν
μ¬κ· ν¨μλ₯Ό μ¬μ©νμ¬ κ·Έλνμ λͺ¨λ λ Έλλ₯Ό λ°©λ¬Ένλ€. νμ¬ λ Έλμ λ°©λ¬Έν μ§ν©μ μ λ ₯κ°μΌλ‘ μ¬μ©νκ³ μμ§ λ°©λ¬Ένμ§ μμ λͺ¨λ μΈμ ν λ Έλμ DFSλ₯Ό μ μ©νλ€.
μ λ°©λ²μ λͺ¨λ λ Έλλ₯Ό λ°©λ¬Ένλ κ²μ΄ λͺ©μ μΌ λ μ μ©νλ€.
def recursive_dfs(root, visited=[]):
visited.append(root)
for w in graph[root]:
if w not in visited:
visited = recursive_dfs(w, visited)
return visited
print(recursive_dfs(1, [])) #[1,2,]λΉκ΅
λ λ°©λ² λͺ¨λ μκ° λ° κ³΅κ° λ³΅μ‘λλ λμΌνλ€.
μΌλ°μ μΌλ‘ λ°λ³΅ ꡬν(Stack)μ νΈμΆ μ€νμ μ¬μ©νμ§ μκΈ° λλ¬Έμ κ³΅κ° μΈ‘λ©΄μμ λ ν¨μ¨μ μ¬κ· ꡬνμ λ°λ³΅ ꡬνλ³΄λ€ κ°λ¨νκ³ κ°κ²°νμ¬ κ°λ μ±μ΄ μ’λ€. κ·Έλ¬λ κ·Έλν ν¬κΈ°κ° ν¬κ±°λ μν κ΅¬μ‘°μΈ κ²½μ° μ€ν μ€λ²νλ‘ λ°μνλ€.
2. BFS(Breadth-First Search, λλΉ μ°μ νμ)
2.1 κ°λ
μμ λ Έλμμ μμ λ Έλλ€μ λλΉλ₯Ό μ°μ μΌλ‘ μμλλ‘ νμνλ μκ³ λ¦¬μ¦
BFSλ μμ νμ μκ³ λ¦¬μ¦μ μνλ©°, κ°μ€μΉκ° μλ κ·Έλνμμ λμΌν 거리μ μλ λͺ¨λ λ Έλλ₯Ό νμνλ€. μ΄ν 거리μ λ Έλλ₯Ό νμνκΈ° μμνλ λ°©μμ΄λ€.
λ°λΌμ, κ°μ€μΉκ° μλ κ·Έλνμμ μ΅λ¨κ±°λ¦¬λ₯Ό ꡬνλ λ¬Έμ μ νμ©λλ€. Queueλ₯Ό νμ©ν΄ λ€μ λ°©λ¬Έν λ Έλλ₯Ό μΆμ νκ±°λ, While λ°λ³΅λ¬Έμ ν΅ν λ¬Έμ λ₯Ό ν΄κ²°νλ€.
2.2 νμ κ³Όμ
μ°Έκ³ ( ν(Queue)μ κ°λ )
- μ μ μ μΆ(FIFO, First In First Out)λ‘ λ¨Όμ λ€μ΄μ¨ λ°μ΄ν°κ° λ¨Όμ λκ°λ λ°©μμ μ ν μλ£κ΅¬μ‘°
frontμμ λ°μ΄ν°λ₯Ό μμ (dequeue)νλ€.rearμμ λ°μ΄ν°λ₯Ό μ½μ (enqueue)νλ€.
- μμ λ Έλμμ μμνκ³ λκΈ°μ΄(Queue)μ μ½μ νλ€.
- λκΈ°μ΄μμ λ
Έλλ₯Ό μ κ±°νκ³ κ²μ¬(
poll=dequeue)νλ€. - κ²μ¬ν λ Έλκ° λͺ©ν λ ΈλλΌλ©΄ κ²μ μλ£
- κ·Έλ μ§ μμ κ²½μ°, κ²μ¬ν λ
Έλμ μν μμ λ
Έλ μ€ λ°©λ¬Ένμ§ μμ μμ λ
Έλλ₯Ό νμ λ£λλ€(
offer=enqueue) - λκΈ°μ΄μ΄ λΉμ΄ μκ±°λ λͺ©ν λ Έλλ₯Ό μ°Ύμ λκΉμ§ μ λ¨κ³ λ°λ³΅νλ€.
2.3 νΉμ§
μ₯μ
- κ°λ¨νκ³ μ΄ν΄νκΈ° μ½λ€.
- μ°κ²°λ κ΅¬μ± μμμμ λͺ¨λ λ Έλλ₯Ό μ°Ύλλ° μ¬μ© κ°λ₯νλ€.
λ¨μ
- λ§μ λ©λͺ¨λ¦¬κ° νμνλ―λ‘ κ·Έλνκ° ν° κ²½μ° μ ν©νμ§ μλ€.
- κ·Έλν μν μ, κ°μ€μΉ κ³ λ €νμ§ μκΈ° λλ¬Έμ κ°μ€μΉ λ§ν¬κ° μλ κ·Έλνμλ μ ν©νμ§ μλ€.
- λ€μ κΉμ΄λ‘ μ΄λνκΈ° μ μ λ Έλμ λͺ¨λ νμ νλͺ©μ νμνκΈ° λλ¬Έμ λΆκΈ° κ³μκ° ν° κ·Έλνμλ λΉν¨μ¨μ μ΄λ€.(λΆκΈ° κ³μλ, κ° λ Έλκ° νκ· μ μΌλ‘ κ°μ§κ³ μλ μμ λ Έλμ κ°μ)
- λ€μ κΉμ΄λ‘ μ΄λνκΈ° μ μ νμ¬ κΉμ΄μ λͺ¨λ λ Έλλ₯Ό λ°©λ¬ΈνκΈ° λλ¬Έμ λ Έλ μκ° λ§μ κ·Έλνμλ λΉν¨μ¨μ μ΄λ€.
- λͺ©ν λ Έλκ° μμ λ Έλμμ λ©λ¦¬ λ¨μ΄μ Έ μμΌλ©΄ λ€μ κΉμ΄λ‘ μ΄λνκΈ° μ μ μ£Όμ΄μ§ κΉμ΄μ λͺ¨λ λ Έλλ₯Ό νμνκΈ° λλ¬Έμ λΉν¨μ¨μ μ΄λ€.
λΉκ΅
- BFSλ λ©λͺ¨λ¦¬ μ¬μ©λμ΄ λ§κ³ , λ Έλ μκ° λ§μ κ·Έλνμλ μ ν©νμ§ μλ€.
- λν, κ°μ€μΉ λ§ν¬κ° μ‘΄μ¬νλ κ·Έλνμ κ²½μ° μ λλ‘ μλνμ§ μμ μ μλ€.
2.4 ꡬν λ°©λ²
μ£Όλ‘ κ·Έλνκ° μ£Όμ΄μ‘μ λ, κ²½λ‘λ₯Ό μ°μ΄μ£Όλ μμ μ νμ©λλ€. 0λ² μμ λ Έλλ₯Ό Queueμ λ£κ³ , while λ°λ³΅λ¬Έμ ν΅ν΄ Queueκ° λΉμμ§ λ κΉμ§ νμνλ€.
λν, μ€λ³΅μ΄ λ°μν κ²½μ°λ₯Ό λλΉνμ¬ boolean λ°°μ΄ visitedλ₯Ό μ μΈνμ¬ λ°©λ¬Έμ²λ¦¬λ₯Ό ꡬννλ€.
# μμ κ·Έλν
graph = {
1 : [2,3,4],
2 : [5],
3 : [5],
4 : [],
5 : [6,7],
6 : [],
7 : [3]K
}
from collections import deque
def BFS(root):
visited = [root] # νμ¬ λ
Έλ λ°©λ¬Έ μ²λ¦¬
queue = deque([root])
while queue:
v = queue.popleft() # νμμ μμ κΊΌλ΄κΈ°
for w in graph[v]:
if w not in visited:
visited.append(w)
queue.append(w)
return visited
print(BFS(1)) #[1,2,3,4,5,6,7]μ°Έκ³ μ¬μ΄νΈ