05-4 8퀸 문제
8퀸 문제 알아보기
8퀸 문제(8-Queen prooblem)는 재귀 알고리즘을 설명할 때 자주 나오는 예제입니다.
8개의 퀸이 서로 공격하여 잡을 수 없도록 8 x 8 체스판에 배치하세요.
분기 작업으로 문제 해결하기
실습 5-7 각 열에 퀸을 1개 배치하는 조합을 재귀적으로 나열하기
# 각 열에 퀸을 1개 배치하는 조합을 재귀적으로 나열하기
pos = [0] * 8 # 각 열에서 퀸의 위치를 출력
def put() -> None:
"""각 열에 배치한 퀸의 위치를 출력"""
for i in range(8):
print(f'{pos[i]:2}',end='')
print()
def set(i: int) -> None:
"""i열에 퀸을 배치"""
for j in range(8):
pos[i] = j # 퀸을 j행에 배치
if i == 7: # 모든 열에 퀸 배치를 종료
put()
else:
set(i + 1) # 다음 열에 퀸을 배치
set(0)
이렇게 차례대로 가지가 뻗어 나가듯이 배치 조합을 열거하는 방법을 분기(branching) 작업이라고 합니다. 하노이의 탑이나 8퀸 문제처럼 큰 문제를 작은 문제로 분할하고, 작은 문제 풀이법을 결합하여 전체 풀이법을 얻는 방법을 분할 정복법(divide and conquer 분할 해결법)이라고 합니다.
한정 작업과 분기 한정법
실습 5-8 행과 열에 퀸을 1개 배치하는 조합을 재귀적으로 나열하기
# 행과 열에 퀸을 1개 배치하는 조합을 재귀적으로 나열하기
pos = [0]* 8 # 각 열에서 퀸의 위치
flag = [False] * 8 # 각 행에 퀸을 배치했는지 체크
def put() -> None:
"""각 열에 배치한 퀸의 위치를 출력"""
for i in range(8):
print(f'{pos[i]:2}', end='')
print()
def set(i:int) -> None:
"""i열의 알맞은 위치에 퀸을 배치"""
for j in range(8):
if not flag[j]: # j행에 퀸을 배치하지 않았으면
pos[i] = j # 퀸을 j행에 배치
if i == 7: # 모든 열에 퀸 배치를 완료
put()
else:
flag[j] = True
set(i + 1) # 다음 열에 퀸을 배치
flag[j] = False
set(0)
실습 5-8 프로그램은 flag라는 새로운 list형 배열을 사용합니다. 이 배열은 같은 행에 중복하여 퀸을 배치하지 않기 위한 표시로 사용됩니다.
8퀸 문제 해결 프로그램 만들기
실습 5-9 8퀸 문제 알고리즘 구현하기
# 8퀸 문제 알고리즘 구현하기
pos = [0] * 8 # 각 열에 배치한 퀸의 위치
flag_a = [False] * 8 # 각 해에 퀸을 배치했는지 체크
flag_b = [False] * 15 # 대각선 방향(↙↗)으로 퀸을 배치했는지 체크
flag_c = [False] * 15 # 대각선 방향(↘↖)으로 퀸을 배치했는지 체크
def put() -> None:
"""각 열에 배치한 퀸의 위치를 출력"""
for i in range(8):
print(f'{pos[i]:2}', end='')
print()
def set(i: int) -> None:
"""i열의 알맞은 위치에 퀸을 배치"""
for j in range(8):
if( not flag_a[j] # j행에 퀸이 배치되지 않았다면
and not flag_b[i + j] # 대각선 방향(↙↗)으로 퀸이 배치되지 않았다면
and not flag_c[i - j + 7]): # 대각선 방향(↘↖)으로 퀸이 배치되지 않았다면
pos[i] = j # 퀸을 j행에 배치
if i == 7: # 모든 열에 퀸을 배치 완료
put()
else:
flag_a[j] = flag_b[i + j] = flag_c[i - j + 7] = True
set(i + 1)
flag_a[j] = flag_b[i + j] = flag_c[i - j + 7] = False
set(0) # 0열에 퀸을 배치
# 8퀸 문제 알고리즘 □와 ■로 구현하기
pos = [0] * 8 # 각 열에 배치한 퀸의 위치
flag_a = [False] * 8 # 각 해에 퀸을 배치했는지 체크
flag_b = [False] * 15 # 대각선 방향(↙↗)으로 퀸을 배치했는지 체크
flag_c = [False] * 15 # 대각선 방향(↘↖)으로 퀸을 배치했는지 체크
def put() -> None:
"""퀸의 배치를 □와 ■로 출력"""
for j in range(8):
for i in range(8):
print('■' if pos[i] == j else '□', end='')
print()
print()
def set(i: int) -> None:
"""i열의 알맞은 위치에 퀸을 배치"""
for j in range(8):
if( not flag_a[j] # j행에 퀸이 배치되지 않았다면
and not flag_b[i + j] # 대각선 방향(↙↗)으로 퀸이 배치되지 않았다면
and not flag_c[i - j + 7]): # 대각선 방향(↘↖)으로 퀸이 배치되지 않았다면
pos[i] = j # 퀸을 j행에 배치
if i == 7: # 모든 열에 퀸을 배치 완료
put()
else:
flag_a[j] = flag_b[i + j] = flag_c[i - j + 7] = True
set(i + 1)
flag_a[j] = flag_b[i + j] = flag_c[i - j + 7] = False
set(0) # 0열에 퀸을 배치
- 출처: Do it! 자료구조와 함께 배우는 알고리즘 입문 - 파이썬 편
- notebook ipynb file: https://github.com/heejvely/Algorithm/blob/main/Do_it_algorithm/Do_it_%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98_%EC%9E%AC%EA%B7%80%20%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98.ipynb
GitHub - heejvely/Algorithm: 파이썬 알고리즘 인터뷰 책을 참고한 파이썬 알고리즘 연습
파이썬 알고리즘 인터뷰 책을 참고한 파이썬 알고리즘 연습. Contribute to heejvely/Algorithm development by creating an account on GitHub.
github.com
'Code > Algorithm' 카테고리의 다른 글
[Algorithm] 정렬 알고리즘_2(버블 정렬) (2) | 2022.12.19 |
---|---|
[Algorithm] 정렬 알고리즘_1 (0) | 2022.12.19 |
[Algorithm] 재귀 알고리즘_3(하노이의 탑) (0) | 2022.12.09 |
[Algorithm] 재귀 알고리즘_2 (0) | 2022.12.09 |
[Algorithm] 재귀 알고리즘_1 (2) | 2022.12.06 |