基于蒙特卡洛的强化学习方法【附带代码实现】

2023-11-02

基于蒙特卡洛的强化学习方法

蒙特卡洛方法(Monte-Carlo methods)也被称为统计模拟方法,是一种基于概率统计的数值计算方法。运用蒙特卡洛方法时,我们通常使用重复随机抽样,然后运用概率统计方法来从抽样结果中归纳出我们想求的目标的数值估计。

一个简单的例子是用蒙特卡洛方法来计算圆的面积。例如,在下图所示的正方形内部随机产生若干个点,细数落在圆中点的个数,圆的面积与正方形面积之比就等于圆中点的个数与正方形中点的个数之比。如果我们随机产生的点的个数越多,计算得到圆的面积就越接近于真实的圆的面积。
image.png

强化学习算法的精髓之一是解决无模型的马尔可夫决策问题。无模型的强化学习算法主要包括蒙特卡洛方法和时序差分方法。本文的主题是蒙特卡洛方法,那么如何用蒙特卡洛方法来估计一个策略在一个马尔可夫决策过程中的状态价值函数呢?

回到值函数最原始的定义公式
V ( s ) = E [ G t ∣ S t = s ] V(s)=\mathbb{E}\left[G_{t} \mid S_{t}=s\right] V(s)=E[GtSt=s]

状态值函数的计算实际上是计算返回值的期望。动态规划的方法是利用模型计算该期望。在没有模型时,我们可以采用蒙特卡洛的方法计算该期望,即利用随机样本估计期望。

一个很直观的想法就是用策略在 MDP 上采样很多条序列,计算从这个状态出发的回报,再求其期望就可以了,公式如下:
V π ( s ) = E π [ G t ∣ S t = s ] ≈ 1 N ∑ i = 1 N G t ( i ) V^{\pi}(s)=\mathbb{E}_{\pi}\left[G_{t} \mid S_{t}=s\right] \approx \frac{1}{N} \sum_{i=1}^{N} G_{t}^{(i)} Vπ(s)=Eπ[GtSt=s]N1i=1NGt(i)

在计算值函数时,蒙特卡洛方法是利用经验平均代替随机变量的期望。下面分别阐述经验和平均的意思。

经验”:当要评估智能体的当前策略时,我们可以利用策略产生很多次试验,每次试验都是从任意的初始状态开始直到终止,比如一次试验(episode)为 S 1 , A 1 , R 2 , ⋯   , S T S_1,A_1,R_2,\cdots,S_T S1,A1,R2,,ST,计算一次试验中状态 s s s处的折扣回报返回值为 G ( s ) = R t + 1 + γ R t + 2 + ⋯ + γ T − 1 R T G(s)=R_{t+1}+\gamma R_{t+2}+\cdots+\gamma^{T-1}R_T G(s)=Rt+1+γRt+2++γT1RT,那么"经验"就是指利用该策略做很多次试验,产生很多幕数据,见下图。
image.png

平均”:就是求平均值。不过,利用蒙特卡洛方法求状态处的值函数时,又可以分为第一次访问蒙特卡罗方法每次访问蒙特卡罗方法。第一次访问蒙特卡洛方法是指在计算状态处的值函数时,只利用每次试验中第一次访问到状态 s s s时的返回值。如上图中第一次试验所示,计算状态 s s s处的均值时只利用 G 11 G_{11} G11,因此第一次访问蒙特卡洛方法的计算公式为

V ( s ) = G 11 ( s ) + G 21 ( s ) + ⋯ N ( s ) V(s)=\dfrac{G_{11}(s)+G_{21}(s)+\cdots}{N(s)} V(s)=N(s)G11(s)+G21(s)+

每次访问蒙特卡洛方法是指在计算状态 s s s处的值函数时,利用所有访问到状态 s s s时的回报返回值,即

V ( s ) = G 11 ( s ) + G 12 ( s ) + ⋯ + G 21 ( s ) + ⋯ N ( s ) V(s)=\dfrac{G_{11}(s)+G_{12}(s)+\cdots+G_{21}(s)+\cdots}{N(s)} V(s)=N(s)G11(s)+G12(s)++G21(s)+

同时,根据大数定律:当 N ( s ) → ∞ N(s)\rightarrow \infty N(s),有 V ( s ) → V π ( s ) V(s)\rightarrow V^{\pi}(s) V(s)Vπ(s)

在一条序列中,可能没有出现过这个状态,可能只出现过一次这个状态,也可能出现过很多次这个状态。我们介绍的蒙特卡洛价值估计方法会在该状态每一次出现时计算它的回报。还有一种选择是一条序列只计算一次回报,也就是这条序列第一次出现该状态时计算后面的累积奖励,而后面再次出现该状态时,该状态就被忽略了。假设我们现在用策略从状态开始采样序列,据此来计算状态价值。我们为每一个状态维护一个计数器和总回报,计算状态价值的具体过程如下所示。


  1. 使用策略 π \pi π采样若干条序列:
    s 0 ( i ) ⟶ a 0 ( i ) r 0 ( i ) , s 1 ( i ) ⟶ a 1 ( i ) r 1 ( i ) , s 2 ( i ) ⟶ a 2 ( i ) ⋯ ⟶ a T − 1 ( i ) r T − 1 ( i ) , s T ( i ) s_{0}^{(i)} \stackrel{a_{0}^{(i)}}{\longrightarrow} r_{0}^{(i)}, s_{1}^{(i)} \stackrel{a_{1}^{(i)}}{\longrightarrow} r_{1}^{(i)}, s_{2}^{(i)} \stackrel{a_{2}^{(i)}}{\longrightarrow} \cdots \stackrel{a_{T-1}^{(i)}}{\longrightarrow} r_{T-1}^{(i)}, \boldsymbol{s}_{T}^{(i)} s0(i)a0(i)r0(i),s1(i)a1(i)r1(i),s2(i)a2(i)aT1(i)rT1(i),sT(i)
  2. 对每一条序列中的每一时间步 t t t的状态 s s s进行以下操作:
  3. 更新状态 s s s的计数器 N ( s ) ← N ( s ) + 1 N(s)\leftarrow N(s)+1 N(s)N(s)+1
  4. 更新状态 s s s的总回报 M ( s ) ← M ( s ) + G t M(s) \leftarrow M(s)+G_{t} M(s)M(s)+Gt
  5. 每一个状态的价值被估计为回报的平均值 V ( s ) = M ( s ) / N ( s ) V(s)=M(s) / N(s) V(s)=M(s)/N(s)

由于智能体与环境交互的模型是未知的,蒙特卡罗方法是利用经验平均来估计值函数,而能否得到正确的值函数,则取决于经验。因此,如何获得充足的经验是无模型强化学习的核心所在。

在动态规划方法中,为了保证值函数的收敛性,算法会逐个扫描状态空间中的状态。而无模型的方法充分评估策略值函数的前提,是每个状态都能被访问到。因此,在蒙特卡洛方法中必须采用一定的方法保证每个状态都能被访问到,方法之一是探索性初始化。探索性初始化是指每个状态都有一定的几率作为初始状态。在学习基于探索性初始化的蒙特卡罗方法前,我们还需要先了解策略改善方法,以及便于进行迭代计算的平均方法。

蒙特卡洛策略改善方法:蒙特卡洛方法利用经验平均估计策略值函数。估计出值函数后,对于每个状态,它通过最大化动作值函数来进行策略的改善。即
π ( s ) = arg ⁡ max ⁡ a q ( s , a ) \pi(s)=\arg\max_a q(s,a) π(s)=argamaxq(s,a)

增量更新方法:计算回报的期望时,除了可以把所有的回报加起来除以次数,还有一种增量更新的方法。对于每个状态和对应回报,进行如下计算:


  • N ( s ) ← N ( s ) + 1 N(s) \leftarrow N(s)+1 N(s)N(s)+1
  • V ( s ) ← V ( s ) + 1 N ( s ) ( G − V ( S ) ) V(s) \leftarrow V(s)+\frac{1}{N(s)}(G-V(S)) V(s)V(s)+N(s)1(GV(S))

