휴리스틱 (Heuristics)
정의
휴리스틱 (Heuristics) 은 NP-hard 문제나 지나치게 큰 탐색 공간에서 최적해 대신 실용적으로 충분히 좋은 해를 빠르게 찾는 방법의 총칭. 크게 근사 알고리즘 (Approximation Algorithm, 최적해와의 비율 보장), Local Search (국소적 개선 반복), Greedy Heuristic (탐욕적 선택) 으로 나눈다.
문제 상황과 동기
P != NP 가정 하에 최적해를 다항 시간에 구할 수 없는 문제 (TSP, Knapsack, Vertex Cover, Max Clique 등) 가 존재. 현실에서는 “최적에 가까운” 해로도 충분한 경우가 많음.
- naive (exact): 지수 시간 (2^N). N=50 이상에서 불가능.
- heuristics: O(N log N) ~ O(N^2) 로 최적 대비 90~99% 품질의 해.
핵심 통찰: 최적을 포기하는 대신, 실용적 시간 내에 “충분히 좋은” 해를 얻는다.
시각화
핵심 아이디어
1. 근사 알고리즘 (Approximation Algorithm)
최적해 OPT 에 대해 항상 C <= alpha * OPT (minimization) 를 보장. alpha 를 근사 비율 (Approximation Ratio) 이라 함.
2. Local Search
현재 해의 “이웃 (neighborhood)” 을 정의하고, 더 나은 이웃이 없을 때까지 이동. 지역 최적 (local optimum) 에 빠질 위험.
3. Greedy Heuristic
매 선택에서 당장 가장 좋아 보이는 선택. matroid 구조에서는 최적 보장, 일반적으로는 보장 없음.
알고리즘
# Local Search (Max-Cut 예시)
1. 임의 분할 (S, V\S) 로 초기화
2. repeat:
3. 모든 정점 v 에 대해:
4. v 를 반대편으로 옮기면 cut 증가? -> 이동
5. until 더 이상 개선 없음
6. return S
# Greedy (Vertex Cover 예시)
1. C = empty
2. while 남은 간선 있음:
3. 임의 간선 (u,v) 선택, C 에 u,v 추가
4. u,v 에 부속된 모든 간선 제거
5. return C
구현
// Greedy Vertex Cover (2-approximation)
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m; cin >> n >> m;
vector<pair<int,int>> edges(m);
for (int i = 0; i < m; i++) {
int u, v; cin >> u >> v;
edges[i] = {u, v};
}
vector<bool> covered(m, false);
vector<int> cover;
for (int i = 0; i < m; i++) {
auto [u, v] = edges[i];
if (covered[i]) continue;
cover.push_back(u);
cover.push_back(v);
for (int j = i; j < m; j++) {
auto [a, b] = edges[j];
if (a == u || a == v || b == u || b == v)
covered[j] = true;
}
}
cout << "Cover size: " << cover.size() << "\n";
for (int v : cover) cout << v << " ";
cout << "\n";
}4 4
0 1
1 2
2 3
3 0Cover size: 4
0 1 2 3복잡도
| 항목 | 값 |
|---|---|
| 근사 Greedy | O(N + M) (간선 순회) |
| Local Search (1회 iteration) | O(N) ~ O(N^2) |
| 근사 비율 (Vertex Cover) | 2-approximation (최적의 2배 이내) |
| 근사 비율 (TSP metric) | 1.5-approximation (Christofides) |
변형 / 활용
| 종류 | 예시 | 특징 |
|---|---|---|
| Greedy | Fractional Knapsack, Huffman | 당장 최선, matroid 에서 최적 |
| Local Search | Max-Cut, 2-OPT TSP | 이웃 정의가 핵심 |
| Approximation | Vertex Cover, Set Cover, TSP | 이론적 보장 있음 |
| Metaheuristic | Simulated Annealing, GA | 문제 무관 범용 |
함정
1. Local Optimum
Local Search 가 전역 최적 대신 지역 최적에 갇힘. restart / perturbation 으로 완화.
2. Greedy 의 오판
당장의 이득이 장기적으로 손해. 예: 0-1 Knapsack 에서 Greedy 는 최적 보장 없음.
3. 근사 비율 오해
근사 알고리즘은 guaranteed ratio 를 가짐. Heuristic 은 보통 ratio guarantee 가 없음. 구분 필요.
BOJ 연습 문제
| 번호 | 제목 | 정답률 | 링크 |
|---|---|---|---|
| BOJ 13904 | 과제 (Greedy) | - | kokoa-lab |
| BOJ 1700 | 멀티탭 스케줄링 (Greedy) | - | kokoa-lab |
| BOJ 2217 | 로프 (Greedy) | - | kokoa-lab |
| BOJ 12865 | 평범한 배낭 (Greedy 로는 안 됨) | - | kokoa-lab |
참고
이 글의 용어 (3개)
- 경사 하강법 (Gradient Descent)algorithm
- 정의 경사 하강법 (Gradient Descent, GD) 은 미분 가능한 목적 함수 f(x) 의 1차 도함수 (gradient) 방향으로 반복 이동하며 극소값 (local mi…
- 그리디 (Greedy)algorithm
- 정의 그리디 (Greedy) 알고리즘은 매 단계마다 국소 최적 (locally optimal) 선택을 하여 전역 최적해 (globally optimal solution) 에 도달…
- 담금질 기법 (Simulated Annealing)algorithm
- 정의 담금질 기법 (Simulated Annealing, SA) 은 금속의 담금질 (annealing) 과정에서 영감을 받은 확률적 메타휴리스틱. 온도 T 가 높을 때는 나쁜 해…
💬 댓글