【发布时间】:2018-09-24 16:58:22
【问题描述】:
我想在 Python 中最小化网格上的成本函数。我有两个变量 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])
换句话说,网格点 (i+1,j+1) 依赖于两个内核 foo 和 bar,它是相邻节点 (i,j+1) (i+1,j) 和 (我,j)。下面是一个玩具示例
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])
但是,这是一个非常低效的解决方案。特别是因为 N 可能是任意大的。所以我的问题是:这是最/更有效的计算方法?使用迭代器(我尝试过 np.nditer 但没有取得很大成功),或者使用 Numba,或者在 Numpy 中有一些花哨的技巧吗?我已经开始使用 Numpy 研究 ufuncs 和 ufunc.accumulate,但无法立即找到解决方案。
请注意,在foo、bar 和dd 中将比在玩具示例中更复杂。
【问题讨论】:
-
现在的问题非常抽象。考虑发布minimal reproducible example
-
用玩具示例更新了问题。我认为我对此的实际应用是不必要的复杂
标签: python python-3.x numpy dynamic-programming