Dynamic Programming (๋์ ๊ณํ๋ฒ)
๋์ ๊ณํ๋ฒ(๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ) ์ด๋, ๋ณต์กํ ๋ฌธ์ ๋ฅผ ๊ฐ๋จํ ์ฌ๋ฌ ๊ฐ์ ๋ฌธ์ ๋ก ๋๋์ด ํธ๋ ๋ฐฉ๋ฒ์ ๋งํ๋ค. ์ด๊ฒ์ ๋ถ๋ถ ๋ฌธ์ ๋ฐ๋ณต๊ณผ ์ต์ ๋ถ๋ถ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ณ ์๋ ์๊ณ ๋ฆฌ์ฆ์ ์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ์ ๋นํด ๋์ฑ ์ ์ ์๊ฐ์ ๋ด์ด ํ ๋ ์ฌ์ฉํ๋ค. - Wikipedia
โท ์ฝ๋ฉํ ์คํธ์์์ DP
์ฝ๋ฉํ ์คํธ์ ๋จ๊ณจ ๋ฌธ์ ๋ก ์ถ์ ๋๊ณ ์๊ธฐ์ ํ์์ ์ผ๋ก ์์์ผํ๋ ๊ฐ๋ ์ค ํ๋์ด๋ค. ๊ฐํน ์ ์ฝ์ฌํญ์ ์ฃผ์ด์ง๋ ์ซ์์ ๋ฒ์๊ฐ ํฌ๊ณ , ๊ฒฝ์ฐ์ ์๊ฐ ์์ฒญ ๋ง์ ๋ฌธ์ ๋ค์ด ๋๋ถ๋ถ DP(๋์ ๊ณํ๋ฒ) ์ ํ์ฉํ์ฌ ํ์ด์ผ ํ๋ ๋ฌธ์ ์ด๋ค.
Dynamic Programming (๋์ ๊ณํ๋ฒ) ๋ฐฉ๋ฒ
๋ชจ๋ ์์ ๋ฌธ์ ๋ค์ ํ ๋ฒ๋ง ํ์ด์ผ ํ๋ค. ๋ฐ๋ผ์ ์ ๋ต์ ๊ตฌํ ์์ ๋ฌธ์ ์ ๋ต์ ์ด๋๊ฐ์ ๋ฉ๋ชจํด๋๋๋ค. ๋ค์ ๊ทธ ๋ณด๋ค ํฐ ๋ฌธ์ ๋ฅผ ํ์ด๋๊ฐ ๋, ๋๊ฐ์ ์์ ๋ฌธ์ ๊ฐ ๋ํ๋๋ฉด ์์ ๋ฉ๋ชจํ ์์ ๋ฌธ์ ์ ๋ํ ๊ฒฐ๊ณผ๊ฐ์ ์ด์ฉํ๋ ๊ฒ์ด DP ์ด๋ค.
์ฆ, ์ํฅ์ ์ ๊ทผ๋ฒ์ผ๋ก, ๊ฐ์ฅ ์์ ๋ถ๋ถ์ ํด๋ต์ ๊ตฌํ ๋ค ์ด๋ฅผ ์ ์ฅํ๊ณ , ์ ์ฅํ ๊ฐ์ ์ด์ฉํ์ฌ ์์ ๋ฌธ์ ๋ฅผ ํ์ด๊ฐ๋ ๋ฐฉ์์ด๋ผ๊ณ ํ๋ฉด ๋๊ฒ ๋ค. ์ด๋ ๋์ ๊ณํ์ ํต์ฌ์ Memoization(๋ฉ๋ชจ์ด์ ์ด์ ) ์ด๋ผ๋ ๊ธฐ๋ฒ์ธ๋ฐ, ์ด์ ๋ํ ๋ด์ฉ์ ์๋์ ๋ค๋ค๋ณด์.
Dynamic Programming (๋์ ๊ณํ๋ฒ) ์กฐ๊ฑด
๋์ ๊ณํ๋ฒ์ ์ ์ฉํ๊ธฐ ์ํด์๋ ์ ์ ์์์ ๋ณธ ๊ฒ์ฒ๋ผ, ๋ ๊ฐ์ง ์์ฑ์ ๋ง์กฑ์์ผ์ผ ํ๋ค.
- ๋ถ๋ถ ๋ฐ๋ณต ๋ฌธ์ (Overlapping Subproblem)
- ์ต์ ๋ถ๋ถ ๊ตฌ์กฐ (Optimal Substructure)
โถ ๋ถ๋ถ ๋ฐ๋ณต ๋ฌธ์ (Overlapping Subproblem)
๋์ ๊ณํ๋ฒ์ ๋ฑ์ฅ์ ํผ๋ณด๋์น ์์ด์ด๋ผ๊ณ ํ๋ค. ํผ๋ณด๋์น ์์ด์ ๋ํ์ ์ธ ์ฌ๊ทํจ์๋ก, ์๋์ ๊ฐ์ด ํํํ ์ ์๋ค.
func fibo(_ n: Int) -> {
if n <= 1 { return n }
return fibo(n - 1) + fibo (n - 2)
}
๋ง์ฝ fibo(7) ์ ๊ตฌํ๋ ๊ณผ์ ์ ๋์ํ ํด๋ณด๋ฉด, ์๋ ์ด์ง ํธ๋ฆฌ์ ๊ฐ๋ค.
7๋ฒ์งธ ๊ฐ์ ๊ตฌํ๊ธฐ ์ํด์๋ ์ด 25๋ฒ์ ํจ์๊ฐ ํธ์ถ๋๋ค๋ ๊ฒ์ ์ ์ ์๋ค. ์ด ๊ณผ์ ์์ fibo(5), fibo(4), fibo(3)๋ค์ด ์ด๋ฏธ ์งํํ๋ ์ฐ์ฐ์์๋ ๋ถ๊ตฌํ๊ณ ์ฌ๊ท๋๋ฉฐ ๋ฐ๋ณต์ ์ผ๋ก ์ฐ์ฐํ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
์ด๋ฌํ ๋ฐ๋ณต์ ์ธ ์ฐ์ฐ์ ๋ถ๋ถ ๋ฐ๋ณต ๋ฌธ์ (Overlapping Subproblem) ์ด๋ผ๊ณ ํ๋ค. ์ด๋ ์ด๋ค ๋ฌธ์ ๊ฐ ์ฌ๋ฌ ๊ฐ์ ๋ถ๋ถ ๋ฌธ์ ๋ก ์ชผ๊ฐ์ง ์ ์์ ๋ ์ฌ์ฉํ๋ ์ฉ์ด์ด๋ค.
์ด๋ ๋ถ๋ถ๋ฌธ์ (subproblem) ๋ ํญ์ ์๋ก์ด ๋ถ๋ถ ๋ฌธ์ ๋ฅผ ์์ฑํด๋ด๊ธฐ ๋ณด๋ค๋ ๊ณ์ํด์ ๊ฐ์ ๋ถ๋ถ ๋ฌธ์ ๊ฐ ์ฌ๋ฌ๋ฒ ์ฌ์ฌ์ฉ๋๊ฑฐ๋ ์ฌ๊ท ์๊ณ ๋ฆฌ์ฆ์ ํตํด ํด๊ฒฐ๋๋ ๋ฌธ์ ๋ฅผ ๊ฐ๋ฅดํจ๋ค.
โถ ์ต์ ๋ถ๋ถ ๊ตฌ์กฐ (Optimal Substructure)
์ต์ ๋ถ๋ถ ๊ตฌ์กฐ๋, ์์ ๋ถ๋ถ ๋ฌธ์ ์์ ๊ตฌํ ์ต์ ์ ๋ต์ผ๋ก ํฉ์ณ์ง ํฐ ๋ฌธ์ ์ ์ต์ ์ ๋ต์ ๊ตฌํ ์ ์์ด์ผ ํ๋ค๋ ๊ฒ์ด๋ค.
์๋ ํผ๋ณด๋์น ์์ด์ ์์ ๋ณด์.
fibo(n) = fibo(n-1) + fibo(n-2)
ํฐ ๋ฌธ์ ์ ๋ต์ธ fibo(n) ์ด ์ต์ ์ ๋ต์ด ๋๋ ค๋ฉด, ์์ ๋ถ๋ถ์ ๋ฌธ์ ์ธ fibo(n-1), fibo(n-2)์ด ์ต์ ์ ๋ต์ด์ด์ผ๋ง ํ๋ค. ์์ ๋ถ๋ถ์ ๋ฌธ์ ์ ์ต์ ์ ๋ต์ผ๋ก ํฐ ๋ฌธ์ ์ ์ต์ ์ ๋ต์ ๊ตฌํ๋ค๋ ๋ป์ด๋ค.
์ฌ๊ธฐ์, fibo(n-1)์ ๊ตฌํ๊ธฐ ์ํด์๋ ๋ค์ fibo(n-2) + fibo(n-3)์ด ๋๊ณ , fibo(n-2)๊ฐ ์ค๋ณต๋๊ฒ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ต์ ๋ถ๋ถ ๊ตฌ์กฐ๋ฅผ ๋ง์กฑํ๋ค๋ฉด ๋ฌธ์ ์ ํฌ๊ธฐ์ ์๊ด์์ด fibo(n-1)์ ์ธ์ ๋ ์ผ์ ํ ๊ฐ์ ๊ฐ์ง๋ค.
๊ทธ๋ผ ์ด ์ค๋ณต๋๋ ์ฐ์ฐ๊ณผ์ ์ ์ค์ด๊ธฐ ์ํด์๋ ์ด๋ป๊ฒ ํด์ผํ ๊น? ์ด๊ฒ์ ๋ฐ๋ก Memoization ๊ฐ๋ ์์ ์ค๋ช ํ ์ ์๋ค.
Memoization (๋ฉ๋ชจ์ด์ ์ด์ )
์์ ์ค๋ณต๋๋ ์ฐ์ฐ๊ณผ์ ์ ํด๊ฒฐํ๊ธฐ ์ํด์๋ Memoization(๋ฉ๋ชจ์ด์ ์ด์ )์ด๋ผ๋ ๋์ ๊ณํ๋ฒ์ ๊ฐ๋ ์ด ๋์ ๋๊ฒ ๋๋ค.
Memoization(๋ฉ๋ชจ์ด์ ์ด์ )์ ์ปดํจํฐ ํ๋ก๊ทธ๋จ์ด ๋์ผํ ๊ณ์ฐ์ ๋ฐ๋ณตํด์ผํ ๋, ์ด์ ์ ๊ณ์ฐํ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํจ์ผ๋ก์จ ๋์ผํ ๊ณ์ฐ์ ๋ฐ๋ณต ์ํ์ ์ ๊ฑฐํ์ฌ ํ๋ก๊ทธ๋จ ์คํ ์๋๋ฅผ ๋น ๋ฅด๊ฒ ํ๋ ๊ธฐ์ ์ด๋ค. - Wikipedia
์ฆ, ๋ฉ๋ชจ๋ฆฌ์ ๊ณ์ฐํ ๊ฐ์ ์ ์ฅํด ๋๊ฐ์ผ๋ก์จ ๋ฐ๋ณต ์ํ๋ ๋ ์ฐ์ฐ ์์ด ์ ์ฅ๋ ๊ฐ์ ์ฌ์ฉํ๋ค๋ ๊ฐ๋ ์ด๋ค.
์ด๋ฌํ ๋ฉ๋ชจ์ด์ ์ด์ ์ด๋ผ๋ ๊ฐ๋ ์, ์ค์ํํธ ์ฝ๋๋ฅผ ํตํด์ ๊ตฌํํด๋ณด์. cache๋ผ๋ ๋ฐฐ์ด์ ์ด์ฉํด์ ๊ฐ์ ์ ์ฅํด์ฃผ์๋ค.
func fibo(_ n: Int) -> Int{
var cache: [Int] = [0, 1]
for num in 2...n {
cache.append(cache[num - 1] + cache[num - 2])
}
return cache[n]
}
๋ฐฐ์ด์ ์์ฑํ๊ณ , ๊ณ์ฐํ ๊ฐ์ ์ ์ฅํ๊ณ , ์ ์ฅ๋ ๊ฐ์ผ ๊ฒฝ์ฐ ๋ฐฐ์ด์ ๊ฐ์ ๋ฆฌํดํ๋ ํ์์ผ๋ก ์ฝ๋๋ฅผ ๊ตฌํํ ์ ์๋ค. ์ด๋ ๊ฒ ํ๊ฒ ๋๋ฉด ์ฐ์ฐ์ ์ค๋ณต์ ๋ง์ ์ ์๋ค. ์ฃผ๋ก ์ ์ฅ์ ํด๋๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ cache๋ผ๊ณ ๋ถ๋ฅธ๋ค.
๋์ ๊ณํ๋ฒ์ 2๊ฐ์ง ์ ๊ทผ ๋ฐฉ๋ฒ
๋์ ๊ณํ๋ฒ์ผ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๊ณ ํ ๋, ๋ ๊ฐ์ง์ ์ ๊ทผ ๋ฐฉ๋ฒ์ด ์กด์ฌํ๋ค.
- Bottom - up
- Top - down
โถ Bottom - up ๋ฐฉ๋ฒ
๋ง๊ทธ๋๋ก, ์๋์ ์๋ก ์ ๊ทผํ๋ ๋ฐฉ๋ฒ์ผ๋ก ๋ถ๋ถ ๋ฌธ์ ์์๋ถํฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ฌ ์ ์ฐจ ํฐ ๋ฌธ์ ๋ฅผ ํ์ด๊ฐ๋ ๋ฐฉ์์ด๋ค. for ๋ฌธ์ ์ด์ฉํ๋ ๋ฐฉ์์ด ์ด์ ํด๋นํ๋ค.
var cache = [Int](repeating: 0, count : 101)
cache[1] = 1
cache[2] = 1
func fibo(_ n: Int) -> Int {
for i in 3...n {
cache[i] = cache[i-1] + cache[i-2]
}
return cache[n]
}
โถ Top - Down ๋ฐฉ๋ฒ
๋ง๊ทธ๋๋ก, ์์์ ์๋๋ก ์ ๊ทผํ๋ ๋ฐฉ๋ฒ์ผ๋ก, ํฐ ๋ฌธ์ ์์ ๋ถ๋ถ ๋ฌธ์ ๋ก ์ชผ๊ฐ๊ฐ๋ฉด์ ์ฌ๊ท ํธ์ถ์ ํตํด ๋ฌธ์ ๋ฅผ ํธ๋ ๋ฐฉ๋ฒ์ด๋ค.
//๋ฒ์๋ณด๋ค 1ํฌ๊ฒ
// cache[0] ์ด๊ธฐ๊ฐ ์ํ 0์ผ๋ก ๋ชจ๋ ์ฑ์์ค
var cache = [Int](repeating: 0, count: 101)
cache[1] = 1
cache[2] = 1
//ํผ๋ณด๋์น ์์ด
func fibo(_ n: Int) -> Int {
if cache[n] != 0 {
return cache[n]
}
cache[n] = fibo(n-1) + fibo(n-2)
return cache[n]
}
๐๐ป ์ฐธ๊ณ ํ ์๋ฃ, ๊ฐ์ฌํฉ๋๋ค
https://galid1.tistory.com/507
https://velog.io/@gillog/%EB%8F%99%EC%A0%81-%EA%B3%84%ED%9A%8D%EB%B2%95Dynamic-Programming
https://babbab2.tistory.com/100