Julia 编写 k 步前瞻函数的方法?

Julia way to write k-step look ahead function?

假设我有两个表示概率图的数组:

      2
     / \
1 ->     4 -> 5 -> 6 -> 7
     \ /
      3  

其中进入状态 2 的概率为 0.81,进入状态 3 的概率为 (1-0.81) = 0.19。我的数组代表状态的估计值以及奖励。 (注:数组的每个索引代表其各自的状态)

V = [0, 3, 8, 2, 1, 2, 0]
R = [0, 0, 0, 4, 1, 1, 1]

上下文并不重要,它只是让我知道我来自哪里。我需要编写一个 k 步前瞻函数,在其中我将奖励的折扣值相加并将其添加到第 k 个状态的估计值中。

到目前为止,我已经能够通过为向前看的每个步骤创建单独的函数来做到这一点。 我问这个问题的目的是弄清楚如何重构这段代码,这样我就不会重复自己并使用惯用的 Julia。

这是我所说的一个例子:

function E₁(R::Array{Float64,1}, V::Array{Float64, 1}, P::Float64)
    V[1] + 0.81*(R[1] + V[2]) + 0.19*(R[2] + V[3])
end

function E₂(R::Array{Float64,1}, V::Array{Float64, 1}, P::Float64)
    V[1] + 0.81*(R[1] + R[3]) + 0.19*(R[2] + R[4]) + V[4]
end

function E₃(R::Array{Float64,1}, V::Array{Float64, 1}, P::Float64)
    V[1] + 0.81*(R[1] + R[3]) + 0.19*(R[2] + R[4]) + R[5] + V[5]
end

.
.
.

依此类推。似乎如果我要忽略 E₁() 这将非常容易重构。但是因为我必须对两个不同状态下的价值估计进行折扣,所以我很难想出一种方法来将其推广到 k 步。

我认为我显然可以编写一个函数,将整数作为值,然后使用一堆 if 语句,但这似乎不符合 Julia 的精神。关于如何重构这个的任何想法?某种关闭?存储 R 和 V 的不同数据类型?

看起来你基本上有一个离散的 Markov chain。所以标准方法是将图形存储为其转换矩阵:

T = zeros(7,7)
T[1,2] = 0.81
T[1,3] = 0.19
T[2,4] = 1
T[3,4] = 1
T[5,4] = 1
T[5,6] = 1
T[6,7] = 1

然后你可以通过从左边乘以 T' 来计算在每个状态结束的概率,给定一个初始分布(因为通常,转换矩阵是转置定义的):

julia> T' * [1,0,0,0,0,0,0] # starting from (1)
7-element Array{Float64,1}:
 0.0 
 0.81
 0.19
 0.0 
 0.0 
 0.0 
 0.0 

同样,在 k 步之后到达每个状态的概率可以使用 T':

的幂来计算
julia> T' * T' * [1,0,0,0,0,0,0]
7-element Array{Float64,1}:
 0.0
 0.0
 0.0
 1.0
 0.0
 0.0
 0.0

既然您在 k 步之后有了所有概率,您也可以轻松计算期望值。也许将 T 定义为稀疏矩阵是值得的。