探索性初始化在迭代每一幕时,初始状态是随机分配的,这样可以保证迭代过程中每个状态行为对都能被选中。它蕴含着一个假设:假设所有的动作都被无限频繁选中。对于这个假设,有时很难成立,或无法完全保证。所以,需要设计一个温和的探索策略,即对所有的状态 s s s a a a都满足: π ( a ∣ s ) > 0 \pi(a|s)>0 π(as)>0。也就是说,温和的探索策略是指在任意状态下,采用动作集中每个动作的概率都大于零。典型的温和策略是 ε \varepsilon ε-soft策略:

π ( a ∣ s ) ← { 1 − ε + ε ∣ A ( s ) ∣  if  a = arg ⁡ max ⁡ a Q ( s , a ) ε ∣ A ( s ) ∣  if  a ≠ arg ⁡ max ⁡ a Q ( s , a ) \pi(a \mid s) \leftarrow\left\{\begin{array}{ll} 1-\varepsilon+\frac{\varepsilon}{|A(s)|} & \text { if } a=\arg \max _{a} Q(s, a) \\ \frac{\varepsilon}{|A(s)|} & \text { if } a \neq \arg \max _{a} Q(s, a) \end{array}\right. π(as){1ε+A(s)εA(s)ε if a=argmaxaQ(s,a) if a=argmaxaQ(s,a)

根据探索策略(行动策略)和评估的策略是否为同一个策略,蒙特卡罗方法又分为on-policy和off-policy两种方法。若行动策略和评估及改善的策略是同一个策略,称为on-policy,可翻译为同策略。比如,要产生数据的策略和评估及要改善的策略都是 ε \varepsilon ε-soft策略。若行动策略和评估及改善的策略是不同的策略,称为off-policy,可翻译为异策略。异策略可以保证充分的探索性。例如用来评估和改善的策略 π \pi π是贪婪策略,用于产生数据的探索性策略 μ \mu μ为探索性策略,如 ε \varepsilon ε-soft策略。

用于异策略的目标策略 π \pi π和行动策略 μ \mu μ并非任意选择的,而是必须满足一定的条件。这个条件是覆盖性条件,即行动策略 μ \mu μ产生的行为覆盖或包含目标策略 π \pi π产生的行为。利用式子表示:满足 π ( a ∣ s ) > 0 \pi(a|s)>0 π(as)>0的任何 ( s , a ) (s,a) (s,a)均满足 μ ( a ∣ s ) > 0 \mu(a|s)>0 μ(as)>0。利用行为策略产生的数据评估目标策略需要利用重要性采样方法。

重要性采样来源于求期望,重要性采样的原理可以用图来描述。
E [ f ] = ∫ f ( z ) p ( z ) d z E[f]=\int f(z) p(z) dz E[f]=f(z)p(z)dz
image.png

当随机变量 z z z的分布非常复杂时,无法利用解析的方法产生用于逼近期望的样本,这时,我们可以选用一个概率分布很简单,很容易产生样本的概率分布 q ( z ) q(z) q(z),比如正态分布。原来的期望可变为
E [ f ] = ∫ f ( z ) p ( z ) d z = ∫ f ( z ) p ( z ) q ( z ) q ( z ) d z = 1 N ∑ n p ( z n ) q ( z n ) f ( z n ) , z n ∼ q ( z ) \begin{aligned} E[f] &=\int f(z) p(z) d z \\ &=\int f(z) \frac{p(z)}{q(z)} q(z) d z \\ &=\frac{1}{N} \sum_{n} \frac{p\left(z^{n}\right)}{q\left(z^{n}\right)} f\left(z^{n}\right), z^{n} \sim q(z) \end{aligned} E[f]=f(z)p(z)dz=f(z)q(z)p(z)q(z)dz=N1nq(zn)p(zn)f(zn),znq(z)

定义重要性权重: w n = p ( z n ) q ( z n ) w^n=\dfrac{p(z^n)}{q(z^n)} wn=q(zn)p(zn),普通的重要性采样求积分如下式所示:
E [ f ] = 1 N ∑ n ω n f ( z n ) E[f]=\frac{1}{N} \sum_{n} \omega^{n} f\left(z^{n}\right) E[f]=N1nωnf(zn)

通过上面的式子,可以分析出基于重要性采样的积分估计为无偏估计,即估计的期望值等于真实的期望。但是,基于重要性采样的积分估计的方差无穷大。这是因为原来的被积函数乘了一个重要性权重,改变了被积函数的形状及分布。尽管被积函数的均值没有发生变化,但方差明显发生改变。

在重要性采样中,使用的采样概率分布与原概率分布越接近,方差越小。然而,被积函数的概率分布往往很难求得,因此没有与之相似的简单采样概率分布,如果使用分布差别很大的采样概率对原概率分布进行采样,方差会趋近于无穷大。一种减小重要性采样积分方差的方法是采用加权重要性采样
E [ f ] ≈ ∑ n = 1 N ω n ∑ m = 1 N ω m f ( z n ) E[f] \approx \sum_{n=1}^{N} \dfrac{\omega^{n}}{\sum_{m=1}^{N} \omega^{m}} f\left(z^{n}\right) E[f]n=1Nm=1Nωmωnf(zn)

在异策略方法中,行动策略 μ \mu μ即用来产生样本的策略,所产生的轨迹概率分布相当于重要性采样中的 q ( z ) q(z) q(z), 用来评估和改进的策略 π \pi π所对应的轨迹概率分布为 p ( z ) p(z) p(z),因此利用行动策略 μ \mu μ所产生的累积函数返回值来评估策略 π \pi π时,需要在累积函数返回值前面乘以重要性权重。

在目标策略 π \pi π下,一次试验的概率为
P r ( A t , S t + 1 , ⋯   , S T ) = ∏ k = t T − 1 π ( A k ∣ S k ) p ( S k + 1 ∣ S K , A k ) Pr(A_t,S_{t+1},\cdots,S_T)=\prod_{k=t}^{T-1}\pi(A_k|S_k)p(S_{k+1}|S_K,A_k) Pr(At,St+1,,ST)=k=tT1π(AkSk)p(Sk+1SK,Ak)

在行动策略 μ \mu μ下,相应的试验的概率为
P r ( A t , S t + 1 , ⋯   , S T ) = ∏ k = t T − 1 μ ( A k ∣ S k ) p ( S k + 1 ∣ S K , A k ) Pr(A_t,S_{t+1},\cdots,S_T)=\prod_{k=t}^{T-1}\mu(A_k|S_k)p(S_{k+1}|S_K,A_k) Pr(At,St+1,,ST)=k=tT1μ(AkSk)p(Sk+1SK,Ak)

因此重要性权重为
ρ t T = ∏ k = t T − 1 π ( A k ∣ S k ) p ( S k + 1 ∣ S k , A k ) ∏ k = 1 T − 1 μ ( A k ∣ S k ) p ( S k + 1 ∣ S k , A k ) = ∏ k = t T − 1 π ( A k ∣ S k ) μ ( A k ∣ S k ) \rho_{t}^{T}=\frac{\prod_{k=t}^{T-1} \pi\left(A_{k} \mid S_{k}\right) p\left(S_{k+1} \mid S_{k}, A_{k}\right)}{\prod_{k=1}^{T-1} \mu\left(A_{k} \mid S_{k}\right) p\left(S_{k+1} \mid S_{k}, A_{k}\right)}=\prod_{k=t}^{T-1} \frac{\pi\left(A_{k} \mid S_{k}\right)}{\mu\left(A_{k} \mid S_{k}\right)} ρtT=k=1T1μ(AkSk)p(Sk+1Sk,Ak)k=tT1π(AkSk)p(Sk+1Sk,Ak)=k=tT1μ(AkSk)π(AkSk)

普通重要性采样的值函数估计式如下

V ( s ) = ∑ t ∈ T ( s ) ρ t T ( t ) G t ∣ T ( s ∣ V(s)=\dfrac{\sum_{t\in \mathcal{T}(s)}\rho_t^{T(t)}G_t}{|\mathcal{T}(s|} V(s)=T(stT(s)ρtT(t)Gt

加权重要性采样值函数估计为

V ( s ) = ∑ t ∈ T ( s ) ρ t T ( t ) G t ∑ t ∈ T ( s ) ρ t T ( t ) V(s)=\dfrac{\sum_{t\in \mathcal{T}(s)}\rho_t^{T(t)}G_t}{\sum_{t\in \mathcal{T}(s)}\rho_t^{T(t)}} V(s)=tT(s)ρtT(t)tT(s)ρtT(t)Gt

根据上述分析,异策略每次访问蒙特卡罗算法的伪代码见如下算法伪代码。


Input:对于所有的 s ∈ S s \in S sS, a ∈ A ( s ) a \in A(s) aA(s) ( s , a ) ← (s,a) ← (s,a)任意, C ( s , a ) ← 0 C(s,a) ← 0 C(s,a)0, π ( s ) ← π(s) ← π(s)相对于 Q Q Q的贪婪策略
Repeat

  • 利用软策略 μ \mu μ产生一次实验: S 0 , A 0 , R 1 , ⋯   , S T − 1 , A T − 1 , R T , S T S_{0}, A_{0}, R_{1}, \cdots, S_{T-1}, A_{T-1}, R_{T}, S_{T} S0,A0,R1,,ST1,AT1,RT,ST
  • G → 0 , W → 1 G \rightarrow 0, \quad W \rightarrow 1 G0,W1
  • For t = T − 1 , T − 2 , ⋯   , 0 t = T −1,T −2,\cdots ,0 t=T1,T2,,0 do
    • G ← γ G + R t + 1 G \leftarrow \gamma G+R_{t+1} GγG+Rt+1
    • C ( S t , A t ) ← C ( S t , A t ) + W C\left(S_{t}, A_{t}\right) \leftarrow C\left(S_{t}, A_{t}\right)+W C(St,At)C(St,At)+W
    • Q ( S t , A t ) ← Q ( S t , A t ) + W C ( S t , A t ) [ G − Q ( S t , A t ) ] Q\left(S_{t}, A_{t}\right) \leftarrow Q\left(S_{t}, A_{t}\right)+\frac{W}{C\left(S_{t}, A_{t}\right)}\left[G-Q\left(S_{t}, A_{t}\right)\right] Q(St,At)Q(St,At)+C(St,At)W[GQ(St,At)]
    • π ( S t ) ← arg ⁡ max ⁡ a Q ( S t , a ) \pi\left(S_{t}\right) \leftarrow \arg \max _{a} Q\left(S_{t}, a\right) π(St)argmaxaQ(St,a)
    • For A t ≠ π ( S t ) A_{t} \neq \pi\left(S_{t}\right) At=π(St) do
      • break for
    • End
    • W ← W 1 μ ( A t , ∣ S t ) \mathrm{W} \leftarrow \mathrm{W} \frac{1}{\mu\left(A_{t}, \mid S_{t}\right)} WWμ(At,St)1
  • End

Until


与基于动态规划的方法相比,基于蒙特卡罗的方法只是在值函数估计上有所不同,在整个框架上则是相同的,即估当前策略,再利用学到的值函数进行策略改善。

蒙特卡洛方法代码实现

# 把输入的两个字符串通过“-”连接
def join(str1, str2):
    return str1 + '-' + str2


def sample(MDP, Pi, timestep_max, number):
    ''' 采样函数,策略Pi,限制最长时间步timestep_max,总共采样序列数number '''
    S, A, P, R, gamma = MDP
    episodes = []
    for _ in range(number):
        episode = []
        timestep = 0
        s = S[np.random.randint(4)]  # 随机选择一个除s5以外的状态s作为起点
        # 当前状态为终止状态或者时间步太长时,一次采样结束
        while s != "s5" and timestep <= timestep_max:
            timestep += 1
            rand, temp = np.random.rand(), 0
            # 在状态s下根据策略选择动作
            for a_opt in A:
                temp += Pi.get(join(s, a_opt), 0)
                if temp > rand:
                    a = a_opt
                    r = R.get(join(s, a), 0)
                    break
            rand, temp = np.random.rand(), 0
            # 根据状态转移概率得到下一个状态s_next
            for s_opt in S:
                temp += P.get(join(join(s, a), s_opt), 0)
                if temp > rand:
                    s_next = s_opt
                    break
            episode.append((s, a, r, s_next))  # 把(s,a,r,s_next)元组放入序列中
            s = s_next  # s_next变成当前状态,开始接下来的循环
        episodes.append(episode)
    return episodes


# 采样5次,每个序列最长不超过1000步
episodes = sample(MDP, Pi_1, 20, 5)
print('第一条序列\n', episodes[0])
print('第二条序列\n', episodes[1])
print('第五条序列\n', episodes[4])
# 对所有采样序列计算所有状态的价值
def MC(episodes, V, N, gamma):
    for episode in episodes:
        G = 0
        for i in range(len(episode) - 1, -1, -1):  #一个序列从后往前计算
            (s, a, r, s_next) = episode[i]
            G = r + gamma * G
            N[s] = N[s] + 1
            V[s] = V[s] + (G - V[s]) / N[s]


timestep_max = 20
# 采样1000次,可以自行修改
episodes = sample(MDP, Pi_1, timestep_max, 1000)
gamma = 0.5
V = {"s1": 0, "s2": 0, "s3": 0, "s4": 0, "s5": 0}
N = {"s1": 0, "s2": 0, "s3": 0, "s4": 0, "s5": 0}
MC(episodes, V, N, gamma)
print("使用蒙特卡洛方法计算MDP的状态价值为\n", V)

\quad
\quad
参考

  • 《动手学强化学习》
  • 《深入浅出强化学习》

持续更新中…

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于蒙特卡洛的强化学习方法【附带代码实现】 的相关文章

随机推荐

  • STM32串口下载

    使用FlyMCU下载程序 1 上电前 设置BOOT0 1 BOOT1 0 或者是在上电后 设置BOOT0 1 BOOT1 0之后 然后按一下复位按键 从而通过串口下载程序 2 在MDK编译加载生成的hex文件 并勾选右边的编程前重装文件 这
  • Unity进阶 - 动画系统 - Animations选项卡

    Unity进阶 动画系统 Animations选项卡 相关文章阅读 Unity 进阶 动画系统 Mecanim动画系统 Unity进阶 动画系统 给人物角色制作动画 Unity进阶 动画系统 人形动画的导入 Unity进阶 动画系统 导入设
  • 中国移动笔试有感

    被3号的中国移动笔试给深深地虐了 以前被像阿里阿这样的大企业虐就没啥子感觉 笔试完依旧是嘻嘻哈哈 像恒生这样的企业 笔试对我来说还是比较容易的虽然面试被刷了 说明还是需要多读书啊 但是中国移动的笔试 真的深深的激起了我学习的动力 我也不知道
  • C语言_带参宏和函数的区别及各自优缺点

    前言 C语言中 要想解决某子问题 可以自定义一个函数来专门处理该问题 比如 我想比较两个数的大小 那么我可以地定义一个函数max来完成两个数求最大值功能 但是 C语言中我们也可以通过宏定义来定义一个求最值的函数MAX 然后通过使用带参宏来完
  • 善待自己:改变命运的N个人生哲理

    心灵的栅栏 人与月亮的距离并不遥远 因为人与人心灵间的距离更为遥远 王尔德 当玛格丽特的丈夫杰瑞因脑瘤去世后 她变得异常愤怒 生活太不公平 她憎恨孤独 孀居 年 她的脸变得紧绷绷的 一天 玛格丽特在小镇拥挤的路上开车 忽然发现一幢她喜欢的房
  • 《软件测试的艺术》读后感 Or 读书笔记

    软件测试的艺术 读后感 Or 读书笔记 第一章 一次自评价测试 第二章 软件测试的心理学和经济学 第三章 代码检查 走查与评审 第四章 测试用例的设计 第五章 模块 单元 测试 第六章 更高级别的测试 第七章 可用性 或用户体验 测试 第八
  • Java—类的加载概述

    1 1 类的加载概述 当程序要使用某个类时 如果该类还未被加载到内存中 则系统会通过加载 连接 初始化三步来实现对这个类进行初始化 1 加载 是将class文件读入内存 并为之创建一个Class对象 任何类被使用时系统都会建立一个Class
  • Docker中安装Gitlab详细全教程

    前言 一 安装Gitlab 1 搜索影像 2 下载影像 3 启动Git服务 4 查看Gitlab是否已经启动 二 配置Gitlab 1 首先 先进入容器 2 修改gitlab rb文件 3 修改gitlab rb文件中的IP与端口号 3 配
  • OpenCV——求直线交点

    您可以使用OpenCV中的cv Point和cv Vec4i数据类型来表示点和直线 然后使用cv intersect函数来计算两条直线的交点 下面是一个示例代码 其中line1和line2分别表示两条直线的起点和终点 cv Point li
  • 机器学习(11)——时间序列分析

    目录 1 时间序列数据的相关检验 1 1 白噪声检验 1 2 平稳性检验 1 3 自相关分析和偏自相关分析 2 移动平均算法 2 1 简单移动平均法 2 2 简单指数平滑法 2 3 霍尔特线性趋势法 2 4 Holt Winters 季节性
  • Centos7安装dig命令

    2019独角兽企业重金招聘Python工程师标准 gt gt gt Centos7安装dig命令 作者 jwj 时间 2018 10 17 分类 服务器 最近做一个项目 需要用到Gmail邮箱发送邮件 但发现发送不出去 排查问题时 需要用到
  • 最新SecureCRT 中文注册版

    SecureCRT是一款由VanDyke Software公司开发的终端仿真软件 它提供了类似于Telnet和SSH等协议的远程访问功能 SecureCRT专门为网络管理员 系统管理员和其他需要保密访问网络设备的用户设计 软件下载 Secu
  • filter IE滤镜(Internet Explorer)CSS

    http justcoding iteye com blog 940184 概述 CSS滤镜虽然只能在IE浏览器中表现出效果 但是仍不失为网页增加特效的好办法 1 CSS静态滤镜样式 filter CSS静态滤镜样式的使用方法 filter
  • PlatformIO基于ESP32S2的SPI软串口LCD屏调试

    文章目录 VSCode PlatformIO Arduino ESP32S2 SPI LCD 320 240 一 准备工作 二 测试 1 全屏检测 2 图形测试 参考资料 VSCode PlatformIO Arduino ESP32S2
  • 基于SSM+Vue的网上拍卖系统

    末尾获取源码 开发语言 Java Java开发工具 JDK1 8 后端框架 SSM 前端 采用Vue技术开发 数据库 MySQL5 7和Navicat管理工具结合 服务器 Tomcat8 5 开发软件 IDEA Eclipse 是否Mave
  • Halcon: (示例 1)OCR 字符识别

    目录 示例 涉及算子描述 text line orientation hom mat2d identity hom mat2d rotate affine trans image dots image reduce domain vecto
  • Flutter 混合架构方案探索

    得益于 Flutter 优秀的跨平台表现 混合开发在如今的 App 中随处可见 如最近微信公布的小程序新渲染引擎 Skyline 发布正式版也在底层渲染上使用了 Flutter 号称渲染速度提升50 在现有的原生 App 中引入 Flutt
  • pnpm的原理和优势(monorepo)

    硬连接和软连接 硬连接 存储的物理磁盘上该文件的地址 比如 F 恭喜发财 mp4这个文件是一个硬连接 通过它可以找到物理磁盘上该 mp4 数据的地址 软件连 是一个引用 它存储的是硬连接的地址 简而言之 它保存的是文件路径F 恭喜发财 mp
  • 软件设计师学习笔记9-进程调度

    目录 1 PV操作 1 1进程的同步与互斥 1 1 1互斥 1 1 2同步 1 2 PV操作 1 2 1信号量 1 2 2 PV操作的概念 2 信号量与PV操作 2 1 PV操作与互斥模型 2 2 PV操作与同步模型 2 3 互斥与同步模型
  • 基于蒙特卡洛的强化学习方法【附带代码实现】

    基于蒙特卡洛的强化学习方法 蒙特卡洛方法 Monte Carlo methods 也被称为统计模拟方法 是一种基于概率统计的数值计算方法 运用蒙特卡洛方法时 我们通常使用重复随机抽样 然后运用概率统计方法来从抽样结果中归纳出我们想求的目标的