Loading [MathJax]/jax/output/CommonHTML/jax.js

Algorithm/๋™์ ๊ณ„ํš๋ฒ•

[Dynamic Programming] ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ๊ธฐ์ดˆ

ํด๋กœ์ด๐Ÿ“ 2023. 10. 20. 10:54

์ฝ”๋“œ์—†๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ๋‹˜์˜ ๊ฐ•์˜ ์ˆ˜๊ฐ•

 

 

Dynamic Programming

์กฐ๊ฑด

  • ๋ฌธ์ œ๊ฐ€ ๋” ์ž‘์€ subproblem์œผ๋กœ ์ชผ๊ฐœ์งˆ ๋•Œ
  • subproblem์˜ solution์œผ๋กœ ๋” ํฐ problem์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์„ ๋•Œ
  • ๋‚˜๋ˆˆ subprolem์ด ๊ฒน์น  ๋•Œ -> ํ•„์š”ํ•œ ๊ณ„์‚ฐ ์ˆ˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

 

ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด

๋Œ€ํ‘œ์ ์ธ ๋™์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์˜ˆ์‹œ

ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด F(7)์„ ๊ตฌํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด?

F(7) = F(6) + F(5)

F(7) = F(5) + F(4) + F(4) + F(3)

F(7) = F(4) + F(3) + F(3) + F(2) + F(3) + F(2) + F(2) + F(1)

.

.

.

์‹œ๊ฐ„ ๋ณต์žก๋„๋Š”?

์ธต์ด ๋Š˜์–ด๋‚  ๋•Œ๋งˆ๋‹ค 2๊ฐ€ ๊ณฑํ•ด์ง€๊ณ  ์ด n๊ฐœ์˜ ์ธต์ด๊ธฐ ๋•Œ๋ฌธ์— O(2n)

def fib_naive(n):
  if n == 0:
	return 0
  elif n == 1:
	return 1
  else:
	fib = fib_naive(n-1) + fib_naive(n-2)
	return fib

 

 

๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์œผ๋กœ ์ ์šฉํ•ด๋ณด์ž๊ตฌ

  • ๊ฒฐ๊ณผ ๊ฐ’์˜ array๋ฅผ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด ๋‘”๋‹ค.
  • ๋‚˜๋ˆ ์ง€๋Š” subproblem์—์„œ ํ•„์š”ํ•œ ๊ฐ’์„ array์—์„œ ์ฐพ๋Š”๋‹ค.
  • ๊ฐ’์ด ์—†์œผ๋ฉด ๊ทธ ๋•Œ ๊ณ„์‚ฐํ•ด์„œ ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค.
fib_array = [0,1]

def fib_recur_dp(n):
  if n < len(fib_array): # ๊ตฌํ•ด์•ผ ํ•  n๋ฒˆ์งธ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜๊ฐ€ ๋ฐฐ์—ด์— ์กด์žฌํ•˜๋ฉด ๊ทธ ๊ฐ’์„ return
  	return fib_array[n]
    
  else:
	fib = fib_recur_dp(n-1) + fib_recur_dp(n-2)
	fib_array.append(fib)
	return fib

์ด๋ ‡๊ฒŒ ๊ณ„์‚ฐํ•˜๋ฉด ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. O(n)

 

ํ•˜์ง€๋งŒ ์œ„์˜ ํ•จ์ˆ˜์—์„œ fib_recur_dp(10000)๊ณผ ๊ฐ™์ด ํฐ ์ˆซ์ž๋ฅผ ๊ตฌํ•˜๋ ค๋ฉด ์žฌ๊ท€ ๊นŠ์ด ์ดˆ๊ณผ ์—๋Ÿฌ๊ฐ€ ๋‚˜์˜จ๋‹ค.

๊ฐ€์žฅ ์œ„์˜ ์ˆซ์ž n๋ถ€ํ„ฐ ์ชผ๊ฐœ๋‚˜๊ฐ€๋ฉด์„œ ํ•ด๊ฒฐํ•˜๋ ค๊ณ  ํ•˜๊ธฐ ๋•Œ๋ฌธ์— top-down ๋ฐฉ์‹์˜ ๋‹ค์ด๋‚˜๋ฏน ์†”๋ฃจ์…˜์ด๋ผ๊ณ  ํ•œ๋‹ค. ์Œ“์•„๊ฐ€๋Š” stack์˜ ํ•œ๊ณ„๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ข‹์€ solution์€ ์•„๋‹ˆ๋‹ค.

 

Bottom up ๋‹ค์ด๋‚˜๋ฏน ์†”๋ฃจ์…˜

๊ฐ€์žฅ ์ž‘์€ F(0) ๋ถ€ํ„ฐ F(1), F(2) ... ์Œ“์•„๋‚˜๊ฐ€๋Š” ๊ฒƒ

def fib_dp(n):
  if n == 0:
	return 0
  elif n == 1:
	return 1
  
  fib_array = [0,1]
  for i in range(2,n+1):
	num = fib_array[i-1] + fib_array[i-2]
	fib_array.append(num)
  return fib_array(n)

์‹œ๊ฐ„ ๋ณต์žก๋„: O(n)

๊ณต๊ฐ„ ๋ณต์žก๋„: O(n)