๋์ ๊ณํ๋ฒ(Dynamic Programming)์
์ฌ์ฉํ ์ ์๋ ์๊ณ ๋ฆฌ์ฆ ๊ธฐ๋ฒ์ด๋ค.
์์๋ก, ํผ๋ณด๋์น ์์ด์ ์ฌ๊ท์ DP๋ก ๊ตฌํ๋ ๋ฐฉ์์ ๋น๊ตํด๋ณด์.
import time
#์ฌ๊ท ํจ์
def Fibonacci(n):
if n == 1 or n == 2:
return 1
else:
return Fibonacci(n-1) + Fibonacci(n-2)
n = 40
startTime = time.time()
result = Fibonacci(n)
endTime = time.time()
timeRecursive = endTime - startTime
print(f"Fibonacci({n}) ๊ณ์ฐ ๊ฒฐ๊ณผ")
print(f"๊ฐ : {result} / ์คํ ์๊ฐ {timeRecursive}์ด")
Fibonacci(40) ๊ณ์ฐ ๊ฒฐ๊ณผ
๊ฐ : 102334155 / ์คํ ์๊ฐ 29.934786319732666์ดO(2^n)
์ด ์ฌ๊ทํจ์๊ฐ ์คํ๋๋ ๊ณผ์ ์ ์ดํด๋ณด๋ฉด, ๋์ผํ ๊ณผ์ ์ ๋ฐ๋ณตํ๋ค๋ ๊ฒ์ ์ ์ ์๋ค. ์ด๋ก ์ธํด ์คํ๊ณผ์ ์ด ์ค๋ ๊ฑธ๋ฆฌ๊ฒ ๋๋ค.
๊ทธ๋ฐ๋ฐ ์ด ๊ณผ์ ์ ์ ์ดํด๋ณด๋
(sub-problem)๊ฐ ์ค์ฒฉ๋๊ณ ex) Fibo(n-k)๊ฐ ๋ฐ๋ณต๋จex) Fibo(n) = Fibo(n-1) + Fibo(n-2)์ฆ ์ด ๋ฌธ์ ๋ DP๋ก ํด๊ฒฐํ ์ ์๋ค.
์ด์ ํผ๋ณด๋์น ์์ด์ DP๋ก ํด๊ฒฐํด๋ณด์.
import time
# ๋์ ๊ณํ๋ฒ
def Fibonacci_DP(n):
if n == 1 or n == 2:
return 1
fibo = [0 for _ in range(n+1)]
fibo[1], fibo[2] = 1, 1
for i in range(3, n+1):
fibo[i] = fibo[i-1] + fibo[i-2]
return fibo[n]
n = 10000
startTime = time.time()
result = Fibonacci_DP(n)
endTime = time.time()
timeDP = endTime - startTime
print(f"Fibonacci({n}) ๊ณ์ฐ ๊ฒฐ๊ณผ")
print(f"๊ฐ : {result} / ์คํ ์๊ฐ {timeDP}์ด")
Fibonacci(10000) ๊ณ์ฐ ๊ฒฐ๊ณผ
๊ฐ : 33644764876...(์๋ต) / ์คํ ์๊ฐ 0.00937342643737793์ด
O(n)์ฌ๊ท์ DP์ ์คํ ์๊ฐ์ ๋น๊ตํด๋ณด๋ฉด, DP๋ฐฉ์์ด ์ฌ๊ท๋ฐฉ์๋ณด๋ค ๋งค์ฐ ๋น ๋ฅธ ๊ฒ์ ์ ์ ์๋ค.
๋ฐฉ๊ธ ์ ๋ฌธ์ ์ ๊ฒฝ์ฐ, ๋ฐํ
์
(Bottom-Up) ์ ๊ทผ ๋ฐฉ์์ ํตํด ๋ฌธ์ ๋ฅผ ํ์๋ค.
DP๋ ์ฃผ๋ก ํ๋ค์ด(Top-Down)๊ณผ ๋ฐํ
์
(Bottom-Up) ์ ๊ทผ๋ฐฉ์์ ํตํด์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค.
ํ๋ค์ด์ ์์์๋ถํฐ ์๋๋ก, ์ฆ ํฐ ๋ฌธ์ ์์ ์์ํด์ ํ์ํ ํ์๋ฌธ์ ์ ํด๋ฅผ ๊ตฌํด๊ฐ๋ ๋ฐฉ์์ด๋ค.
ํ๋ค์ด ๋ฐฉ์์ ๊ฒฝ์ฐ, ์ฌ๊ท์ ๋ฉ๋ชจ์ ์ด์
(Memoization)์ ํ์ฉํ๋ค.
๋ฉ๋ชจ์ ์ด์
(Memoization): ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๊ณผ์ ์์ ์ด๋ฏธ ๊ณ์ฐํ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํด์ ์ค๋ณต ๊ณ์ฐ์ ๋ฐฉ์งํ๋ ๊ธฐ๋ฒ ์ค ํ๋
- ํ๋ค์ด์ ์ ๊ทผ ๋ฐฉ์
- ์ฌ๊ท ํจ์๋ฅผ ํตํด ๊ตฌํ๋๋ค.
- ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ฉฐ ํ์ํ ๋ถ๋ถ ๋ฌธ์ ๋ง ๊ณ์ฐ๋์ด ์ ์ฅ๋๋ค.
์์ ํ์ด๋ณธ ํผ๋ณด๋์น ์์ด์ ํ๋ค์ด ๋ฐฉ์์ผ๋ก ๊ตฌํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํํ ์ ์๋ค.
# ๋์ ๊ณํ๋ฒ (ํ๋ค์ด)
def Fibonacci_DP(n, memo = {}):
if n in memo:
return memo[n]
if n <= 1:
return n
memo[n] = Fibonacci_DP(n-1, memo) + Fibonacci_DP(n-2, memo)
return memo[n]
print(Fibonacci_DP(20)) # ์ถ๋ ฅ 6765
Fibonacci_DP ํจ์๋ฅผ ํตํด์ ์์์๋ถํฐ ์ฌ๊ท์ ์ผ๋ก ์์ด์ ๊ณ์ฐํ๋ฉด์, ๊ณ์ฐ๋ ๊ฒฐ๊ณผ๋ memo ๋์
๋๋ฆฌ์ ์ ์ฅํ๋ฉฐ ์ค๋ณต ๊ณ์ฐ์ ํผํ๊ณ ์๋ค.
๋ฐํ ์ ์ ์๋์์๋ถํฐ ์๋ก, ์ฆ ์์ ํ์๋ฌธ์ ์์ ์์ํด ๋ ํฐ ๋ฌธ์ ์ ํด๋ฅผ ๊ตฌ์ฑํ๋ ๋ฐฉ์์ด๋ค.
๋ฐํ
์
๋ฐฉ์์ ๊ฒฝ์ฐ, ๋ฐ๋ณต๋ฌธ๊ณผ ํ๋ทธ๋ ์ด์
(Tabulation)์ ํ์ฉํ๋ค.
ํ๋ทธ๋ ์ด์
(Tabulation): ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๊ณผ์ ์์ ์ด๋ฏธ ๊ณ์ฐํ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํด์ ์ค๋ณต ๊ณ์ฐ์ ๋ฐฉ์งํ๋ ๊ธฐ๋ฒ ์ค ํ๋
- ๋ฐํ ์ ์ ์ ๊ทผ ๋ฐฉ์
- ๋ฐ๋ณต๋ฌธ์ ํตํด ๊ตฌํ๋๋ค.
- ๋ชจ๋ ๋ถ๋ถ ๋ฌธ์ ๋ฅผ ๊ณ์ฐํด์ ์์ ๊ฒ๋ถํฐ ์์ฐจ์ ์ผ๋ก ์ ์ฅํ๋ค.
์์ ๊ตฌํํ ์ฝ๋๋ฅผ ๋ค์ ์ดํด๋ณด์.
# ๋์ ๊ณํ๋ฒ (๋ฐํ
์
)
def Fibonacci_DP(n):
if n == 1 or n == 2:
return 1
fibo = [0 for _ in range(n+1)]
fibo[1], fibo[2] = 1, 1
for i in range(3, n+1):
fibo[i] = fibo[i-1] + fibo[i-2]
return fibo[n]
print(Fibonacci_DP(20)) # ์ถ๋ ฅ 6765
Fibonacci_DP ํจ์ ๋ด์์ fibo๋ฆฌ์คํธ์ ์ธ๋ฑ์ค๊ฐ 1๊ณผ 2์ผ ๋ ๊ฐ์ 1๋ก ์ด๊ธฐํํ๋ค. (๊ธฐ์ ์กฐ๊ฑด(Base Case))
๊ทธ๋ฆฌ๊ณ ๋ฐ๋ณต๋ฌธ์ ํตํด 3์์ n๊น์ง ์์ฐจ์ ์ผ๋ก ์์ด์ ๊ณ์ฐํ๊ณ fibo๋ฆฌ์คํธ์ ์ ์ฅํ๋ค.
| ํญ๋ชฉ | ํ๋ค์ด(Top-Down) | ๋ฐํ ์ (Bottom-Up) |
|---|---|---|
| ๊ตฌํ ๋ฐฉ์ | ์ฌ๊ท์ ๋ฉ๋ชจ์ด์ ์ด์ | ๋ฐ๋ณต๋ฌธ๊ณผ ํ๋ทธ๋ ์ด์ (ํน์ ํ ์ด๋ธ) |
| ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ | ์ฌ๊ท ํธ์ถ ์คํ + ์บ์ | ํ ์ด๋ธ์ ๋ชจ๋ ๋ถ๋ถ ๋ฌธ์ ๊ฒฐ๊ณผ ์ ์ฅ |
| ์ฝ๋ ๋ณต์ก๋ | ์ฌ๊ท ํจ์ ์ฌ์ฉ์ผ๋ก ์ฝ๋๊ฐ ๊ฐ๊ฒฐํ ์ ์์ | ๋ฐ๋ณต๋ฌธ๊ณผ ํ ์ด๋ธ ์ด๊ธฐํ ๋ฑ์ผ๋ก ๋ค์ ๋ณต์กํ ์ ์์ |
| ๊ณ์ฐ ์์ | ํ์ํ ๋ถ๋ถ ๋ฌธ์ ๋ถํฐ ์ฌ๊ท์ ์ผ๋ก ๊ณ์ฐ | ์์ ๋ฌธ์ ๋ถํฐ ์์ฐจ์ ์ผ๋ก ๊ณ์ฐ |
ํ ์ด๋ธ
(table): ๋ฐ์ดํฐ๋ฅผ ๊ตฌ์กฐํํ์ฌ ์ ์ฅํ๊ณ , ํจ์จ์ ์ผ๋ก ๊ฒ์ํ๊ฑฐ๋ ์ฐธ์กฐํ ์ ์๋๋ก ๋ง๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ก,
์ฌ๊ธฐ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ถ๋ถ ๋ฌธ์ ์ ํด๋ต์ ์ ์ฅํ๋ ๋ฐฐ์ด ๋๋ ๋ฆฌ์คํธ๋ฅผ ์๋ฏธํ๋ค.
์บ์
(cache): ๋ฐ์ดํฐ๋ ๊ณ์ฐ ๊ฒฐ๊ณผ๋ฅผ ์์๋ก ์ ์ฅํด ๋์๋ค๊ฐ ํ์ํ ๋ ๋น ๋ฅด๊ฒ ๊บผ๋ด ์ฐ๋ ์ ์ฅ์๋ฅผ ์๋ฏธํ๋ค.
๋ฌธ์ ๋ฅผ ํ์๋ฌธ์ ๋ก ์ชผ๊ฐ๊ณ , ๊ทธ ํ์๋ฌธ์ ์ ๋ถ๋ถํด๋ฅผ ํตํด์ ์ ์ฒด ๋ฌธ์ ์ ํด๋ฅผ ๊ตฌํ๋ค๋ ์ธก๋ฉด์์ ๋ถํ ์ ๋ณต(Divide and Conquer)๊ณผ ๋์ ๊ณํ๋ฒ(Dynamic Programming)์ ๋์ผํ๊ฒ ๋ณด์ด๊ธฐ๋ ํ๋ค.
ํ์ง๋ง ์ ๊ทผ ๋ฐฉ์๊ณผ ์ ์ฉ๋๋ ๋ฌธ์ ์ ํน์ฑ์์ ๋์ ๋ช ๊ฐ์ง ์ค์ํ ์ฐจ์ด์ ์ด ์๋ค.

