[英]Dynamic Programming Grid in Python
I want to minimize a cost function over a grid in Python. 我想通过Python中的网格最小化成本函数。 I have two variables x and y which can be computed as
我有两个变量x和y可以计算为
x[i+1,j+1], y[i+1,j+1] = f(x[i,j], x[i+1,j], x[i,j+1], foo[i,j], bar[i,j])
In other words the grid point (i+1,j+1) depends on two kernels foo
and bar
, and it's neighboring nodes (i,j+1) (i+1,j) and (i,j). 换句话说,网格点(i + 1,j + 1)依赖于两个内核
foo
和bar
,并且它是相邻节点(i,j + 1)(i + 1,j)和(i,j)。 A toy example can be seen below 玩具示例如下
import numpy as np
N = 20
ivec = np.arange(N)
jvec = np.arange(N)
# Kernels
foo = np.sin(ivec[:,None] * jvec[None,:])
bar = np.cos(ivec[:,None] + jvec[None,:])
# We want to find the total cost for traversing over the matrix
d = np.zeros((N,N))
# And store the optimal path
indices = np.zeros((N,N), "int")
for i in range(N-1):
for j in range(N-1):
# Compute all posibilities for reaching current node
dd = [
d[i+1,j] + foo[i,j],
d[i,j+1] + bar[i,j],
d[i,j] + foo[i,j] * bar[i,j]
]
# And find and store the minimim path
indices[i+1,j+1] = np.argmin(dd)
d[i+1,j+1] = dd[indices[i+1,j+1]]
print(d[-1,-1])
However this is a very inefficient solution. 但是,这是一个非常低效的解决方案。 Especially as N might be arbitrarily large.
特别是因为N可能会任意大。 So my question is: which is the most / more efficient way to compute this?
所以我的问题是:哪种/最有效的计算方法是? Using iterators (I have tried np.nditer without great success), or using Numba, or are there some fancy trickery one can do in Numpy?
使用迭代器(我尝试过np.nditer并没有取得很大的成功),或者使用Numba,或者在Numpy中可以做一些花哨的技巧吗? I've started looking into ufuncs and
ufunc.accumulate
with Numpy but can't immediately see a solution. 我已经开始用Numpy研究ufuncs和
ufunc.accumulate
,但无法立即看到解决方案。
Note that in foo
, bar
and dd
will be more complicated than in the toy example. 请注意,在
foo
, bar
和dd
会比玩具示例中的复杂。
As you mentioned, using numba could be the easiest way to make your code faster when N is large. 如您所提到的,当N大时,使用numba可能是使代码更快的最简单方法。
import numba
import numpy as np
@numba.jit(nopython=True)
def dp(foo, bar):
N = foo.shape[0]
# We want to find the total cost for traversing over the matrix
d = np.zeros((N,N))
# And store the optimal path
indices = np.zeros((N,N), dtype=np.int64)
for i in range(N-1):
for j in range(N-1):
# Compute all posibilities for reaching current node
dd = np.array([
d[i+1,j] + foo[i,j],
d[i,j+1] + bar[i,j],
d[i,j] + foo[i,j] * bar[i,j]
])
# And find and store the minimim path
indices[i+1,j+1] = np.argmin(dd)
d[i+1,j+1] = dd[indices[i+1,j+1]]
return d[-1,-1]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.