Cute Running Puppy

알고리즘

알고리즘(8)

jwjin 2025. 2. 3. 15:24
728x90

- Back Tracking(되돌아가며 풀어보기)

백트래킹 알고리즘 : 해를 찾는 과정에서 해를 더 이상 얻지 못하면 바로 직전 상태로 되돌아가서 다른 것을 시도하며 해를 찾는다.

  • 백트래킹 알고리즘은 최적화 문제결정 문제를 해결
  • 결정 문제 : 문제에 대한 해의 존재 여부(즉, 해가 '있다' 또는 '없다')를 답하는 문제
  • 백트래킹은 해 탐색 순서가 깊이 우선(Depth First)으로 수행
  • 분기 한정(Branch-and-Bound) 알고리즘 - 한정 값(bound)을 이용하여 한정 값이 가장 좋은 것 부터 최선 우선(Best First)탐색하는 방식으로 탐색 범위를 상당히 줄여서 해를 찾는다.

 

- M-coloring 백트래킹 알고리즘

인접한 영역을 서로 다른 색으로 칠하는 지도 색칠

지도를 Graph를 활용하여 보면 n개의 영역 = n개의 정점 / 두 영역이 서로 인접하면 그래프에선 두 영역에 대응되는 두 정점들을 간선으로 잇는다.

  1. 정점 0을 하나의 색으로 칠함
  2. 모든 점들이 색칠될 때까지 다음 점이 이미 색칠된 점과 인접하면, 인접한 점의 색과 다른 색을 선택

단, 주어진 k(색의 수)에 대해 색칠 실패하면 k를 1증가 후, 처음부터 다시 알고리즘 수행

상태 공간 트리(state space tree)

수행시간 : O(nkⁿ)

 

- 여왕 말 문제(n-Queens problem)

Q가 같은 열, 같은 행, 같은 대각선상에 서로 놓이지 않도록 n x n 장기판에 n개의 Q를 배치하는 문제 (단, n>3)

  1. Q를 (0, 0)부터 놓기 시작하여 다음 Q를 서로 위협하지 않도록 배치한다.
  2. 만일 배치할 수 없으면, 직전 Q의 위치를 다음 칸으로 이동하여 다시 시도한다. 다음 칸이 없는 경우에는 위층의 Q를 다음 칸으로 이동하여 시도한다.
def solve_n_queens(n):
    def is_safe(board, row, col):
        # 같은 열 확인
        for i in range(row):
            if board[i] == col:
                return False

        # 좌상향 대각선 확인
        for i, j in zip(range(row - 1, -1, -1), range(col - 1, -1, -1)):
            if board[i] == j:
                return False

        # 우상향 대각선 확인
        for i, j in zip(range(row - 1, -1, -1), range(col + 1, n)):
            if board[i] == j:
                return False

        return True

    def solve(row, board, solutions):
        if row == n:
            solutions.append(board[:])  # 현재 해를 저장
            return

        for col in range(n):
            if is_safe(board, row, col):
                board[row] = col
                solve(row + 1, board, solutions)
                board[row] = -1  # 백트래킹

    solutions = []
    board = [-1] * n  # 각 행에 퀸의 열 위치를 저장
    solve(0, board, solutions)

    # 결과 출력
    def print_board(solutions):
        for sol in solutions:
            for i in sol:
                row = ["."] * n
                row[i] = "Q"
                print(" ".join(row))
            print("\n")

    print_board(solutions)
    return len(solutions)

# 예제 실행
n = 8  # n-Queens 문제에서 n의 값
solution_count = solve_n_queens(n)
print(f"총 솔루션 개수: {solution_count}")

수행시간 : O(nⁿ⁺¹)

 

- 합이 K 되는 숫자

동적 계획 알고리즘에서 이 알고리즘은 O(nK) 시간에 최적해를 찾았는데 K=2ⁿ 이라면, DP알고리즘도 n이 커질수록 해를 찾기 어렵다. 백트래킹 알고리즘을 이용하여 좀더 빠르게 해를 찾을 수 있다.

  1. 주어진 숫자들을 증가 순으로 정렬
  2. 순서대로 숫자를 선택하는 경우(o)와 포기하는 경우(x)로 나누어 상태 공간 트리의 노드를 만든다. 만일 노드를 만들 수 없거나 만들 필요가 없으면 부모 노드로 되돌아가서 다른 노드를 선택한다.
  3. 위에서 만든(선택한) 노드에서 해를 찾으면 알고리즘 종료, 해가 아니면 2를 수행한다.

 

가지치기(punning)

입력을 정렬하는 이유: 자식 노드를 만들 때 다음 숫자를 추가한 합이 K를 초과하면 그 이후의 숫자는 다음 숫자보다 크므로 만들어진 노드로부터 아래로 더 이상 탐색해도 해가 없으므로

탐색 중단 : 가지치기(punning)

수행 시간 : O(2ⁿ)

 

728x90

'알고리즘' 카테고리의 다른 글

알고리즘(7)  (0) 2025.01.24
알고리즘(6)  (0) 2025.01.23
알고리즘(5)  (0) 2025.01.22
알고리즘(4)  (0) 2025.01.22
알고리즘(3)  (0) 2024.10.13