我想最小化Python中网格上的成本函数。我有两个变量x和y,可以计算为
find . -type f -exec bash -c '
logcmd() { printf "%q " "$@"; printf "\n"; } # a more accurate replacement for echo
for f; do
logcmd mv "$f" "${f%.*}${0}.${f##*.}"
done' "$i" {} +
换句话说,网格点(i + 1,j + 1)取决于两个内核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])
和foo
,并且它是相邻节点(i,j + 1)(i + 1, j)和(i,j)。可以在下面看到一个玩具示例
bar
但是,这是一个非常低效的解决方案。特别是因为N可能会任意大。所以我的问题是:哪种/最有效的计算方法是?使用迭代器(我尝试过np.nditer并没有取得很大的成功),或者使用Numba,或者在Numpy中可以做一些花哨的技巧吗?我已经开始用Numpy研究ufuncs和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])
,但无法立即看到解决方案。
请注意,在ufunc.accumulate
中,foo
和bar
比玩具示例中的要复杂。
答案 0 :(得分:0)
如前所述,使用Numba可能是在N很大时使代码更快的最简单方法。
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]