Monday, July 14, 2008

Dynamic Programming

Bien, hoy lei un poco de Dynamic Programming, es bacancito, de una pense en un decorator en Python, no es complicado, ahi esta el ejemplo:

1) Fibonacci normal:


#!/usr/bin/python
import sys

def fib(x):
if x==0:
return 0
if x==1:
return 1
return fib(x-1)+fib(x-2)

print fib(int(sys.argv[1]))


Este codigo tiene un comportamiento como lo muestra la grafica (N vs segundos)



2) Ahora con un decorator implementando Dynamic Programming.


#!/usr/bin/python
import sys

map={}
def dynamic_programming(func):
def decorator(*args, **kwargs):
if (func,args) in map:
return map[(func,args)]
else:
r = func(*args, **kwargs)
map[(func,args)] = r
return r
return decorator


@dynamic_programming
def fib(x):
if x==0:
return 0
if x==1:
return 1
return fib(x-1)+fib(x-2)


print fib(int(sys.argv[1]))


Como pueden ver el codigo de la funcion fib no se cambio, solo se le agrego un decorator, el cual busca primero si el argumento esta en un diccionario, para no recalcularlo. (kwargs es un dict, y no puedo usarlo como un key en otro dict, toco sacarlo del key :))

No pondre grafica de este solo esto:


$ time ./fib2.py 499
86168291600238450732788312165664788095941068326060883324529903470149056115823592713458328176574447204501

real 0m0.029s
user 0m0.024s
sys 0m0.004s

2 comments:

Juan Alvarez said...

Se supone que este tipo de comportamiento lo tiene haskell por defecto sin necesidad de usar decorators!. Eso hace entonces que programar en haskel ya implique estar utilizando programación dinámica desde el lenguaje? No creo

Unknown said...

¿Qué es la variable kwargs? supongoq que args son los argumentos,func la función... creo que me pierdo algo :p

Muy bueno el artículo, no es una gran revelación pero puede resultar muy útil :) .