Python中的动态编程网格

时间:2018-09-24 16:58:23

标签: python python-3.x numpy dynamic-programming

我想最小化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中,foobar比玩具示例中的要复杂。

1 个答案:

答案 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]