divede ์คํ๋ฌ๋ค.
๋ถํ ์ ๋ณต(Divide and Conquer)
์์ : ๋ณํฉ ์ ๋ ฌ
(Merge Sort), ํต ์ ๋ ฌ(Quick Sort), ์ด์ง ํ์(Binary Search)
๋์ ๊ณํ๋ฒ(Dynamic Programming)
์์ : ํผ๋ณด๋์น ์์ด, LCS(์ต์ฅ ๊ณตํต ๋ถ๋ถ ์์ด), ๋ง๋ ์๋ฅด๊ธฐ ๋ฌธ์
๋์ ๊ณํ๋ฒ์ ์ด๋ฆ์ ๋ณด๋ฉด ๋์ (dynamic)์ด๋ผ๋ ๋ง์ด ๋ถ์ด์๋๋ฐ, ์์ ์ดํด๋ณธ ๊ฒ์ฒ๋ผ, ์ฌ์ค ์ด ๊ธฐ๋ฒ์ ๋์ ๊ณผ๋ ๊ฑฐ๋ฆฌ๊ฐ ๋ฉ๋ค.
๊ทธ๋ฐ๋ฐ๋ ์ด๋ฆ์ด ์ด๋ฐ ์ด์ ๋, ๋์ ๊ณํ๋ฒ์ ๊ณ ์์๊ฐ dynamic์ด๋ ์ด๋ฆ์ด ๋ฉ์ ธ๋ณด์ฌ์ ๋ถ์๊ธฐ์ ์ด๋ฐ ์ด๋ฆ์ผ๋ก ์ ํด์ง๊ฒ ๋์๋ค.