简体   繁体   English

Python中的动态编程网格

[英]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)依赖于两个内核foobar ,并且它是相邻节点(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. 请注意,在foobardd会比玩具示例中的复杂。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM