BFS(Breadth-First Search)

A -> B
|
v
C -> D

์œ„ ๊ทธ๋ž˜ํ”„๋ฅผ distance layer ํ˜•ํƒœ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

์ถœ๋ฐœ ๋…ธ๋“œ๋ฅผ A๋ผ๊ณ  ํ–ˆ์„ ๋•Œ A์˜ layer๋Š” 0์ด๋ฉฐ A์™€ ๊ฐ„์„  1๊ฐœ๋กœ ์—ฐ๊ฒฐ๋œ C์™€ B์˜ layer๋Š” A๋ฅผ ๊ธฐ์ค€์œผ๋กœ 1์ด๋‹ค.

์ดˆ๋ก์ƒ‰์œผ๋กœ ๋œ ๊ฐ„์„ ์€ ๊ทธ๋ž˜ํ”„์˜ distance layer์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์ง€๋งŒ, ๋นจ๊ฐ„์ƒ‰ ๊ฐ„์„ ์˜ ๊ฒฝ์šฐ A์™€ D์˜ ๊ฑฐ๋ฆฌ๋ฅผ 2์—์„œ 1๋กœ ๋ฐ”๊พธ๋ฏ€๋กœ distance layer ํ˜•ํƒœ๋ฅผ ๋ณ€ํ•˜๊ฒŒ ํ•œ๋‹ค.

BFS

BFS๋Š” ์ธ์ ‘ํ•œ ์ •์ ๋“ค์„ ์šฐ์„ ์œผ๋กœ ํƒ์ƒ‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ, ํ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ๋‘ ์ •์ ์˜ ๊ฑฐ๋ฆฌ(์ตœ์†Œ ๊ฒฝ๋กœ)๋ฅผ ๊ตฌํ•˜๊ณ ์ž ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋ฉฐ ์˜์‚ฌ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

def BFS(G, start_v):
  for u in V:
    dist[u] = infinity

  start_v = 0

  queue = {start_v} 
  
  while queue is not empty:
    u = dequeue(queue)
    for adj_v in adjacent_vertexes(u):
      if dist[adj_v] == infinity:
        enqueue(adj_v)
        dist[adj_v] = dist[u] + 1

BFS์˜ ์‹œ๊ฐ„๋ณต์žก๋„ = O(|E| + |V|)

๊ฐ ์ •์ ์€ ์ตœ๋Œ€ 1๋ฒˆ ํ์— ์‚ฝ์ž…๋œ๋‹ค. -> while๋ฌธ์€ |V|๋งŒํผ ์‹คํ–‰ํ•œ๋‹ค.

์ •์  ์‚ฌ์ด์˜ ๊ฐ ๊ฐ„์„ ์„ ํ†ตํ•ด ์ •์ ์˜ ๋ฐฉ๋ฌธ ์—ฌ๋ถ€๋ฅผ ์ฒดํฌํ•œ๋‹ค. -> for๋ฌธ์€ ์ด ๊ฐ„์„ ์˜ ๊ฐฏ์ˆ˜๋งŒํผ ์‹คํ–‰ํ•œ๋‹ค.

(๋ฐฉํ–ฅ์—†๋Š” ๊ทธ๋ž˜ํ”„๋Š” ๊ฐ„์„ ์˜ ๊ฐฏ์ˆ˜ * 2 ๋งŒํผ ์‹คํ–‰ํ•œ๋‹ค.)

์ตœ๋‹จ ๊ฒฝ๋กœ ํŠธ๋ฆฌ (Shortest-path Tree)

์ตœ๋‹จ ๊ฒฝ๋กœ ํŠธ๋ฆฌ๋Š” ๋ฐฉํ–ฅ์—†๋Š” ๊ทธ๋ž˜ํ”„ ๋‚ด์˜ ๊ฐ ์ •์  ์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ(์ตœ๋‹จ ๊ฒฝ๋กœ)๋ฅผ ํŠธ๋ฆฌ๋กœ ๋‚˜ํƒ€๋‚ธ๋‹ค. ์–ด๋–ค ์ •์  S๋ฅผ ์‹œ์ž‘์œผ๋กœ BFS๋ฅผ ์‹คํ–‰ํ•˜๊ณ ๋‚˜์„œ ๊ฐ ์ •์ ์—์„œ S๋กœ์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ €์žฅํ•œ๋‹ค. ํŠธ๋ฆฌ์˜ ๋ฃจํŠธ๋Š” S๊ฐ€ ๋œ๋‹ค.

๊ทธ๋ž˜ํ”„์™€ ์ตœ๋‹จ ๊ฒฝ๋กœ ํŠธ๋ฆฌ

๋ฐฉํ–ฅ์—†๋Š” ๊ทธ๋ž˜ํ”„์˜ ์ •์  S์—์„œ B๋กœ ๊ฐ€๋Š” ์ตœ๋‹จ ๊ฒฝ๋กœ๋Š” B์—์„œ S๋กœ ๊ฐ€๋Š” ์ตœ๋‹จ ๊ฒฝ๋กœ์™€ ๊ฐ™๋‹ค. ๋”ฐ๋ผ์„œ ๊ฐ ์ •์ ์—์„œ S๋กœ ํ–ฅํ•˜๋Š” ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ํŠธ๋ฆฌ ํ˜•ํƒœ๋กœ ๋งŒ๋“  ๊ฒƒ์ด ์ตœ๋‹จ ๊ฒฝ๋กœ ํŠธ๋ฆฌ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, B์—์„œ S๋กœ ํ–ฅํ•˜๋Š” ์ตœ๋‹จ ๊ฒฝ๋กœ๋Š” 3์ด๋‹ค.

