과학적 일정 추정: PERT에서 Monte Carlo까지
I’m happy to translate the article for you, but I’ll need the full text you’d like translated. Could you please paste the content (or the portion you want translated) here? I’ll keep the source line, formatting, markdown, and any code blocks exactly as they appear.
PERT (Program Evaluation and Review Technique)
PERT는 1950년대 미국 해군에 의해 폴라리스 미사일 프로젝트를 위해 개발되었습니다. 이 비밀 프로젝트는 개발 기간을 2년 단축시켰습니다.
def pert_estimation(optimistic, realistic, pessimistic):
"""
O: Optimistic (when everything is perfect)
R: Realistic (normal case)
P: Pessimistic (when everything goes wrong)
"""
# PERT formula
expected = (optimistic + 4 * realistic + pessimistic) / 6
# Standard deviation (uncertainty)
std_dev = (pessimistic - optimistic) / 6
return {
"expected": expected,
"std_dev": std_dev,
"range_68%": (expected - std_dev, expected + std_dev),
"range_95%": (expected - 2 * std_dev, expected + 2 * std_dev)
}
# Real example: Login API development
result = pert_estimation(
optimistic=4, # Best: 4 hours
realistic=8, # Reality: 8 hours
pessimistic=16 # Worst: 16 hours
)
print(f"Expected: {result['expected']:.1f} hours") # 8.7 hours
print(f"68% probability: {result['range_68%']}") # (6.7, 10.7)
print(f"95% probability: {result['range_95%']}") # (4.7, 12.7)
왜 4를 곱하나요?
이 계수는 정상에 가까운 분포에서 가장 가능성이 높은(최빈값) 추정치에 더 큰 가중치를 부여하며, 이는 애자일 팀에 유용합니다.
플래닝 포커
A quick, team‑wide consensus technique:
- 모든 사람이 카드를 준비합니다 (1, 2, 3, 5, 8, 13, 21, 34…).
- 카드를 동시에 공개합니다.
- 추정값이 크게 차이날 경우, 이유를 논의합니다.
- 합의된 추정값에 도달합니다.
fibonacci = [1, 2, 3, 5, 8, 13, 21, 34]
심리적 효과: 큰 숫자에 대해 더 넓은 간격을 두어 과도한 정밀도를 방지합니다.
몬테카를로 시뮬레이션
몬테카를로는 무작위 샘플링을 사용하여 프로젝트 완료 시간을 모델링합니다.
import random
import numpy as np
def monte_carlo_simulation(tasks, iterations=1000):
"""Simulate project completion time."""
results = []
for _ in range(iterations):
total_time = 0
for task in tasks:
# Randomly select actual time for each task
actual = random.triangular(
task['min'],
task['max'],
task['likely']
)
total_time += actual
results.append(total_time)
return {
"mean": np.mean(results),
"p50": np.percentile(results, 50), # Median
"p90": np.percentile(results, 90), # 90 % probability
"p95": np.percentile(results, 95) # 95 % probability
}
# Project tasks
tasks = [
{"name": "Design", "min": 2, "likely": 3, "max": 5},
{"name": "Development", "min": 5, "likely": 8, "max": 15},
{"name": "Testing", "min": 2, "likely": 3, "max": 6}
]
result = monte_carlo_simulation(tasks)
print(f"50% probability: complete within {result['p50']:.1f} days")
print(f"90% probability: complete within {result['p90']:.1f} days")
속도 기반 추정
과거 스프린트 속도를 활용하여 향후 작업을 예측합니다.
class VelocityEstimator:
def __init__(self, past_sprints):
self.velocities = past_sprints
def estimate(self, total_points):
avg_velocity = np.mean(self.velocities)
std_velocity = np.std(self.velocities)
sprints_needed = total_points / avg_velocity
return {
"expected_sprints": sprints_needed,
"optimistic": total_points / (avg_velocity + std_velocity),
"pessimistic": total_points / (avg_velocity - std_velocity)
}
# Past 10 sprint velocities
past_velocities = [23, 28, 25, 30, 22, 27, 26, 24, 29, 26]
estimator = VelocityEstimator(past_velocities)
result = estimator.estimate(total_points=150)
print(f"Expected: {result['expected_sprints']:.1f} sprints")
print(f"Range: {result['optimistic']:.1f} ~ {result['pessimistic']:.1f}")
전문가 합의 (와이드밴드 델파이)
구조화된 다라운드 추정 프로세스:
-
Round 1 – 익명 제출
- Dev A: 10일
- Dev B: 5일
- Dev C: 15일
-
Round 2 – 이유 공유 및 재추정
- A: “DB 마이그레이션을 고려하면…”
- B: “아, 그걸 놓쳤네요.”
- C: “테스트 자동화가 포함돼 있나요?”
새로운 추정값: 8일, 9일, 10일.
-
Round 3 – 합의
- 최종 추정: 9일.
권장 사항
| 접근 방식 | 사용 시점 |
|---|---|
| 플래닝 포커 | 빠르고 쉬운 팀 합의 |
| PERT + 속도 | 정확도와 실용성의 균형 |
| 몬테카를로 + 와이드밴드 델파이 | 위험 분석이 필요한 고정밀 프로젝트 |
유사 과거 프로젝트를 통한 추정치 조정
similar_projects = [
{"name": "Login System A", "estimated": 20, "actual": 35},
{"name": "Login System B", "estimated": 15, "actual": 28},
{"name": "Login System C", "estimated": 25, "actual": 40}
]
adjustment_factor = np.mean([p["actual"] / p["estimated"] for p in similar_projects])
# adjustment_factor ≈ 1.73
# Apply to a new raw estimate
new_estimate = raw_estimate * adjustment_factor
스프린트 추정 회고
| 작업 | 예상 | 실제 | 차이 | 원인 |
|---|---|---|---|---|
| API 개발 | 8 시간 | 12 시간 | +4 시간 | 인증 복잡도 |
| UI 구현 | 6 시간 | 5 시간 | –1 시간 | 템플릿 재사용 |
| 테스트 | 4 시간 | 8 시간 | +4 시간 | 엣지 케이스 |
교훈: 인증 및 테스트 단계는 대략 1.5× 여유를 두어야 합니다.
마무리 생각
- PERT를 사용하여 불확실성을 계산하십시오.
- 단일 숫자가 아니라 범위로 추정하십시오.
- 과거 데이터(속도, 유사 프로젝트)를 활용하십시오.
- 전체 팀을 참여시키십시오 (Planning Poker, Wideband Delphi).
- 추정 프로세스를 지속적으로 개선하십시오.
과학적인 추정 및 프로젝트 관리가 필요하신가요? Plexo를 확인해 보세요.