# 문제 유형별 수치해석 기법 개괄

수치해석은 이산적인 연산 환경에서 연속적인 문제들을 근사적으로 다루는 다양한 기법을 포괄한다. 실제로 응용되는 대상 문제는 비선형 방정식이나 선형 연립방정식, 적분 및 미분을 비롯한 다양한 미분방정식, 다항식 보간이나 데이터 피팅 등으로 광범위하며, 각 문제 유형에 따라 접근 전략과 알고리즘이 달라진다. 문제 유형별 특성을 정확히 파악한 뒤, 그 목적에 가장 적합한 알고리즘을 활용하는 것이 필수적이다. 여기서는 대표적인 문제 유형을 나누어 그 기본 원리와 흔히 쓰이는 기법들을 엄밀하게 살펴본다.

#### 비선형 방정식의 해 구하기

연속적인 함수 $f(x)$에 대하여 $f(x) = 0$을 만족하는 $x$를 찾는 문제는 응용 분야 전반에서 자주 발생한다. 예를 들어 물리나 공학 현상에서 시스템의 균형점 혹은 특수 해를 구하는 상황에서 나타난다. 이때 사용하는 방법 중 가장 기본적인 것은 이분법(bisection method)이며, $f(a)$와 $f(b)$의 부호가 서로 반대임이 보장되는 구간 $\[a, b]$ 내부에 근이 존재한다고 할 때, 구간을 반복적으로 이등분하며 해를 좁혀나간다. 수렴은 상대적으로 느리지만 단조롭고 안정적이다.

뉴턴 방법(Newton-Raphson method)은 $f'(x)$가 존재한다는 전제 아래, 수렴 속도를 획기적으로 높일 수 있는 기법이다. 뉴턴 방법은 다음 식을 반복적으로 적용한다.