์ตœ๋‹จ ๊ฒฝ๋กœ ํŠธ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด

  • ๋‘ ์ •์ ์˜ ๊ฑฐ๋ฆฌ(์ตœ๋‹จ ๊ฒฝ๋กœ)๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

  • S -> A ์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ํ†ตํ•ด A -> S ์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์–ด๋А ์ •์ ์„ ์‹œ์ž‘์ ์œผ๋กœ ํ•˜์—ฌ ๋ชจ๋“  ์ •์ ๊ณผ์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋“ค์„ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

์ตœ๋‹จ ๊ฒฝ๋กœ ํŠธ๋ฆฌ์˜ ์ค‘์š”ํ•œ ํŠน์ง• ์ค‘ ํ•˜๋‚˜๋Š” ํŠธ๋ฆฌ๋กœ ๋‚˜ํƒ€๋‚ด๋Š” ๊ทธ๋ž˜ํ”„์— ์‚ฌ์ดํด์ด ์—†๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

์ •์  S์™€ A์˜ ๊ฑฐ๋ฆฌ(์ตœ๋‹จ ๊ฒฝ๋กœ)๊ฐ€ d๋ผ๊ณ  ํ–ˆ์„ ๋•Œ A๋Š” ๋‹ค๋ฅธ ์ •์  B, C, D, E์™€ ์‚ฌ์ดํด์„ ์ด๋ฃฌ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. A์—์„œ S๋กœ ํ–ฅํ•˜๋Š” ์ตœ๋‹จ ๊ฒฝ๋กœ๋Š” S์—์„œ A๋กœ ํ–ฅํ•˜๋Š” ์ตœ๋‹จ ๊ฒฝ๋กœ์™€ ๊ฐ™๋‹ค. ๋”ฐ๋ผ์„œ A์—์„œ ์ถœ๋ฐœํ•˜์—ฌ ๋‹ค๋ฅธ ์ •์ ์œผ๋กœ ์ด๋™ํ•  ๋•Œ๋งˆ๋‹ค d๋ฅผ 1์”ฉ ๊ฐ์†Œ์‹œ์ผœ S์— ๋„์ฐฉํ–ˆ์„ ๋•Œ 0์ด ๋˜๋Š”์ง€ ํ™•์ธํ•˜๋ ค๊ณ  ํ•œ๋‹ค.

A, B, C, D, E๊ฐ€ ์‚ฌ์ดํด์„ ์ด๋ฃฐ ๋•Œ ๋ฌดํ•œ์œผ๋กœ d๊ฐ€ ๊ฐ์†Œ๋˜๋ฏ€๋กœ A์—์„œ S๋กœ ํ–ฅํ•˜๋Š” ์ตœ๋‹จ ๊ฒฝ๋กœ๋Š” ๋งˆ์ด๋„ˆ์Šค ๋ฌดํ•œ๋Œ€๊ฐ€ ๋  ๊ฒƒ์ด๋‹ค. ์ด๋Š” A์—์„œ S๋กœ ํ–ฅํ•˜๋Š” ์ตœ๋‹จ ๊ฒฝ๋กœ๊ฐ€ d๋ผ๋Š” ๊ฐ€์ •๊ณผ ๋ชจ์ˆœ๋˜๋ฏ€๋กœ ์ตœ๋‹จ ๊ฒฝ๋กœ ํŠธ๋ฆฌ์— ์‚ฌ์ดํด์ด ์กด์žฌํ•˜์ง€ ์•Š์Œ์„ ์ฆ๋ช…ํ•œ๋‹ค.

์•„๋ž˜๋Š” prev ๋ฐฐ์—ด์— ์ด์ „์— ๋ฐฉ๋ฌธํ–ˆ๋˜ ์ •์ ์„ ์ €์žฅํ•˜์—ฌ ์ตœ๋‹จ ๊ฒฝ๋กœ ํŠธ๋ฆฌ๋ฅผ ๋งŒ๋“œ๋Š” ์ฝ”๋“œ๋‹ค.

def BFS(G, start_v):
  for u in V:
    dist[u] = infinity
    prev[u] = nil

  start_v = 0

  queue = {start_v} 
  
  while queue is not empty:
    u = dequeue(queue)
    for adj_v in adjacent_vertexes(u):
      if dist[adj_v] == infinity:
        enqueue(adj_v)
        dist[adj_v] = dist[u] + 1
        prev[adj_v] = u


# u์—์„œ S๋กœ ํ–ฅํ•˜๋Š” ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•œ๋‹ค.
# ์˜ˆ) ConstructPath(S, G, prev) -> (G, B, A, S) ๋ฆฌํ„ด 
def ConstructPath(S, u, prev):
  result = empty
  
  while u != S:
    result.append(u)
    u = prev[u]
  
  return reverse(result)    

์ตœ๋‹จ ๊ฒฝ๋กœ ํŠธ๋ฆฌ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‘ ์ •์ ์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•  ๋•Œ ์‹œ๊ฐ„๋ณต์žก๋„๋Š” O(|V| + |E|) ์ด๋‹ค.

์ถœ์ฒ˜

Last updated

Was this helpful?