무작위화와 근사 알고리즘으로 성능과 해 품질을 관리하는 법
Randomized Algorithms와 Approximation Algorithms의 원리, 근사 보장, 운영 파라미터와 스트리밍·최적화 적용 방식을 정리한다.
2026-08-14 · 최초 발행 2024-04-29
최적해와 평균 성능 사이의 선택
대규모 데이터와 고성능 시스템에서는 언제나 정확한 최적해를 기다릴 수 없다. 어떤 문제는 내부 무작위성으로 최악의 입력 패턴을 피하는 편이 낫고, 어떤 문제는 다항시간 안에 품질 한계가 분명한 해를 구해야 한다.
Randomized Algorithms는 난수나 랜덤 샘플링을 알고리즘 내부에 포함해 기대 성능을 높이거나 구현을 단순화하는 방식이다. 입력과 독립적인 무작위성을 사용해 평균 시간·공간 복잡도를 개선한다. Monte Carlo형은 확률적 오류를 허용하는 대신 시간 상한을 보장하고, Las Vegas형은 정답을 보장하면서 기대 실행시간 상한을 둔다. 랜덤 퀵소트의 기대 O(n log n) 성능과 랜덤화 해시의 균등 분산이 대표적인 예다.
Approximation Algorithms는 NP-난해 최적화 문제를 다항시간에 풀되, 최적값 OPT와 비교한 해의 오차 한계를 근사비율 ρ로 제시한다. Vertex Cover의 2-근사, Set Cover의 ln n 비율, PTAS와 FPTAS가 이 범주에 속한다. 핵심은 제약을 지키면서 계산 가능한 수준의 해 품질을 확보하는 데 있다.
무작위성은 재현 가능하게 다뤄야 한다
무작위 알고리즘은 시드 관리가 빠지면 실험 재현과 롤백이 어려워진다. 시드를 고정하고, 분산 난수원을 분리하며, 스트리밍 처리에서는 저장공간을 O(1)~O(log n)으로 유지하는 설계가 필요하다. 시드 로그는 운영 기록의 일부가 된다.
평균 성능만 보는 것도 부족하다. 마르코프·체르노프 테일바운드로 실패확률 ε의 상계를 관리하고, 독립 반복이나 부스팅으로 결과를 안정화할 수 있다. 유니버설 해싱, 랜덤 리밸런싱, 지수적 백오프는 충돌과 편향을 줄여 락 경쟁이나 핫스팟 같은 최악 패턴을 완화하는 데 쓰인다.
근사 알고리즘에서는 보장 자체가 운영 계약이 된다. 비등호 변환, Dual Fitting, Linear/LP rounding, 그리디 교정으로 근사비율 ρ를 도출하고 최악의 해 품질 상한을 명시한다. 서브모듈러 최적화의 1−1/e, 메트릭 TSP의 1.5-근사 Christofides, 컷·플로우 문제의 LP-이중성 기반 근사는 문제 구조에 따라 재사용할 수 있는 패턴이다.
PTAS와 FPTAS에서는 ε 파라미터가 실행시간과 해 품질의 교환 조건이 된다. SLA에 맞춰 다단계 근사 파이프라인을 구성할 수 있다.
문제 구조에 따라 경로를 나누기
먼저 문제가 결정 문제인지 최적화 문제인지, NP-완전 또는 NP-난해한지, 메트릭이나 서브모듈러 성질을 갖는지 식별한다. 다항시간에 최적해를 구할 수 있다면 랜덤화로 평균 성능을 높이고 분산을 줄이는 방향을 검토한다. NP-난해 문제라면 근사 알고리즘이나 휴리스틱과 근사 보장을 섞는 방식이 대상이 된다.
무작위 방식은 목표 실패확률 ε를 정한 뒤 독립 반복 k회를 적용해 합성 실패확률을 ε^k로 관리한다. 근사 방식은 근사비율 ρ의 증명을 검토하고, 샘플링 기반 사후 검증으로 Upper/Lower bound를 추정한다. 어느 쪽이든 시드·ε·ρ를 관리하고, 예외 시 폴백 경로와 성능·정확도 메트릭을 함께 둬야 한다.
분산 처리와 최적화에서의 적용
분산 해시와 샤딩에서는 유니버설 해싱 및 키 랜덤화로 파티션을 고르게 분산하고 핫스팟을 줄일 수 있다. 온라인 리밸런싱에서는 충돌 확률의 상계를 관리한다. 랜덤 백오프는 락 경쟁과 재시도 폭주를 막는 데 쓰이며, 큐 스케줄링에 무작위 추출을 섞으면 지연분산을 줄일 수 있다.
스트리밍과 텔레메트리에서는 Reservoir Sampling으로 메모리 O(k) 안에 대표 샘플을 유지한다. Count-Min 스케치는 빈도를 근사 추정하는 수단이다.
네트워크와 물류 설계에서는 Metric TSP의 1.5-근사로 라우팅 초기해를 만든 뒤 지역탐색으로 미세 조정할 수 있다. 카버리지와 시설배치에는 서브모듈러 그리디의 1−1/e를 적용한다. budgeted allocation에는 LP 라운딩으로 수익 근사 보장을 두고, 다단계 근사로 SLA와 캡 제한을 함께 맞춘다. 기한과 가중치 제약이 있는 스케줄링에서는 라그랑지안 라운딩으로 비용 상계를 제시할 수 있다.
데이터 과학과 ML에서는 랜덤 프로젝션 기반 LSH가 근사 최근접 탐색을 가속한다. 시드는 탐색 지연과 재현성의 균형을 통제하는 값이다. SGD와 Subsampling은 확률적 최적화로 대규모 데이터 학습을 가속하며, 배치 샘플링과 학습률 스케줄은 분산 완화에 사용된다.
성능과 운영 부담의 차이
| 구분 | 성능 | 확장성 | 일관성(해 품질/결과 재현) | 안정성(최악 케이스) | 운영 편의 |
|---|---|---|---|---|---|
| Randomized | 기대 성능 우수, 분산 낮춤 | 병렬/스트리밍에 유리 | 시드 고정 시 재현 가능, 해 품질 확률적 | 실패확률 ε 존재, 부스팅으로 완화 | 구현 단순, 파라미터 적음 |
| Approximation | 다항시간 내 보장된 해 품질 | 대규모 최적화에 확장 | 근사비율 ρ로 품질 상한 보장 | 최악 케이스 품질 하한 명시 | 파라미터(ε, ρ)·증명 관리 필요 |
스트림에서 대표 샘플 유지하기
전제: Python 3.10+, 표준 라이브러리만 사용.
# python 3.10+
import random
def reservoir_sample(stream, k, seed=42):
random.seed(seed)
reservoir = []
for i, x in enumerate(stream, start=1):
if i <= k:
reservoir.append(x)
else:
j = random.randint(1, i)
if j <= k:
reservoir[j-1] = x
return reservoir
# 사용 예
if __name__ == "__main__":
data = range(1, 100001)
sample = reservoir_sample(data, k=1000, seed=7) # 재현성 보장
print(len(sample), min(sample), max(sample))
층화가 필요하면 스트라타별로 독립 리저버를 적용한다. 시드와 스트림 오프셋을 로그로 남기고, 분산 환경에서는 시드 공간을 분할한다.
무가중 그래프의 Vertex Cover 근사
# python 3.10+
from collections import defaultdict
def vertex_cover_2approx(edges):
# edges: 리스트[(u, v)], 무방향, 자기 루프 없음 가정
uncovered = set((min(u, v), max(u, v)) for u, v in edges if u != v)
cover = set()
while uncovered:
u, v = uncovered.pop()
cover.update([u, v]) # 두 끝점 추가
to_remove = set()
for a, b in uncovered:
if a in (u, v) or b in (u, v):
to_remove.add((a, b))
uncovered -= to_remove
return cover # |cover| <= 2 * OPT
# 사용 예
if __name__ == "__main__":
E = [(1,2), (2,3), (3,4), (4,1), (2,4)]
C = vertex_cover_2approx(E)
print("cover:", sorted(C))
이 방식은 해 크기 ≤ 2·OPT를 보장한다. 가중치가 있으면 프라이멀-듀얼 또는 LP 라운딩 기법을 적용한다. 대규모 그래프는 엣지 샘플링, 근사, 국소 개선 단계로 파이프라인화할 수 있다.
랜덤화는 퀵소트·해시 기반 파이프라인에서 평균 3060% 지연 감소를 기대할 수 있으며, 워크로드에 따라 달라진다. 근사 스킴은 탐색 공간을 줄여 연산비를 2040% 절감할 수 있다. ρ=1.5인 메트릭 TSP, ρ=2인 VC, ρ≈ln n인 세트 커버처럼 해 품질의 한계를 명시할 수 있다는 점도 운영상 이점이다.
실패확률과 근사비율을 계약 가능한 형태로 관리하면 SLA 설계가 쉬워진다. 시드·ε·ρ를 관리하는 흐름은 재현성, 롤백, 실험 관리를 체계화하고, 스트리밍·분산 환경에서는 데이터 스케치와 샘플링 기반 처리를 안정화한다.