$$
x\_{n+1} = x\_n - \frac{f(x\_n)}{f'(x\_n)}
$$

여기서 $f'(x\_n)$이 0에 근접하지 않는다고 가정하면, 보통 2차 수렴(quadratic convergence)을 기대할 수 있다. 그러나 초기값 $x\_0$의 선택이나 $f'(x)$의 계산 등이 까다롭다는 단점이 있으며, $f'(x)$를 구하기 어려운 경우에는 할선법(secant method)과 같은 미분계수를 직접 구하지 않는 알고리즘을 쓸 수 있다.

이 외에도 고차 다항식의 근을 찾기 위한 폴리어(POLYALG) 알고리즘, 이터레이션의 안전성 개선을 위한 레귤라-파솔라 기법, 혹은 다차원 문제에서 야코비 행렬을 근사적으로 구해가며 해를 찾는 다변수 뉴턴 방법 등이 실용적으로 많이 응용된다.

#### 선형 연립방정식의 해법

행렬 $\mathbf{A}$와 미지수 벡터 $\mathbf{x}$, 우변 벡터 $\mathbf{b}$에 대하여 $\mathbf{A}\mathbf{x} = \mathbf{b}$를 만족하는 $\mathbf{x}$를 구하는 문제도 매우 중요하다. 계수가 될 수 있는 행렬 $\mathbf{A}$는 대칭 행렬, 희소 행렬, 대각우세 행렬 등 다양한 특성을 가질 수 있으며, 문제의 규모가 커질수록 효율적인 알고리즘 설계가 필수적이다.

직접 해법(direct method)의 대표 예로 가우스 소거(Gaussian elimination) 과정이 있다. 가우스 소거에서 축차적으로 열 혹은 행을 사용해 피보 존(leading principal submatrix)을 삼각화(triangularization)한다. 그 뒤 전방 대입(forward substitution)과 후방 대입(backward substitution)을 통해 해를 구한다. 이와 같은 과정에서 부동소수점 연산 오차를 줄이기 위해 피벗팅(pivoting)을 적절히 수행한다.

행렬을 $L$과 $U$로 분해하는 $LU$ 분해나 $QR$ 분해는 반복적으로 같은 계수 행렬을 사용하되 우변 벡터만 달라지는 상황에서 효율적이다. 희소(sparse) 구조를 갖는 거대 규모 행렬일 경우, 고전적인 가우스 소거보다 희소성(sparsity)를 보존하기 위한 특별한 알고리즘을 사용해야 한다.

반복 해법(iterative method)으로는 자코비(Jacobi) 방법, 가우스-자이델(Gauss-Seidel) 방법, SOR(초과이완법) 등이 흔히 쓰인다. 이러한 방법은 초기 추정치 $\mathbf{x}^{(0)}$에 대해

$$
\mathbf{x}^{(k+1)} = \mathbf{M}\mathbf{x}^{(k)} + \mathbf{c}
$$

형태로 점진적인 근사값을 갱신하며, 보통 대각 우세(diagonally dominant) 구조나 특정 조건에서 수렴이 보장된다. 매우 큰 차원을 다루거나 계수가 매우 복잡한 경우에도 반복해법은 적은 메모리를 활용하여 근사해를 구할 수 있다.

#### 고윳값 문제

행렬 $\mathbf{A}$의 고윳값(eigenvalue)와 고유벡터(eigenvector)를 구하는 문제는 물리학, 기계공학, 통계학(주성분분석) 등 다양한 영역에서 핵심적이다. 고윳값 분해를 통해서는 다양한 선형 변환의 해석이 가능해진다.

수치적으로 중요한 대표 기법은 거듭제곱 방법(power method)이며, 어떤 벡터 $\mathbf{x}^{(0)}$에 대하여 $\mathbf{x}^{(k+1)} = \frac{\mathbf{A}\mathbf{x}^{(k)}}{|\mathbf{A}\mathbf{x}^{(k)}|}$와 같이 반복하여 가장 큰 절댓값의 고윳값에 대응하는 고유벡터를 근사한다. 레일리 몫 반복(Rayleigh quotient iteration)을 사용하면 수렴 속도가 크게 개선될 수 있으며, QR 알고리즘은 일반적인 정사각 행렬의 고윳값을 전부 구할 수 있는 견고한 방법이다.

#### 보간법과 근사

주어진 데이터 점 $(x\_i, y\_i)$를 통과하는 함수를 찾거나, 혹은 어떤 함수를 더 낮은 차원 혹은 단순한 형태로 근사하는 문제는 계산 과학과 공학 전반에 걸쳐 등장한다. 다항식 보간(polynomial interpolation)에서 라그랑주(Lagrange) 보간이나 뉴턴(Newton) 보간 다항식을 통해 데이터를 통과하는 폴리노미얼을 찾을 수 있다. 라그랑주 보간식은

$$
P(x) = \sum\_{j=0}^{n} y\_j \ell\_j(x)
$$

형태를 가지며, 이때 $\ell\_j(x)$는 $x\_j$를 제외한 나머지 지점들에 대해 0이 되도록 구성된 라그랑주 기저다항식이다. 그러나 고차 다항식을 사용할수록 런지 현상(Runge phenomenon)이 발생할 수 있다.

따라서 스플라인(spline)을 사용한 구간별 보간(piecewise polynomial interpolation)이 더욱 안정적이다. 구간별로 비교적 낮은 차수의 다항식을 사용하되, 접합점에서 연속성과 매끄러움을 보장한다. 2차 혹은 3차 스플라인이 가장 흔히 쓰인다. 특히 3차 스플라인은 2차 도함수가 각 구간에서 연속하도록 하여, 상당히 부드러운 보간 함수를 구현한다.

보간이 아니라 최소제곱근사(least squares approximation)를 통해 노이즈가 낀 데이터를 모델링하는 경우도 많다. 이때에는 보통 잔차의 제곱합

$$
\sum\_{i} \bigl( y\_i - f(x\_i) \bigr)^2
$$

이 최소가 되도록 $f(x)$의 파라미터를 결정한다. 선형 회귀 문제로 귀결되는 경우, $\mathbf{A}^T \mathbf{A} \mathbf{p} = \mathbf{A}^T \mathbf{y}$를 풀어 해를 구한다.

#### 최적화 문제

함수 $g(\mathbf{x})$를 최소화 혹은 최대화하는 $\mathbf{x}$를 찾는 문제도 폭넓게 다룬다. 제약식이 없는 단순 스칼라 함수의 1차원 최적화부터, 다변수 벡터 공간의 대규모 제약 조건 최적화까지 다양한 변형이 존재한다. 1차원 무제약 최적화에서 골든 섹션 서치(golden section search)나 이분 탐색 기법을 활용하며, 다차원 최적화에는 경사하강법(gradient descent), 뉴턴 방법, 준뉴턴(quasi-Newton) 등 다양한 이터레이션 전략이 쓰인다.

뉴턴 방법을 최적화에 적용할 경우, 헤세 행렬(Hessian matrix) $\mathbf{H} = \nabla^2 g(\mathbf{x})$의 역행렬을 활용하는

$$
\mathbf{x}\_{n+1} = \mathbf{x}\_n - \mathbf{H}^{-1}(\mathbf{x}\_n) \nabla g(\mathbf{x}\_n)
$$

형식을 따른다. 실제로는 헤세 행렬의 직접 계산 및 역행렬화가 부담스럽기 때문에, BFGS(Barzilai-Borwein, Davidon-Fletcher-Powell 등 포함), L-BFGS 같은 준뉴턴 기법이 더 광범위하게 쓰인다.

#### 수치적 적분과 미분

연속적인 적분

$$
\int\_a^b f(x), dx
$$

을 근사하는 문제는 $f(x)$가 주어진 구간에서 비교적 원활(smooth)하고 직접 적분이 어려운 경우에 유용하다. 가장 기본적인 사각형 공식부터 사다리꼴 공식(trapezoidal rule), 심프슨 공식(Simpson’s rule) 등이 체계적으로 발전되어 있다. 사다리꼴 공식은 단순히 구간을 잘게 나누고, 구간마다 직선 보간을 통해 넓이를 추정한다. 심프슨 공식은 쌍분할구간당 2차 다항식 보간을 활용하기 때문에, $f(x)$가 다항식 함수에 근사적일 경우 효과적이다. 복합 사다리꼴 공식 혹은 복합 심프슨 공식은 구간 분할 횟수를 늘려 정밀도를 높일 수 있다.

수치 미분은 $f'(x)$를 직접 구할 수 없는 상황에서 차분 근사값으로 유도된다. 전방 차분, 후방 차분, 중심 차분 등 기초적인 차분식은 테일러 전개를 통해 오차항이 어떻게 구성되는지 분석한다. 예를 들어 중심 차분은

$$
f'(x) \approx \frac{f(x + h) - f(x - h)}{2h}
$$

로 주어지며, 이때 오차항은 일반적으로 $O(h^2)$로 분석된다. 고차 정확도를 가지는 차분 공식도 확장적으로 쓸 수 있다.

#### 상미분방정식(ODE)의 수치해법

실제 물리 현상이나 동역학 시스템의 해석에 핵심이 되는 상미분방정식(Ordinary Differential Equation)을 수치적으로 풀기 위해서는 초기값 문제(Initial Value Problem, IVP)와 경계값 문제(Boundary Value Problem, BVP)를 구분해야 한다. 초기값 문제는 시점 $t\_0$에서 $\mathbf{x}(t\_0) = \mathbf{x}\_0$가 주어졌을 때, 미분방정식

$$
\frac{d\mathbf{x}}{dt} = \mathbf{f}\bigl(t,\mathbf{x}(t)\bigr)
$$

을 만족하는 해 $\mathbf{x}(t)$를 구하는 것이다. 경계값 문제는 예컨대 구간 $\[a, b]$에서 $\mathbf{x}(a)$와 $\mathbf{x}(b)$가 주어지고, 상미분방정식

$$
\frac{d^2\mathbf{x}}{dt^2} = \mathbf{g}\bigl(t,\mathbf{x}(t),\frac{d\mathbf{x}}{dt}\bigr)
$$

을 만족하는 $\mathbf{x}(t)$를 찾는 식으로 설정되는 경우가 많다.

초기값 문제의 대표적 수치해법에는 오일러 방법(Euler’s method)이나 고차 정확도를 갖는 룽게-쿠타(Runge-Kutta) 계열 방법이 있다. 가장 간단한 오일러 전진법(explicit Euler)에서는

$$
\mathbf{x}\_{n+1} = \mathbf{x}\_n + h, \mathbf{f}\bigl(t\_n,\mathbf{x}\_n\bigr)
$$

형태로 해를 점진적으로 구한다. 여기서 $h$는 시간 스텝으로 작을수록 해의 정확도가 좋아지지만, 연산 비용이 커지며 수치오차 축적이나 강건(stability) 문제가 발생할 수 있다.

룽게-쿠타 방법은 중간 스테이지(stage)에서 다단계 평가를 통해 높은 차수의 정밀도를 얻는다. 예컨대 고전적 4차 룽게-쿠타(RK4)는 4번의 중간 평가로

$$
\mathbf{x}\_{n+1} = \mathbf{x}\_n + \frac{h}{6} \bigl(\mathbf{k}\_1 + 2\mathbf{k}\_2 + 2\mathbf{k}\_3 + \mathbf{k}\_4\bigr)
$$

로 $\mathbf{x}\_{n+1}$을 구하며, 각각의 $\mathbf{k}*i$는 $t\_n$과 $t*{n+1}$ 사이에서 $\mathbf{f}$를 평가한 결과로 구성된다. 경직성(stiffness) 문제처럼 미분방정식의 특정 계수가 매우 클 때는 명시적(explicit) 방법이 빠르게 발산하거나 비효율적일 수 있어, 반암시적(implicit) 방법인 뒤벼르기 오일러(backward Euler)나 BDF(Backward Differentiation Formula) 계열 등을 쓰기도 한다.

경계값 문제의 경우에는 차분 방정식으로 변환하여 연립방정식을 해석적으로 혹은 수치적으로 풀어나가거나, 사다리꼴 규칙을 확장한 형식의 알고리즘 등을 활용한다. 슈팅 방법(shooting method)은 초기값 문제 알고리즘을 변형한 예로서, 미지의 초기조건을 추정하고 BVP에서 요구하는 경계조건을 만족하도록 조정해 나가는 과정을 반복한다.

#### 편미분방정식(PDE)의 수치해법

편미분방정식(Partial Differential Equation)은 공간 변수와 시간 변수를 동시에 포함하는 복잡한 물리·수리 모델에 광범위하게 적용된다. 대표적으로 열전도 방정식(heat equation), 파동 방정식(wave equation), 라플라스 방정식(Laplace equation), 나비에-스토크스 방정식(Navier-Stokes equation) 등이 있다. PDE를 푸는 수치 기법은 크게 차분법(finite difference method), 유한요소법(finite element method), 유한체적법(finite volume method) 등으로 분류된다.

차분법은 격자(grid)나 망점(mesh) 위에서 도함수를 차분 근사로 표현한다. 예컨대 1차원 열 방정식

$$
\frac{\partial u}{\partial t} = \alpha \frac{\partial^2 u}{\partial x^2}
$$

에 대해, 공간축 $x$를 등간격 $\Delta x$로 나누고 시간축을 $\Delta t$로 이산화한 다음, 편도함수를 전방 혹은 중심 차분으로 근사하여 점진적으로 계산한다. 이때 수치 안정성(stability)을 위해서 쿠랑-프리드리히-류비 수(Courant-Friedrichs-Lewy, CFL 조건) 등이 중요하게 작용한다.

유한요소법은 물리적 영역을 삼각형, 사각형, 사면체 같은 요소로 분할하고, 각 요소 내에서 약화된 형태(weak form)의 변분 문제를 만족하는 기준 함수의 계수를 구한다. 다양하고 복잡한 지오메트리에도 대응하기 쉽고, 이론적으로 정교한 오차 분석이 가능하다는 장점이 있다. 라플라스나 푸아송(poisson) 방정식, 탄성체 문제, 구조 해석 등에서 널리 쓰인다.

유한체적법은 주로 유체역학 분야에서 보존 법칙을 처리하기 좋다. 이산화된 각 셀에서의 유량(flux)을 균형적으로 계산함으로써 물리적 보존 조건을 안정적으로 충족시킬 수 있다. 충격파나 접촉 불연속면이 발생하는 보존법칙형 PDE에 특히 유용하며, 고차 정확도 스킴(ENO, WENO 등)과 결합하여 경계층이나 급격한 변화 구간을 잘 처리하는 방식도 연구되어 있다.

#### 확률적 방법과 몬테카를로 시뮬레이션

해석해가 존재하더라도 수치 오차가 매우 커지거나, 고차원 문제로 직접 해법을 적용하기 곤란한 상황에서 몬테카를로(Monte Carlo) 기법을 활용한다. 몬테카를로 방법은 난수 샘플링을 통해 근사값을 얻는 방식으로, 고차원 적분이나 통계적 분포를 추정하는 문제에 자주 쓰인다. 대표적으로 몬테카를로 적분은

$$
\int\_{\Omega} f(\mathbf{x}) , d\mathbf{x} \approx \frac{1}{N}\sum\_{k=1}^N f(\mathbf{x}^{(k)})
$$

과 같은 형태로 난수 표본 $\mathbf{x}^{(k)}$를 충분히 많이 취해 통계적으로 접근한다. 차원이 매우 높거나 적분구간이 복잡할수록 전통적인 수치적분 기법과 비교해 상대적으로 장점을 갖는다. 베이즈 추론이나 확률적 최적화에도 몬테카를로 샘플링과 마르코프 연쇄 몬테카를로(MCMC) 기법 등이 적용된다.

#### 연산 복잡도와 오차 해석

수치해석 기법을 적용할 때, 관심 문제의 규모가 클수록 연산 복잡도와 메모리 부담이 매우 중요해진다. 예컨대 $n \times n$ 행렬에 대한 직접 해법은 이론적으로 $O(n^3)$ 정도의 연산량이 요구될 수 있으며, 반복법이나 특수 분해법을 통해 이를 줄이는 방향으로 최적화가 시도된다. 또, 적분이나 미분 방정식을 푸는 과정에서 $h \to 0$과 같이 스텝 크기를 줄일 때 오차가 줄어들지만, 부동소수점 연산 오차 역시 누적되므로 균형 잡힌 알고리즘 설계가 필요하다.

트렁케이션 오류(truncation error)와 반올림 오류(round-off error)는 수치해석 알고리즘 성능을 좌우하는 양대 요소다. 트렁케이션 오류는 이론적 수식에서 유도된 근사 과정 자체의 오류이며, 반올림 오류는 유한 정밀도를 갖는 컴퓨터 부동소수점 산술에서 발생한다. 이 두 요소가 결합하여 전체 오차가 특정 스케일에서 최소화되는 최적 스텝 크기를 결정할 수 있다.

#### 조건수와 문제의 민감도

행렬이나 연산자 등의 조건수(condition number)는 주어진 문제의 민감도를 나타내는 중요한 척도다. 예컨대 선형시스템 $\mathbf{A}\mathbf{x} = \mathbf{b}$에서 $|\Delta \mathbf{b}|$가 작게 변했을 때 $|\Delta \mathbf{x}|$가 크게 변한다면, 문제는 불안정적이라 볼 수 있다. 수학적으로는

$$
\kappa(\mathbf{A}) = |\mathbf{A}||\mathbf{A}^{-1}|
$$

와 같은 표준 정의를 사용하며, $\kappa(\mathbf{A})$ 값이 크면 문제(또는 행렬)가 ill-conditioned(조악조건)하다고 한다. 이 경우 수치 해법을 적용하면 반올림 오차가 증폭되어 실제 해와 크게 다른 결과를 낳을 수 있으므로, 축차적인 피벗팅, 정규방정식 대신 QR 분해를 이용한 최소제곱법, 프리컨디셔닝(preconditioning)을 통한 시스템 개선 등이 고려된다.

특히 반복 해법에서 프리컨디셔너(preconditioner) $\mathbf{M}^{-1}$를 도입하여

$$
\mathbf{M}^{-1}\mathbf{A}\mathbf{x} = \mathbf{M}^{-1}\mathbf{b}
$$

형태로 재구성하면, 새롭게 얻은 계수 행렬 $\mathbf{M}^{-1}\mathbf{A}$가 더 좋은 조건수를 갖도록 설계할 수 있다. 적절한 프리컨디셔닝은 반복 횟수를 크게 줄이고, 해를 빠르고 정확하게 구할 수 있는 기반이 된다.

#### 대규모 희소 시스템과 크릴로프(Krylov) 공간 방법

수치선형대수학에서 매우 큰 차원의 문제를 다룰 때, 대부분의 행렬 원소가 0에 가까운 희소(sparse) 구조를 갖는 상황이 흔하다. 이러한 경우, 희소성(sparsity)을 유지하며 연산량을 줄이는 특수 알고리즘이 필요하다. 반복 해법으로는 크릴로프(Krylov) 부분공간 기반 방법이 대표적이며, GMRES(Generalized Minimal Residual), CG(Conjugate Gradient), BiCGSTAB(Bi-Conjugate Gradient Stabilized) 등이 널리 쓰인다.

예컨대 GMRES는 잔차 벡터(residual vector)가 스팬(span)되는 크릴로프 공간에서 최적의 해를 찾아가는 방식으로, 불특정 계수 행렬(비대칭 포함)에 대해 수렴성이 잘 연구되어 있다. 다만 해를 갱신할수록 보관해야 하는 직교화 벡터들이 누적되어 메모리 비용이 증가하므로, restarted GMRES(예: GMRES(m)) 방식을 쓰기도 한다.

CG(Conjugate Gradient)는 대칭 양의 정부호 행렬(SPD)일 때 활용한다. 해당 조건에서 최적의 수렴 거동을 보이는 것이 이론적으로 증명되며, 프리컨디셔닝과 결합해 대규모 선형계 문제를 효과적으로 풀 수 있다. BiCGSTAB는 비대칭 행렬에 대하여 CG 계열의 장점을 계승하면서도 보다 안정된 수렴을 기대하게 설계되었다.

#### 병렬 계산과 고성능 수치해석

현대의 대규모 계산 문제는 단일 CPU 코어로 감당하기 어려워, 병렬(parallel) 및 분산(distributed) 환경에서 효율적으로 동작하는 알고리즘이 필수적이다. 메모리 접근 패턴, 통신 비용, 로드 밸런싱 등이 병렬 알고리즘 구현의 핵심 이슈다. 예컨대 대규모 지점으로 구성된 유한요소 해석(FEM)을 수행할 때, 영역 분할(domain decomposition) 방식으로 전체 영역을 여러 하위 영역으로 나눈 뒤, 각 영역을 독립적으로 계산하고 경계 부근에서 정보만 교환하는 전략을 쓴다.

수치해석 라이브러리도 MPI(Message Passing Interface), OpenMP, CUDA 등 다양한 병렬 프레임워크를 지원한다. 수치선형대수 전문 라이브러리(PETSc, Trilinos, Hypre 등)나 FFT 연산 최적화 라이브러리(FFTW, Intel MKL FFT 등), BLAS/LAPACK 계열의 고성능 라이브러리가 대표적이다. 이들은 벡터·행렬 연산에 대한 병렬화, 복잡한 데이터 구조 관리, 고차원 배열의 효율적 분산 등을 전문적으로 지원한다.

멀티코어 CPU, GPU, FPGA 등 하드웨어 구조에 맞게 알고리즘을 수정하거나 스레드 병렬화를 적용해야 최적의 성능을 이끌어낼 수 있다. 예컨대 GPU는 대량의 병렬 연산을 처리하는 데 유리하나, 전송 대역폭이나 메모리 구조가 일반 CPU와 달라 최적화를 위해 데이터 병목을 최소화하는 기법을 설계해야 한다.

#### 수치 소프트웨어 구현과 실제 이슈

알고리즘이 이론적으로는 수렴이 보장된다고 해도, 실제 코딩 구현 단계에서는 반올림 오차, 언더플로우·오버플로우, 정수 범위 초과, 메모리 누수, 비효율적 캐시 사용 등 다양한 오류나 성능 저하 요인이 잠재한다. 따라서 고급 프로그래밍 기법과 디버깅, 프로파일링(profiling), 단정도·배정도 부동소수점 활용에 대한 이해가 필수다.

대규모 행렬 연산은 BLAS 레벨3 같은 고성능 루틴으로 처리하는 것이 일반적이며, 경우에 따라서는 행렬 구조에 최적화된 포맷(CSR, COO 등)으로 변환해 희소 벡터·행렬 연산을 가속한다. 파이썬과 같은 언어에서는 NumPy, SciPy, CuPy(또는 PyTorch, TensorFlow 등의 백엔드 활용) 등을 사용하여 벡터화 연산을 극대화한다.

언어 수준에서 C++(특히 템플릿 메타프로그래밍), Fortran(고전적 과학 계산), Julia(동적이지만 빠른 수치 해석), Rust(안전성 강조) 등 다양한 선택지가 존재하며, 각 언어는 메모리 모델·타입 안전성·컴파일러 최적화 등 측면에서 장단점을 갖는다. 실제 대규모 프로젝트에서는 다중 언어 결합, 라이브러리 호환성, 버전 관리, 재현성(reproducibility)을 고려하는 것도 중요하다.
