
계산 복잡도 이론에는 P, NP, NP-완전 외에도 다양한 복잡도 클래스가 있으며, 이들의 관계는 컴퓨터 과학의 중요한 연구 주제입니다.
복잡도 클래스(Complexity Class)는 비슷한 자원(시간, 공간)을 필요로 하는 문제들의 집합입니다.
쉬운 비유:
학교 과목을 난이도로 분류:
쉬운 과목 (P):
- 기초 수학
- 기초 영어
- 노력하면 누구나 풀 수 있음
어려운 과목 (NP):
- 고급 수학
- 답 확인은 쉽지만 찾기 어려움
매우 어려운 과목 (NP-완전):
- 수학 올림피아드
- 가장 어려운 문제들
더 어려운 과목 (PSPACE, EXPTIME):
- 대학원 수준
- 더 많은 자원 필요
결정 불가능 (Undecidable)
↑
EXPTIME (지수 시간)
↑
PSPACE (다항 공간)
↑
NP (비결정적 다항 시간)
↑
P (결정적 다항 시간)
포함 관계: P ⊆ NP ⊆ PSPACE ⊆ EXPTIME ⊂ 결정 불가능
주의: P = NP인지는 아직 모름!
정의:
문제 L이 co-NP에 속한다 ⟺ L의 여집합이 NP에 속한다
즉:
L: "Yes" 답을 검증하기 쉬움
L의 여집합: "No" 답을 검증하기 쉬움
쉬운 비유:
NP 문제:
"이 그래프에 클리크가 있는가?" → 있다면 클리크를 제시하면 쉽게 확인
co-NP 문제:
"이 그래프에 클리크가 없는가?"
→ 없다면... 어떻게 증명?
→ 모든 조합 확인해야 함 (어려움)
차이:
NP: "있다"는 증명 쉬움
co-NP: "없다"는 증명 쉬움
예시:
# NP 문제: 소인수분해 가능성
def is_composite(n):
"""
합성수인가? (소수가 아닌가?)
문제: n이 합성수인가?
검증 (NP):
- "합성수다"의 증명: 인수 제시
- 예: 15 = 3 × 5
- 곱해보면 확인 가능 (쉬움)
n: 검사할 수
factors: 제시된 인수 (증명서)
Returns: True if 합성수
"""
pass
# co-NP 문제: 소수 판정
def is_prime(n):
"""
소수인가?
문제: n이 소수인가?
검증 (co-NP):
- "소수다"의 증명: 어려움
- 모든 가능한 인수가 없음을 보여야 함
- 전통적으로는 모든 수 확인 필요
특이 사항:
- 소수 판정은 사실 P에 속함 (AKS 알고리즘, 2002)
- 하지만 개념적으로는 co-NP 문제
n: 검사할 수
Returns: True if 소수
"""
pass
P, NP, co-NP 관계:
알려진 사실:
- P ⊆ NP
- P ⊆ co-NP
- P = NP ∩ co-NP (추측, 증명 안 됨)
미해결 질문:
- NP = co-NP인가?
- 대부분 학자: NP ≠ co-NP 추측
정의:
PSPACE: 다항 공간으로 해결 가능한 문제들
특징:
- 시간은 제한 없음
- 공간(메모리)만 다항식으로 제한
- 예: O(n²) 메모리 사용
왜 중요한가?
def pspace_vs_np():
"""
PSPACE와 NP의 차이
NP:
- 다항 시간에 검증 가능
- 시간에 집중
PSPACE:
- 다항 공간으로 해결 가능
- 공간에 집중
관계:
NP ⊆ PSPACE (확실)
이유:
- 다항 시간 알고리즘은 최대 다항 공간만 사용 가능 (한 단계당 최대 O(1) 공간)
역은?
PSPACE ⊆ NP? (모름!)
"""
pass
대표 문제: 양적 불 공식 (QBF)
def quantified_boolean_formula():
"""
양적 불 공식 (Quantified Boolean Formula)
일반 불 공식 (SAT): (x₁ ∨ ¬x₂) ∧ (x₂ ∨ x₃) → x₁, x₂, x₃에 값 할당
양적 불 공식 (QBF): ∀x₁ ∃x₂ ∀x₃ ((x₁ ∨ ¬x₂) ∧ (x₂ ∨ x₃))
의미:
- ∀x₁: 모든 x₁에 대해
- ∃x₂: 어떤 x₂가 존재
- ∀x₃: 모든 x₃에 대해
- 식이 참이 되는가?
복잡도:
- PSPACE-완전
- SAT(NP-완전)보다 어려움
왜 어려운가:
- 변수마다 "모든"과 "존재" 반복
- 게임 트리와 비슷
"""
# 간단한 예시
# ∀x ∃y (x ∨ y)
#
# 의미:
# 모든 x(True/False)에 대해
# 어떤 y가 존재해서
# x ∨ y가 참이 되는가?
#
# 확인:
# x=True: y=True 또는 False (둘 다 OK)
# x=False: y=True 선택
# → 답: Yes
pass
PSPACE-완전 문제들:
게임 문제들:
- 체스 (일반화된 n×n)
- 바둑 (일반화된 n×n)
- 리버시
- 체커
왜 PSPACE?
- 게임 트리 탐색
- 모든 수를 다 볼 필요 없음
- 현재 상태만 메모리에 유지
- 재귀로 다음 수 탐색
- 공간 복잡도: O(깊이)
정의:
EXPTIME: 지수 시간으로 해결 가능한 문제들
시간: 2^(다항식)
예: 2^n, 2^(n²), 2^(n³)
특징:
- 매우 느림
- 작은 입력만 가능
- 하지만 계산 가능
PSPACE vs EXPTIME:
알려진 사실:
PSPACE ⊆ EXPTIME (확실)
이유:
- 다항 공간 사용하는 알고리즘은
- 최대 2^(다항 공간) 가지 상태
- 모든 상태 확인하면 해결 가능
- 시간: 지수
엄격한 포함:
PSPACE ⊊ EXPTIME (확실!)
- EXPTIME에만 속하는 문제 존재
대표 문제:
def exptime_problems():
"""
EXPTIME-완전 문제들
1. 체커 (표준 8×8)
- 일반화 버전(n×n)은 EXPTIME
- 표준 버전도 매우 어려움
2. 정규 표현식 매칭
- 일부 복잡한 정규식
- 백트래킹이 지수 시간
3. 프레스버거 산술
- 덧셈만 있는 산술 논리
- 곱셈 없음
- 그래도 지수 시간!
"""
pass
┌─────────────────────────────────┐
│ 결정 불가능 (Undecidable) │
│ - 정지 문제 │
│ - 프로그램 동치 │
└─────────────────────────────────┘
↑
┌─────────────────────────────────┐
│ EXPTIME (지수 시간) │
│ - 체커, 복잡한 정규식 │
└─────────────────────────────────┘
↑
┌─────────────────────────────────┐
│ PSPACE (다항 공간) │
│ - QBF, 체스, 바둑 │
└─────────────────────────────────┘
↑
┌─────────────────────────────────┐
│ NP │
│ - 다항 시간 검증 │
│ ┌──────────────┐ │
│ │ NP-완전 │ │
│ │- SAT, TSP │ │
│ └──────────────┘ │
└─────────────────────────────────┘
↑
┌─────────────────────────────────┐
│ P │
│ - 다항 시간 해결 │
│ - 정렬, 최단 경로 │
└─────────────────────────────────┘
확실한 관계:
P ⊆ NP ⊆ PSPACE ⊆ EXPTIME ⊂ Undecidable
미해결 질문:
- P = NP?
- NP = PSPACE?
┌─────────────────────────┐
│ 결정 불가능 │
└─────────────────────────┘
↑
┌─────────────────────────┐
│ EXPTIME │
│ ┌──────────────────┐ │
│ │ PSPACE │ │
│ │ ┌─────────────┐ │ │
│ │ │ NP │ │ │
│ │ │ ┌─────────┐ │ │ │
│ │ │ │ P │ │ │ │
│ │ │ └─────────┘ │ │ │
│ │ └─────────────┘ │ │
│ └──────────────────┘ │
└─────────────────────────┘
보장된 포함:
P ⊆ NP ⊆ PSPACE ⊆ EXPTIME
엄격한 차이:
P ⊊ EXPTIME (확실)
PSPACE ⊊ EXPTIME (확실)
def classify_problem(problem_description):
"""
문제를 복잡도 클래스로 분류
체크리스트:
"""
# P 클래스
if has_polynomial_algorithm(problem_description):
return "P - 효율적으로 풀 수 있음"
# NP 클래스
if can_verify_in_polynomial(problem_description):
if is_known_npc(problem_description):
return "NP-완전 - 매우 어려움, 근사 필요"
else:
return "NP - 검증 쉬움, 풀기 어려움"
# PSPACE 클래스
if is_game_problem(problem_description):
return "PSPACE - 게임 문제, 매우 어려움"
# EXPTIME 클래스
if requires_exponential_time(problem_description):
return "EXPTIME - 지수 시간 필요"
# 결정 불가능
if is_undecidable(problem_description):
return "결정 불가능 - 컴퓨터로 풀 수 없음"
return "추가 분석 필요"
def choose_solving_strategy(complexity_class, input_size):
"""
복잡도 클래스에 따른 해결 전략
complexity_class: P, NP, PSPACE, EXPTIME 등
input_size: 입력 크기
Returns: 권장 전략
"""
if complexity_class == "P":
# 다항 시간 알고리즘 사용
return "정확한 알고리즘으로 해결"
elif complexity_class == "NP-완전":
if input_size <= 20:
return "정확한 알고리즘 (브루트포스)"
elif input_size <= 1000:
return "동적 계획법 또는 근사 알고리즘"
else:
return "휴리스틱 (유전 알고리즘, 시뮬레이티드 어닐링)"
elif complexity_class == "PSPACE":
if input_size <= 10:
return "게임 트리 탐색 (알파-베타 가지치기)"
else:
return "몬테카를로 트리 탐색, 강화학습"
elif complexity_class == "EXPTIME":
if input_size <= 5:
return "작은 입력만 처리 가능"
else:
return "문제 단순화 또는 근사"
else: # 결정 불가능
return "완벽한 해결 불가능, 휴리스틱만 가능"
1. 기본 개념
[08-01] 결정 문제
- 모든 문제를 Yes/No로 변환
- 복잡도 분석의 기초
[08-02] 클래스 P
- 다항 시간에 해결 가능
- 효율적인 알고리즘 존재
- 예: 정렬, 최단 경로
2. NP와 NP-완전
[08-03] 클래스 NP
- 다항 시간에 검증 가능
- 답 찾기는 어려울 수 있음
- 예: 스도쿠, 소인수분해
[08-04] NP-완전
- NP 중 가장 어려운 문제들
- 하나만 풀면 모든 NP 풀림
- 예: SAT, TSP, 클리크
[08-05] NP-난해
- NP-완전만큼 또는 더 어려움
- NP에 속하지 않을 수 있음
- 예: TSP 최적화, 정지 문제
3. 환원과 증명
[08-06] 다항 시간 환원
- 문제를 다른 문제로 변환
- 난이도 비교 도구
- NP-완전 증명 방법
4. 계산 불가능성
[08-07] 계산 불가능성
- 컴퓨터로 절대 풀 수 없는 문제
- 자기 참조의 역설
- 예: 프로그램 동치, Rice의 정리
[08-08] 정지 문제
- 가장 유명한 불가능 문제
- 튜링의 증명 (귀류법)
- 실무 의미: 완벽한 도구 불가능
5. 기타 클래스
[08-09] 기타 복잡도 클래스
- co-NP: "No" 증명이 쉬움
- PSPACE: 다항 공간
- EXPTIME: 지수 시간
P = NP 문제:
질문:
"검증이 쉬운 문제는 풀기도 쉬운가?"
만약 P = NP이면:
- 모든 NP-완전 문제를 다항 시간에 풀 수 있음
- 암호화 대부분 무용지물
- 최적화 문제들 쉽게 해결
- 컴퓨터 과학 혁명
대부분 학자의 추측:
P ≠ NP
- NP-완전은 본질적으로 어려움
- 효율적 알고리즘 없음
현재 상황:
- 증명 안 됨 (50년째)
- 100만 달러 상금
- 밀레니엄 문제 중 하나
1. 문제의 본질 이해
알고리즘을 못 찾는 이유:
- 내가 부족해서? ✗
- 문제가 본질적으로 어려워서? ✓
복잡도 이론:
→ 문제의 난이도를 수학적으로 증명
→ "어려운 문제"를 정확히 정의
2. 실무적 가치
문제를 받으면:
1. 복잡도 클래스 판단
2. 적절한 전략 선택
P 문제: 정확한 알고리즘
NP-완전: 근사/휴리스틱
결정 불가능: 휴리스틱만
3. 철학적 의미
컴퓨터의 한계:
- 모든 문제를 풀 수 없음
- 증명된 한계 존재
- 하지만 대부분은 해결 가능
인간과 컴퓨터:
- 둘 다 한계가 있음
- 하지만 보완적
- 함께 더 나은 해결
복잡도 클래스
P: 다항 시간 해결
NP: 다항 시간 검증
NP-완전: NP 중 가장 어려움
co-NP: "No" 증명 쉬움
PSPACE: 다항 공간
EXPTIME: 지수 시간
결정 불가능: 풀 수 없음
계층 구조
P ⊆ NP ⊆ PSPACE ⊆ EXPTIME ⊂ Undecidable
확실한 차이:
P ⊊ EXPTIME
PSPACE ⊊ EXPTIME
미해결:
P = NP?
NP = PSPACE?
실무 전략
P: 정확한 알고리즘
NP-완전: 근사/휴리스틱
PSPACE: 게임 AI
EXPTIME: 작은 입력만
결정 불가능: 휴리스틱
운영체제의 기초 개념으로
[09-01] 프로세스 (Process)
이전 글: [08-08] 정지 문제
다음 글: [09-01] 프로세스
시리즈: P1. Computer Science