【问题标题】:Dynamic Programming Grid in PythonPython中的动态编程网格
【发布时间】: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) 依赖于两个内核 foobar,它是相邻节点 (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,但无法立即找到解决方案。

请注意,在foobardd 中将比在玩具示例中更复杂。

【问题讨论】:

  • 现在的问题非常抽象。考虑发布minimal reproducible example
  • 用玩具示例更新了问题。我认为我对此的实际应用是不必要的复杂

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


【解决方案1】:

正如您所提到的,当 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]

【讨论】:

    猜你喜欢
    • 2022-06-15
    • 2013-12-09
    • 2015-02-19
    • 1970-01-01
    • 2016-11-03
    • 2011-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多