Updated:

2 minute read

개요

  • 모든 경우의 수를 전부 고려하는 알고리즘
  • 상태공간을 트리로 나타낼 수 있을 때 적합한 방식
  • BFS는 큐의 크기를 고려해야하고 DFS는 트리의 깊이를 고려하여 선택
  • 최단 거리의 경우 BFS가 유리


DFS

  • 한 방향으로 진행하다가 끝에 다다르거나 더 진행해도 해가 없음이 확인되면 마지막 분기점으로 돌아가 다른 방향으로 진행을 반복
  • 미로찾기, N-Queen


BFS

  • 모든 분기점을 검사해가는 방식
  • 가위바위보
    • 3가지 결과를 검사하고 각각 결과에 대해 3가지 결과를 검사
    • DFS를 쓰면 무한에 빠질 수도 있음


예제

  • 자연수 N과 M이 주어졌을 때, 1부터 N까지 자연수 중에서 중복 없이 M개를 고른 수열
    • 같은 수를 여러번 골라도 되는 경우에는 visited 조건 제외
    • Go
         package main
              
         import (
         	"bufio"
         	"fmt"
         	"os"
         )
              
         func dfs(writer *bufio.Writer, visited []bool, result []int, numberChoice, numberEnd, index int) {
         	if index == numberChoice {
         		for _, value := range result {
         			fmt.Fprintf(writer, "%d ", value)
         		}
         		fmt.Fprintf(writer, "\n")
              
         		return
         	}
              
         	for i := 1; i <= numberEnd; i++ {
         		if visited[i] {
         			continue
         		}
              
         		result[index] = i
              
         		visited[i] = true
         		dfs(writer, visited, result, numberChoice, numberEnd, index+1)
         		visited[i] = false
         	}
         }
              
         func main() {
         	reader := bufio.NewReader(os.Stdin)
         	writer := bufio.NewWriter(os.Stdout)
         	defer writer.Flush()
              
         	N := 0
         	M := 0
         	fmt.Fscanf(reader, "%d %d\n", &N, &M)
              
         	visited := make([]bool, N+1)
         	result := make([]int, M)
         	dfs(writer, visited, result, M, N, 0)
         }
      
  • 자연수 N과 M이 주어졌을 때, 1부터 N까지 자연수 중에서 중복 없이 M개를 고른 집합
    • 같은 수를 여러번 골라도 되는 경우에는 visited 조건 제외
    • Go
         package main
              
         import (
         	"bufio"
         	"fmt"
         	"os"
         )
              
         func dfs(writer *bufio.Writer, visited []bool, result []int, numberChoice, numberStart, numberEnd, index int) {
         	if index == numberChoice {
         		for _, value := range result {
         			fmt.Fprintf(writer, "%d ", value)
         		}
         		fmt.Fprintf(writer, "\n")
              
         		return
         	}
              
         	for i := numberStart; i <= numberEnd; i++ {
         		if visited[i] {
         			continue
         		}
              
         		result[index] = i
              
         		visited[i] = true
         		dfs(writer, visited, result, numberChoice, i, numberEnd, index+1)
         		visited[i] = false
         	}
         }
              
         func main() {
         	reader := bufio.NewReader(os.Stdin)
         	writer := bufio.NewWriter(os.Stdout)
         	defer writer.Flush()
              
         	N := 0
         	M := 0
         	fmt.Fscanf(reader, "%d %d\n", &N, &M)
              
         	visited := make([]bool, N+1)
         	result := make([]int, M)
         	dfs(writer, visited, result, M, 1, N, 0)
         }
      
  • N-Queen
    • Go
         package main
              
         import (
         	"bufio"
         	"fmt"
         	"os"
         )
              
         func promising(board []int, currentRow int) bool {
         	for i := 0; i < currentRow; i++ {
         		if board[i] == board[currentRow] ||
         			i-currentRow == board[i]-board[currentRow] ||
         			(i-currentRow)*-1 == board[i]-board[currentRow] {
         			return false
         		}
         	}
              
         	return true
         }
              
         func dfs(board []int, currentRow, boardSize int, result *int) {
         	if currentRow == boardSize {
         		*result++
         	}
              
         	for i := 0; i < boardSize; i++ {
         		board[currentRow] = i
         		if promising(board, currentRow) {
         			dfs(board, currentRow+1, boardSize, result)
         		}
         	}
         }
              
         func main() {
         	reader := bufio.NewReader(os.Stdin)
         	writer := bufio.NewWriter(os.Stdout)
         	defer writer.Flush()
              
         	N := 0
         	fmt.Fscanln(reader, &N)
              
         	board := make([]int, 15)
              
         	result := 0
         	dfs(board, 0, N, &result)
              
         	fmt.Fprintln(writer, result)
         }