본문으로 건너뛰기
김신건의 로그

Markov Chain: 상태 전이 확률

· 수정 · 📖 약 3분 · 1,096자/단어 #algorithm #foundation #probability #markov
Markov Chain, 마르코프 체인, transition matrix

정의

Markov Chain다음 상태가 오직 현재 상태에만 의존하는 확률 과정. Memoryless property (Markov property).

전이 행렬 (Transition Matrix) : . 각 행의 합 = 1 (확률 보존).

문제 상황과 동기

전형적인 PS 문제 패턴:

  • “N 번 이동 후 위치 j 에 있을 확률” → 전이 행렬 거듭제곱
  • “장기적으로 각 상태에 있는 비율” → 정류 분포
  • “이 게임에서 파산할 확률” → Gambler’s ruin

시각화

날씨 예측 마르코프 체인

stateDiagram-v2
    Sunny --> Sunny : 0.8
    Sunny --> Cloudy : 0.2
    Cloudy --> Sunny : 0.4
    Cloudy --> Cloudy : 0.6

Sunny = 맑음, Cloudy = 흐림. 전이 행렬:

P = \begin\{pmatrix\} 0.8 & 0.2 \\ 0.4 & 0.6 \end\{pmatrix\}

N-step 전이 흐름

flowchart LR
    V0["초기 분포 v0"] -->|"곱하기 P"| V1["1-step 분포 v1"]
    V1 -->|"곱하기 P"| V2["2-step 분포 v2"]
    V2 -->|"..."| Vn["n-step: v0 * P의 n제곱"]

의 j 번째 원소 = 초기 분포 에서 출발해 n 스텝 후 상태 j 에 있을 확률.

핵심 아이디어

행렬 거듭제곱 (N-step 전이)

= i 에서 j 로 n 스텝에 도달할 확률.

Matrix Exponentiation 으로 O(K^3 log N) 에 계산. K = 상태 수.

Stationary Distribution

를 만족하는 확률벡터 (원소 합 = 1).

Ergodic 마르코프 체인 (irreducible + aperiodic) 이면 유일한 정류 분포 존재, 어떤 초기 분포에서도 수렴.

풀이: 에서 마지막 방정식을 로 교체 후 선형계 풀기.

Gambler’s Ruin

가진 돈 i, 목표 N, 매 라운드 이길 확률 p:

해 ():

카지노에서 p = 49% 이더라도 목표가 크면 파산 확률이 압도적으로 높은 이유.

알고리즘

N-step 전이

P = K x K 전이 행렬
Pn = matrix_power(P, n)
answer = Pn[start][end]

정류 분포 (Power Iteration)

pi = [1/K, 1/K, ..., 1/K]  # 균등 초기
for t in 1..T:
    pi = pi * P             # 행벡터 x 행렬
# 수렴 후 pi = 정류 분포

수렴 속도 = 두 번째로 큰 고유값의 절댓값 (spectral gap).

PageRank

  • 각 웹 페이지 = 상태, 하이퍼링크 = 전이
  • 댐핑 인수 d = 0.85:
  • Stationary distribution of P’ = PageRank score

구현

// Markov Chain: 행렬 거듭제곱 + 정류 분포
#include <bits/stdc++.h>
using namespace std;
using Matrix = vector<vector<double>>;

int K;

Matrix mat_mul(const Matrix& A, const Matrix& B) {
  Matrix C(K, vector<double>(K, 0));
  for (int i = 0; i < K; i++)
      for (int k = 0; k < K; k++)
          for (int j = 0; j < K; j++)
              C[i][j] += A[i][k] * B[k][j];
  return C;
}

Matrix mat_pow(Matrix M, long long n) {
  Matrix R(K, vector<double>(K, 0));
  for (int i = 0; i < K; i++) R[i][i] = 1.0;  // 단위 행렬
  while (n > 0) {
      if (n & 1) R = mat_mul(R, M);
      M = mat_mul(M, M);
      n >>= 1;
  }
  return R;
}

int main() {
  // 날씨: 0=맑음, 1=흐림
  K = 2;
  Matrix P = {{0.8, 0.2}, {0.4, 0.6}};

  // N-step 전이
  long long n = 10;
  Matrix Pn = mat_pow(P, n);
  cout << "맑음 시작, " << n << "일 후:\n";
  printf("  맑음 확률: %.4f\n", Pn[0][0]);
  printf("  흐림 확률: %.4f\n", Pn[0][1]);

  // 정류 분포 (Power iteration)
  vector<double> pi(K, 1.0 / K);
  for (int t = 0; t < 1000; t++) {
      vector<double> npi(K, 0);
      for (int i = 0; i < K; i++)
          for (int j = 0; j < K; j++)
              npi[j] += pi[i] * P[i][j];
      pi = npi;
  }
  printf("정류 분포: 맑음=%.4f, 흐림=%.4f\n", pi[0], pi[1]);
  // 정류 분포: 맑음=0.6667, 흐림=0.3333
  // 이론값: pi0 = 0.4/(0.2+0.4) = 2/3
}
stdin
P=[[0.8,0.2],[0.4,0.6]], start=맑음, n=10
결과
맑음 확률: 0.6667, 흐림 확률: 0.3333

복잡도

항목
N-step 계산O(K^3 log N)
Power Iteration 수렴O(K^2 x T)
고유벡터법O(K^3)
공간O(K^2)

K = 상태 수. K 가 크면 희소 행렬 표현 + Power Iteration.

응용

MCMC (Markov Chain Monte Carlo)

복잡한 분포에서 직접 샘플링 불가능할 때, 해당 분포를 정류 분포로 갖는 마르코프 체인 구성 후 충분히 진행해 샘플 획득.

  • Metropolis-Hastings: 제안 분포 q, 수용 확률
  • Gibbs Sampling: 각 변수를 조건부 분포에서 순서대로 샘플링

랜덤 워크

무방향 그래프에서 각 정점의 방문 비율 = degree / (2E). 정류 분포로 분석.

함정

1. 전이 행렬 방향

행 합 = 1 (행이 현재 상태). 열 합 = 1 로 착각하면 전치 행렬 사용 오류.

2. Reducible vs Irreducible

일부 상태 간 도달 불가능하면 reducible. 정류 분포가 유일하지 않을 수 있음.

3. Periodic 체인

주기 d > 1 이면 수렴 안 하고 진동. 자가 루프 추가로 aperiodic 만들기 가능.

4. 부동소수점 누적 오차

행렬 거듭제곱 반복 시 확률 합이 1 에서 벗어남. 주기적으로 정규화하거나 분수 표현 사용.

5. PS 에서 정수형 행렬

확률 문제를 분수/유리수로 처리하면 정밀도 보장. 모듈러 산술과 결합 가능.

BOJ 연습 문제

번호제목정답률링크
BOJ 10830행렬 제곱47.3%kokoa-lab
BOJ 11444피보나치 수 651.2%kokoa-lab
BOJ 2749피보나치 수 350.0%kokoa-lab
BOJ 13252인터넷32.1%kokoa-lab

참고

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기