dynamic_programming

Dynamic programming

컴퓨터λ₯Ό μ΄μš©ν•΄λ„ μ‹œκ°„μ΄ 맀우 많이 ν•„μš”ν•˜κ±°λ‚˜ λ©”λͺ¨λ¦¬ 곡간이 맀우 많이 ν•„μš”ν•˜λ©΄ ν•΄κ²°ν•˜κΈ° μ–΄λ ΅λ‹€.

λ©”λͺ¨λ¦¬ 곡간을 μ•½κ°„ 더 μ‚¬μš©ν•˜λ©΄, μ—°μ‚° 속도λ₯Ό λΉ„μ•½μ μœΌλ‘œ μ¦κ°€μ‹œν‚¬ 수 있고, λŒ€ν‘œμ μΈ λ°©λ²•μœΌλ‘œ λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž˜λ° 기법. 동적 κ³„νšλ²•μ΄λ‹€.

  • λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž˜λ°κ³Ό 동적 ν• λ‹Ήμ˜ λ‹€μ΄λ‚˜λ―Ήμ€ 같은 의미일까?

    Dynamic: 
        ν”„λ‘œκ·Έλž¨μ΄ μ‹€ν–‰λ˜λŠ” 도쀑에
    
    ex) μžλ£Œκ΅¬μ‘°μ—μ„œ 동적할당 (Dynamic Allocation) 은 ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ 쀑 ν”„λ‘œκ·Έλž¨μ— ν•„μš”ν•œ λ©”λͺ¨λ¦¬λ₯Ό ν• λ‹Ήν•˜λŠ” 기법.

λ‹€μ΄λ‚˜λ―Ή μ‚¬μš©μ‘°κ±΄

  1. 큰 문제λ₯Ό μž‘μ€ 문제둜 λ‚˜λˆŒ 수 μžˆλ‹€.

  2. μž‘μ€ λ¬Έμ œμ—μ„œ κ΅¬ν•œ 정닡은 그것을 ν¬ν•¨ν•˜λŠ” 큰 λ¬Έμ œμ—μ„œλ„ λ™μΌν•˜λ‹€.

  3. μœ„ 쑰건을 λ§Œμ‘±ν•˜λŠ” λŒ€ν‘œ 문제: ν”Όλ³΄λ‚˜μΉ˜

    def fibo(n):
      if n == 1 or 2:
        return 1
      return fibo(n - 1) + fibo(n - 2)
    • O(2^N) 의 계산 λ³΅μž‘λ„λ₯Ό κ°€μ Έ 100 만 λ˜λ”λΌλ„ μˆ˜λ°±μ–΅λ…„μ΄ κ±Έλ¦°λ‹€.

Memoization (Top - Down)

λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž˜λ°μ„ κ΅¬ν˜„ν•˜λŠ” 방법 쀑 ν•œ μ’…λ₯˜. ν•œ 번 κ³„μ‚°ν•œ κ²°κ³Όλ₯Ό μ–΄λ”˜κ°€μ— λ‹΄μ•„λ‘λŠ” 것을 의미

ν•œ 번 κ΅¬ν•œ κ²°κ³Όλ₯Ό λ©”λͺ¨λ¦¬ 곡간에 λ©”λͺ¨ν•΄λ‘κ³  같은 식을 λ‹€μ‹œ ν˜ΈμΆœν•˜λ©΄ λ©”λͺ¨ν•œ κ²°κ³Όλ₯Ό κ·ΈλŒ€λ‘œ κ°€μ Έμ˜΄

캐싱 (Caching) 이라고도 함

  • Implementation

    • ν•œ 번 κ΅¬ν•œ 정보λ₯Ό λ¦¬μŠ€νŠΈμ— μ €μž₯. μž¬κ·€μ μœΌλ‘œ μˆ˜ν–‰ν•˜λ‹€κ°€ 같은 정보가 ν•„μš”ν•  λ•Œ 이미 κ΅¬ν•œ 정닡을 λ¦¬μŠ€νŠΈμ—μ„œ κ°€μ Έμ˜΄

      큰 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ μž‘μ€ 문제λ₯Ό 호좜

  • λ•Œμ— λ”°λΌμ„œ λ‹€λ₯Έ μžλ£Œν˜•, 예λ₯Ό λ“€μ–΄ 사전(dict) μžλ£Œν˜•μ„ μ΄μš©ν•  μˆ˜λ„ μžˆλ‹€. μˆ˜μ—΄μ²˜λŸΌ 연속적이지 μ•Šμ€ 경우 μœ μš©ν•¨.

Bottom - Up

λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž˜λ°μ˜ μ „ν˜•μ μΈ ν˜•νƒœ

λ°˜λ³΅λ¬Έμ„ μ΄μš©ν•΄ μž‘μ€ λ¬Έμ œλΆ€ν„° μ°¨κ·Όμ°¨κ·Ό 닡을 λ„μΆœ

LIS (κ°€μž₯ κΈ΄ μ¦κ°€ν•˜λŠ” λΆ€λΆ„ μˆ˜μ—΄)

D[i]: a[i] 둜 λλ‚˜λŠ” κ°€μž₯ κΈ΄ μˆ˜μ—΄

LCS (졜μž₯ 곡톡 λΆ€λΆ„ λ¬Έμžμ—΄)

ν•œ λ¬Έμžμ—΄μ„ κΈ°μ€€μœΌλ‘œ ν•˜λ‚˜μ”© ν•΄λ‚˜κ°

  1. String1[i] == String2[j] 라면 [i, j] = [i - 1, j - 1] + 1

  2. String1[i] != String2[j] 라면 [i, j] = [i - 1, j] 와 [i, j - 1] 쀑 큰 것

Knapsack Problem

2차원 DP 둜 λ§€ μˆœκ°„ λ“€μ–΄μ˜€λŠ” 물건에 따라 μƒˆλ‘œμš΄ 행을 μ±„μ›Œλ‚˜κ°€λ³΄μž

νŽΈμ§‘κ±°λ¦¬

λΈ”λ‘œκ·Έarrow-up-right

etc

  • λŒ€λΆ€λΆ„ DP 핡심은, λ§€ λ²ˆλ§ˆλ‹€ μ΅œμ„ μ˜κ²ƒ 을 νƒν•΄κ°€λŠ” κ²ƒμ΄λ‹ˆ λΉ„κ΅λŒ€μƒ 을 잘 κ²€μ¦ν•˜μž

    • μž‘μ€ 경우의 μ–΄λ–€ ν•΄κ°€ μ μš©λ˜λŠ”μ§€ 잘 보자

  • DP ν…Œμ΄λΈ”

    • ν…Œμ΄λΈ”μ„ μ–΄λ–»κ²Œ ꡬ성할지, λͺ‡ 차원

    • ν–‰, 열은 μ–΄λ–»κ²Œ μ •ν• μ§€

    • μ΄μ „μ˜ 값을 μ–΄λ–»κ²Œ μ°Έκ³ ν•΄μ„œ ν˜„μž¬κ°’μ„ κ²°μ •ν•˜λŠ”μ§€

  • μ½”ν…Œμ—μ„œ λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž˜λ°μ€ λŒ€μ²΄λ‘œ κ°„λ‹¨ν•œ ν˜•νƒœλ‘œ μΆœμ œλœλ‹€.

  • μ£Όμ–΄μ§„ λ¬Έμ œκ°€ λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž˜λ° μœ ν˜•μΈμ§€ νŒŒμ•…ν•˜μž

    • λ¬Έμ œμ—μ„œ μž‘μ€ 문제의 정닡이 이 μž‘μ€ 문제λ₯Ό ν¬ν•¨ν•˜λŠ” 큰 λ¬Έμ œμ—μ„œλ„ λ™μΌν•œ 것인지 νŒŒμ•…μ΄ μ€‘μš”

    • 근데 이건 λ³΄ν…€μ—…λ°©μ‹μœΌλ‘œ 0, 1, 2 λ₯Ό ν•˜λ‹€λ³΄λ©΄ κ·œμΉ™μ΄ 보이고, μ€‘λ³΅λ˜λŠ”κ±Έ 사전에 λ°©μ§€ν•˜κΈ° 손쉽닀.

  • 일단 μž¬κ·€ν•¨μˆ˜λ‘œ μž‘μ„±ν•˜κ³ , μž‘μ€ λ¬Έμ œμ—μ„œ κ΅¬ν•œ 닡이 큰 λ¬Έμ œμ—μ„œ κ·ΈλŒ€λ‘œ μ‚¬μš©λœλ‹€λ©΄ λ©”λͺ¨μ΄μ œμ΄μ…˜μ„ ν™œμš©

  • κ°€λŠ₯ν•˜λ‹€λ©΄ 보텀업 방식을 ꢌμž₯

    • recursion depth 였λ₯˜κ°€ λ‚  수 μžˆλ‹€

      • Sys.setrecursionlimit() λ§€μ„œλ“œ ν˜ΈμΆœν•˜μ—¬ μ™„ν™”ν•  수 있음

Last updated