【问题标题】:Is there a clever way to get rid of these loops using numpy?有没有一种巧妙的方法可以使用 numpy 摆脱这些循环?
【发布时间】:2021-05-12 17:35:01
【问题描述】:

我正在达到最大递归深度,我一直在尝试使用 np.tensordot() 在这种情况下我无法真正了解如何使用它。

def stopping_condtion(a,V,V_old,eps):
    return  np.max(la.norm(V - V_old)) < ((1 - a) * eps)  / a

def value_iteration(net_profit, a, P,V,k = 0):
    eps = 0.1
    m = len(net_profit)
    n = len(V)

    A = np.zeros((n,m))

    for i in range(0,n):
        for j in range(0,m):
            A[i,j] = net_profit[j,i] + a * np.sum(P[j,:,i]) * V[j] 
            
    V_new = np.max(A,axis = 1)

    if stopping_condtion(a,V_new,V,eps):
        print(f'a* =  {np.argmax(A,axis = 1)} with alpha = {a} after n = {k} iterations ')
        return np.argmax(A,axis = 1)
    
    return value_iteration(net_profit, a, P,V_new,k+1)

这些是输入

profit = np.array([900, 800 , 600 , 400, 100])
cost   = np.array([0  , 80  , 800])

net_profit = (np.tile(profit,(3,1)).transpose() - cost).transpose()
alpha  = np.array([0.3, 0.6 , 0.9])


P  = np.array([ [[0.6, 0.4  , 0   , 0  , 0  ],
                 [0  , 0.5  , 0.3 , 0.2, 0  ],
                 [0  , 0    , 0.4 , 0.3, 0.3],
                 [0  , 0    , 0   , 0.5, 0.5],
                 [0  , 0    , 0   , 0  , 1  ]],
               
                [[0.8, 0.2  , 0   , 0  , 0  ],
                 [0  , 0.8  , 0.2 , 0  , 0  ],
                 [0  , 0.2  , 0.6 , 0.2, 0  ],
                 [0  , 0    , 0.3 , 0.6, 0.1],
                 [0  , 0    , 0   , 0.5, 0.5]],
               
                [[1  , 0    , 0   , 0  , 0  ],
                 [1  , 0    , 0   , 0  , 0  ],
                 [1  , 0    , 0   , 0  , 0  ],
                 [1  , 0    , 0   , 0  , 0  ],
                 [1  , 0    , 0   , 0  , 0  ]] ])

V = np.zeros(len(P[0,0]))
value_iteration(net_profit,alpha[0],P,V)

我想知道是否有办法摆脱循环并仅使用 Numpy 操作来提高效率。

【问题讨论】:

  • 什么是aVk
  • @kevin 现在在下面的 sn-p 中。感谢您的快速回复!
  • 你应该把尾递归变成一个循环。这里根本没有理由使用递归
  • @MadPhysicist 即使我这样做,它也表示我达到了最大递归深度。
  • 不递归就无法达到最大递归深度

标签: python numpy tensor operations-research value-iteration


【解决方案1】:

您可以像以下(未经测试的)代码一样使用转置和广播。

A = net_profit.T + a * np.sum(P, axis=1).T * V[:,None]

【讨论】:

  • 这可能与net_profit.T + np.einsum("i,ijk,ijk-&gt;ki", a, P, V[None,:,None])相同
  • @Kevin 有趣的解决方案。注意在这种情况下应该使用[a] 而不是a(因为a 是一个标量)。
  • 更好的是np.array(a, ndmin=1, copy=False),或者更好的是,将a 排除在einsum之外
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-16
  • 1970-01-01
  • 2016-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-15
相关资源
最近更新 更多