当前位置: 首页 > news >正文

【状态估计】线性高斯系统的状态估计——离散时间的递归滤波

前两篇文章介绍了离散时间的批量估计、离散时间的递归平滑,本文着重介绍离散时间的递归滤波。

前两篇位置:【状态估计】线性高斯系统的状态估计——离散时间的批量估计、【状态估计】线性高斯系统的状态估计——离散时间的递归平滑。


离散时间的递归滤波算法

批量优化的方案及其对应的平滑算法方案,是LG问题下能找到的最好的方法了。它利用了所有能用的数据,来估计所有时刻的状态。不过这个方法有一个致命的问题:无法在线运行,因为它需要用未来时刻的信息估计过去的状态。为了在实时场合下使用,当前时刻的状态只能由它之前时间的信息决定,而卡尔曼滤波则是对这样一个问题的传统解决方案

之前讲述了如何从Cholesky分解推导出卡尔曼滤波,实际上并不需要这么复杂,接下来介绍几种推导卡尔曼滤波的方法。

通过MAP推导卡尔曼滤波

假设已经有了 k − 1 k-1 k1时刻的前向估计:

{ x ^ k − 1 , P ^ k − 1 } \{\hat x_{k-1},\hat P_{k-1}\} {x^k1,P^k1}

这两个量是根据初始时刻到 k − 1 k-1 k1时刻的数据推导出来的。目标是计算:

{ x ^ k , P ^ k } \{\hat x_k,\hat P_k\} {x^k,P^k}

其中,需要用到直到 k k k时刻的数据。实际上没有必要再从初始时刻开始,而是简单地用 k − 1 k-1 k1时刻的状态,以及 k k k时刻的 v k v_k vk y k y_k yk就能估计出 k k k时刻的状态了:

{ x ^ k − 1 , P ^ k − 1 , v k , y k } − − > { x ^ k , P ^ k } \{\hat x_{k-1},\hat P_{k-1},v_k,y_k\}-->\{\hat x_k,\hat P_k\} {x^k1,P^k1,vk,yk}>{x^k,P^k}

为了推导这个过程,定义:

z = [ x ^ k − 1 v k y k ] z=\begin{bmatrix}\hat x_{k-1}\\v_k\\y_k\end{bmatrix} z= x^k1vkyk

H = [ 1 − A k − 1 1 C k ] H=\begin{bmatrix}1\\-A_{k-1}&1\\&C_k\end{bmatrix} H= 1Ak11Ck

W = [ P ^ k − 1 Q k R k ] W=\begin{bmatrix}\hat P_{k-1}\\&Q_k\\&&R_k\end{bmatrix} W= P^k1QkRk

x ^ = [ x ^ k − 1 ′ x ^ k ] \hat x=\begin{bmatrix}\hat x_{k-1}^{'}\\\hat x_k\end{bmatrix} x^=[x^k1x^k]

其中, x ^ k − 1 ′ \hat x_{k-1}^{'} x^k1表示使用了直到 k k k时刻的数据计算的 k − 1 k-1 k1时刻的状态估计,而 x ^ k − 1 \hat x_{k-1} x^k1表示使用了直到 k − 1 k-1 k1时刻的数据计算的 k − 1 k-1 k1时刻的状态估计,两者之间相差一个 k k k时刻的后向估计。

通常MAP的最优解 x ^ \hat x x^写成:

( H T W − 1 H ) x ^ = H T W − 1 z (H^TW^{-1}H)\hat x=H^TW^{-1}z (HTW1H)x^=HTW1z

将上面的定义代入:

[ P ^ k − 1 − 1 + A k − 1 T Q k − 1 A k − 1 − A k − 1 T Q k − 1 − Q k − 1 A k − 1 Q k − 1 + C k T R k − 1 C k ] [ x ^ k − 1 ′ x ^ k ] = [ P ^ k − 1 − 1 x ^ k − 1 − A k − 1 T Q k − 1 v k Q k − 1 v k + C k T R k − 1 y k ] \begin{bmatrix}\hat P_{k-1}^{-1}+A_{k-1}^TQ_k^{-1}A_{k-1}&-A_{k-1}^TQ_k^{-1}\\-Q_k^{-1}A_{k-1}&Q_k^{-1}+C_k^TR_k^{-1}C_k\end{bmatrix}\begin{bmatrix}\hat x_{k-1}^{'}\\\hat x_k\end{bmatrix}=\begin{bmatrix}\hat P_{k-1}^{-1}\hat x_{k-1}-A_{k-1}^TQ_k^{-1}v_k\\Q_k^{-1}v_k+C^T_kR_k^{-1}y_k\end{bmatrix} [P^k11+Ak1TQk1Ak1Qk1Ak1Ak1TQk1Qk1+CkTRk1Ck][x^k1x^k]=[P^k11x^k1Ak1TQk1vkQk1vk+CkTRk1yk]

由于并不关心 x ^ k − 1 ′ \hat x_{k-1}^{'} x^k1的实际值,因此可以将它边缘化,等式两侧左乘:

[ 1 0 Q k − 1 A k − 1 ( P ^ k − 1 − 1 + A k − 1 T Q k − 1 A k − 1 ) − 1 1 ] \begin{bmatrix}1&0\\Q_k^{-1}A_{k-1}(\hat P_{k-1}^{-1}+A_{k-1}^TQ_k^{-1}A_{k-1})^{-1}&1\end{bmatrix} [1Qk1Ak1(P^k11+Ak1TQk1Ak1)101]

这是一元线性方程的行操作,于是变成:

[ P ^ k − 1 − 1 + A k − 1 T Q k − 1 A k − 1 − A k − 1 T Q k − 1 0 Q k − 1 − Q k − 1 A k − 1 ( P ^ k − 1 − 1 + A k − 1 T Q k − 1 A k − 1 ) − 1 A k − 1 T Q k − 1 + C k T R k − 1 C k ] [ x ^ k − 1 ′ x ^ k ] = [ P ^ k − 1 − 1 x ^ k − 1 − A k − 1 T Q k − 1 v k Q k − 1 A k − 1 ( P ^ k − 1 − 1 + A k − 1 T Q k − 1 A k − 1 ) − 1 ( P ^ k − 1 − 1 x ^ k − 1 − A k − 1 T Q k − 1 v k ) + Q k − 1 v k + C k T R k − 1 y k ] \begin{bmatrix}\hat P_{k-1}^{-1}+A_{k-1}^TQ_k^{-1}A_{k-1}&-A_{k-1}^TQ_k^{-1}\\0&Q_k^{-1}-Q_k^{-1}A_{k-1}(\hat P_{k-1}^{-1}+A_{k-1}^TQ_k^{-1}A_{k-1})^{-1}A_{k-1}^TQ_k^{-1}+C_k^TR_k^{-1}C_k\end{bmatrix}\begin{bmatrix}\hat x_{k-1}^{'}\\\hat x_k\end{bmatrix}=\begin{bmatrix}\hat P_{k-1}^{-1}\hat x_{k-1}-A_{k-1}^TQ_k^{-1}v_k\\Q_k^{-1}A_{k-1}(\hat P_{k-1}^{-1}+A_{k-1}^TQ_k^{-1}A_{k-1})^{-1}(\hat P_{k-1}^{-1}\hat x_{k-1}-A_{k-1}^TQ_k^{-1}v_k)+Q_k^{-1}v_k+C_k^TR_k^{-1}y_k\end{bmatrix} [P^k11+Ak1TQk1Ak10Ak1TQk1Qk1Qk1Ak1(P^k11+Ak1TQk1Ak1)1Ak1TQk1+CkTRk1Ck][x^k1x^k]=[P^k11x^k1Ak1TQk1vkQk1Ak1(P^k11+Ak1TQk1Ak1)1(P^k11x^k1Ak1TQk1vk)+Qk1vk+CkTRk1yk]

因此,只需要关注 x ^ k \hat x_k x^k

( Q k − 1 − Q k − 1 A k − 1 ( P ^ k − 1 − 1 + A k − 1 T Q k − 1 A k − 1 ) − 1 A k − 1 T Q k − 1 + C k T R k − 1 C k ) x ^ k = Q k − 1 A k − 1 ( P ^ k − 1 − 1 + A k − 1 T Q k − 1 A k − 1 ) − 1 ( P ^ k − 1 − 1 x ^ k − 1 − A k − 1 T Q k − 1 v k ) + Q k − 1 v k + C k T R k − 1 y k (Q_k^{-1}-Q_k^{-1}A_{k-1}(\hat P_{k-1}^{-1}+A_{k-1}^TQ_k^{-1}A_{k-1})^{-1}A_{k-1}^TQ_k^{-1}+C_k^TR_k^{-1}C_k)\hat x_k=Q_k^{-1}A_{k-1}(\hat P_{k-1}^{-1}+A_{k-1}^TQ_k^{-1}A_{k-1})^{-1}(\hat P_{k-1}^{-1}\hat x_{k-1}-A_{k-1}^TQ_k^{-1}v_k)+Q_k^{-1}v_k+C_k^TR_k^{-1}y_k (Qk1Qk1Ak1(P^k11+Ak1TQk1Ak1)1Ak1TQk1+CkTRk1Ck)x^k=Qk1Ak1(P^k11+Ak1TQk1Ak1)1(P^k11x^k1Ak1TQk1vk)+Qk1vk+CkTRk1yk

根据SMW恒等式:

Q k − 1 − Q k − 1 A k − 1 ( P ^ k − 1 − 1 + A k − 1 T Q k − 1 A k − 1 ) − 1 A k − 1 T Q k − 1 = ( Q k + A k − 1 P ^ k − 1 A k − 1 T ) − 1 Q_k^{-1}-Q_k^{-1}A_{k-1}(\hat P_{k-1}^{-1}+A_{k-1}^TQ_k^{-1}A_{k-1})^{-1}A_{k-1}^TQ_k^{-1}=(Q_k+A_{k-1}\hat P_{k-1}A_{k-1}^T)^{-1} Qk1Qk1Ak1(P^k11+Ak1TQk1Ak1)1Ak1TQk1=(Qk+Ak1P^k1Ak1T)1

定义:

P ˇ k = Q k + A k − 1 P ^ k − 1 A k − 1 T \check P_k=Q_k+A_{k-1}\hat P_{k-1}A_{k-1}^T Pˇk=Qk+Ak1P^k1Ak1T

P ^ k = ( P ˇ k − 1 + C k T R k − 1 C k ) − 1 \hat P_k=(\check P_k^{-1}+C_k^TR_k^{-1}C_k)^{-1} P^k=(Pˇk1+CkTRk1Ck)1

原式可化简为:

P ^ k − 1 x ^ k = Q k − 1 A k − 1 ( P ^ k − 1 − 1 + A k − 1 T Q k − 1 A k − 1 ) − 1 ( P ^ k − 1 − 1 x ^ k − 1 − A k − 1 T Q k − 1 v k ) + Q k − 1 v k + C k T R k − 1 y k = Q k − 1 A k − 1 ( P ^ k − 1 − 1 + A k − 1 T Q k − 1 A k − 1 ) − 1 P ^ k − 1 − 1 x ^ k − 1 + ( Q k − 1 − Q k − 1 A k − 1 ( P ^ k − 1 − 1 + A k − 1 T Q k − 1 A k − 1 ) − 1 A k − 1 T Q k − 1 ) v k + C k T R k − 1 y k = P ˇ k − 1 A k − 1 x ^ k − 1 + P ˇ k − 1 v k + C k T R k − 1 y k = P ˇ k − 1 ( A k − 1 x ^ k − 1 + v k ) + C k T R k − 1 y k = P ˇ k − 1 x ˇ k + C k T R k − 1 y k \begin{aligned}\hat P_k^{-1}\hat x_k&=Q_k^{-1}A_{k-1}(\hat P_{k-1}^{-1}+A_{k-1}^TQ_k^{-1}A_{k-1})^{-1}(\hat P_{k-1}^{-1}\hat x_{k-1}-A_{k-1}^TQ_k^{-1}v_k)+Q_k^{-1}v_k+C_k^TR_k^{-1}y_k \\&=Q_k^{-1}A_{k-1}(\hat P_{k-1}^{-1}+A_{k-1}^TQ_k^{-1}A_{k-1})^{-1}\hat P_{k-1}^{-1}\hat x_{k-1}+(Q_k^{-1}-Q_k^{-1}A_{k-1}(\hat P_{k-1}^{-1}+A_{k-1}^TQ_k^{-1}A_{k-1})^{-1}A_{k-1}^TQ_k^{-1})v_k+C_k^TR_k^{-1}y_k \\&=\check P_k^{-1}A_{k-1}\hat x_{k-1}+\check P_k^{-1}v_k+C_k^TR_k^{-1}y_k \\ &=\check P_k^{-1}(A_{k-1}\hat x_{k-1}+v_k)+C_k^TR_k^{-1}y_k \\ &=\check P_k^{-1}\check x_k+C_k^TR_k^{-1}y_k\end{aligned} P^k1x^k=Qk1Ak1(P^k11+Ak1TQk1Ak1)1(P^k11x^k1Ak1TQk1vk)+Qk1vk+CkTRk1yk=Qk1Ak1(P^k11+Ak1TQk1Ak1)1P^k11x^k1+(Qk1Qk1Ak1(P^k11+Ak1TQk1Ak1)1Ak1TQk1)vk+CkTRk1yk=Pˇk1Ak1x^k1+Pˇk1vk+CkTRk1yk=Pˇk1(Ak1x^k1+vk)+CkTRk1yk=Pˇk1xˇk+CkTRk1yk

梳理一下整个过程:

预测:

x ˇ k = A k − 1 x ^ k − 1 + v k P ˇ k = A k − 1 P ^ k − 1 A k − 1 T + Q k \begin{aligned}\check x_k&=A_{k-1}\hat x_{k-1}+v_k \\ \check P_k&=A_{k-1}\hat P_{k-1}A_{k-1}^T+Q_k\end{aligned} xˇkPˇk=Ak1x^k1+vk=Ak1P^k1Ak1T+Qk

更新:

P ^ k = ( P ˇ k − 1 + C k T R k − 1 C k ) − 1 P ^ k − 1 x ^ k = P ˇ k − 1 x ˇ k + C k T R k − 1 y k \begin{aligned}\hat P_k&=(\check P_k^{-1}+C_k^TR_k^{-1}C_k)^{-1} \\ \hat P_k^{-1}\hat x_k&=\check P_k^{-1}\check x_k+C_k^TR_k^{-1}y_k\end{aligned} P^kP^k1x^k=(Pˇk1+CkTRk1Ck)1=Pˇk1xˇk+CkTRk1yk

这是逆协方差形式(信息形式)的卡尔曼滤波。为了得到经典形式的卡尔曼滤波,需要定义卡尔曼增益 K k K_k Kk

K k = P ^ k C k T R k − 1 K_k=\hat P_kC_k^TR_k^{-1} Kk=P^kCkTRk1

经过化简,更新:

K k = P ˇ k C k T ( C k P ˇ k C k T + R k ) − 1 P ^ k = ( 1 − K k C k ) P ˇ k x ^ k = x ˇ k + K k ( y k − C k x ˇ k ) \begin{aligned}K_k&=\check P_kC_k^T(C_k\check P_kC_k^T+R_k)^{-1} \\ \hat P_k&=(1-K_kC_k)\check P_k \\\hat x_k&=\check x_k+K_k(y_k-C_k\check x_k)\end{aligned} KkP^kx^k=PˇkCkT(CkPˇkCkT+Rk)1=(1KkCk)Pˇk=xˇk+Kk(ykCkxˇk)

其中, y k − C k x ˇ k y_k-C_k\check x_k ykCkxˇk称为更新量,指的是实际与期望观测量的误差,而卡尔曼增益则是这部分更新量对估计值的权重。

通过贝叶斯推断推导卡尔曼滤波

使用贝叶斯推断方法还能够以更简洁的方式推出卡尔曼滤波。假设 k − 1 k-1 k1时刻的高斯先验为:

p ( x k − 1 ∣ x ˇ 0 , v 1 : k − 1 , y 0 : k − 1 ) = N ( x ^ k − 1 , P ^ k − 1 ) p(x_{k-1}|\check x_0,v_{1:k-1},y_{0:k-1})=N(\hat x_{k-1},\hat P_{k-1}) p(xk1xˇ0,v1:k1,y0:k1)=N(x^k1,P^k1)

首先,对于预测部份,考虑最近时刻的输入 v k v_{k} vk,来计算 k k k时刻的先验:

p ( x k ∣ x ˇ 0 , v 1 : k , y 0 : k − 1 ) = N ( x ˇ k , P ˇ k ) p(x_k|\check x_0,v_{1:k},y_{0:k-1})=N(\check x_k,\check P_k) p(xkxˇ0,v1:k,y0:k1)=N(xˇk,Pˇk)

其中:

x ˇ k = E [ x k ] = E [ A k − 1 x k − 1 + v k + w k ] = A k − 1 x ^ k − 1 + v k \check x_k=E[x_k]=E[A_{k-1}x_{k-1}+v_k+w_k]=A_{k-1}\hat x_{k-1}+v_k xˇk=E[xk]=E[Ak1xk1+vk+wk]=Ak1x^k1+vk

P ˇ k = E [ ( x k − E [ x k ] ) ( x k − E [ x k ] ) T ] = A k − 1 E [ ( x k − 1 − x ^ k − 1 ) ( x k − 1 − x ^ k − 1 ) T ] A k − 1 T + E [ w k w k t ] = A k − 1 P ^ k − 1 A k − 1 T + Q k \begin{aligned}\check P_k&=E[(x_k-E[x_k])(x_k-E[x_k])^T]\\&=A_{k-1}E[(x_{k-1}-\hat x_{k-1})(x_{k-1}-\hat x_{k-1})^T]A_{k-1}^T+E[w_kw_k^t]\\&=A_{k-1}\hat P_{k-1}A_{k-1}^T+Q_k\end{aligned} Pˇk=E[(xkE[xk])(xkE[xk])T]=Ak1E[(xk1x^k1)(xk1x^k1)T]Ak1T+E[wkwkt]=Ak1P^k1Ak1T+Qk

然后,对于更新部分,将状态与最新一次测量(即 k k k时刻)写成联合高斯分布的形式

p ( x k , y k ∣ x ˇ 0 , v 1 : k , y 0 : k − 1 ) = N ( [ μ x μ y ] , [ Σ x x Σ x y Σ y x Σ y y ] ) = N ( [ x ˇ k C k x ˇ k ] , [ P ˇ k P ˇ k C k T C k P ˇ k C k P ˇ k C k T + R k ] ) p(x_k,y_k|\check x_0,v_{1:k},y_{0:k-1})=N(\begin{bmatrix}\mu_x\\\mu_y\end{bmatrix},\begin{bmatrix}\Sigma_{xx}&\Sigma_{xy}\\\Sigma_{yx}&\Sigma_{yy}\end{bmatrix})=N(\begin{bmatrix}\check x_k\\C_k\check x_k\end{bmatrix},\begin{bmatrix}\check P_k&\check P_kC_k^T\\C_k\check P_k&C_k\check P_kC_k^T+R_k\end{bmatrix}) p(xk,ykxˇ0,v1:k,y0:k1)=N([μxμy],[ΣxxΣyxΣxyΣyy])=N([xˇkCkxˇk],[PˇkCkPˇkPˇkCkTCkPˇkCkT+Rk])

根据高斯推断,可以得到:

p ( x k ∣ x ˇ 0 , v 1 : k , y 0 : k ) = N ( μ x + Σ x y Σ y y − 1 ( y k − μ y ) , Σ x x − Σ x y Σ y y − 1 Σ y x ) p(x_k|\check x_0,v_{1:k},y_{0:k})=N(\mu_x+\Sigma_{xy}\Sigma_{yy}^{-1}(y_k-\mu_y),\Sigma_{xx}-\Sigma_{xy}\Sigma_{yy}^{-1}\Sigma_{yx}) p(xkxˇ0,v1:k,y0:k)=N(μx+ΣxyΣyy1(ykμy),ΣxxΣxyΣyy1Σyx)

代入之前的结果,有:

K k = P ˇ k C k T ( C k P ˇ k C k T + R k ) − 1 P ^ k = ( 1 − K k C k ) P ˇ k x ^ k = x ˇ k + K k ( y k − C k x ˇ k ) \begin{aligned}K_k&=\check P_kC_k^T(C_k\check P_kC_k^T+R_k)^{-1} \\ \hat P_k&=(1-K_kC_k)\check P_k \\ \hat x_k&=\check x_k+K_k(y_k-C_k\check x_k)\end{aligned} KkP^kx^k=PˇkCkT(CkPˇkCkT+Rk)1=(1KkCk)Pˇk=xˇk+Kk(ykCkxˇk)

这与MAP给出的更新步骤的方程是完全一致的。

重申一遍,这件事情的根本在于使用了线性模型,且噪声和先验也都是高斯的。在这些条件下,后验概率也是高斯的,于是它的均值和模正巧是一样的。然而在使用非线性模型之后就不能保证这个性质了

从增益最优化的角度来看卡尔曼滤波

通常来说,卡尔曼滤波是线性高斯系统下的最优解。因此,也可以从其他的角度来看卡尔曼滤波的最优特性。下面介绍其中的一个:

假设有一个估计器,形式如下:

x ^ k = x ˇ k + K k ( y k − C k x ˇ k ) \hat x_k=\check x_k+K_k(y_k-C_k\check x_k) x^k=xˇk+Kk(ykCkxˇk)

但是此时并不知道如何选取 K k K_k Kk的值,才能正确地衡量修正部分的权重。如果定义状态的误差为(估计值 - 真值):

e ^ k = x ^ k − x k \hat e_k=\hat x_k-x_k e^k=x^kxk

那么有:

P ^ k = E [ e ^ k e ^ k T ] = E [ ( x ^ k − x k ) ( x ^ k − x k ) T ] = E [ ( x ˇ k + K k ( C k x k + n k − C k x ˇ k ) − x k ) ( x ˇ k + K k ( C k x k + n k − C k x ˇ k ) − x k ) T ] = E [ ( ( 1 − K k C k ) ( x ˇ k − x k ) + K k n k ) ( ( 1 − K k C k ) ( x ˇ k − x k ) + K k n k ) T ] = ( 1 − K k C k ) E [ ( x ˇ k − x k ) ( x ˇ k − x k ) T ] ( 1 − K k C k ) T + K k E [ C k C k T ] K k T = ( 1 − K k C k ) P ˇ k ( 1 − K k C k ) T + K k R k K k T = P ˇ k − K k C k P ˇ k − P ˇ k C k T K k T + K k ( C k P ˇ k C k T + R k ) K k T \begin{aligned}\hat P_k&=E[\hat e_k\hat e_k^T]\\&=E[(\hat x_k-x_k)(\hat x_k-x_k)^T]\\&=E[(\check x_k+K_k(C_kx_k+n_k-C_k\check x_k)-x_k)(\check x_k+K_k(C_kx_k+n_k-C_k\check x_k)-x_k)^T]\\&=E[((1-K_kC_k)(\check x_k-x_k)+K_kn_k)((1-K_kC_k)(\check x_k-x_k)+K_kn_k)^T]\\&=(1-K_kC_k)E[(\check x_k-x_k)(\check x_k-x_k)^T](1-K_kC_k)^T+K_kE[C_kC_k^T]K_k^T\\&=(1-K_kC_k)\check P_k(1-K_kC_k)^T+K_kR_kK_k^T \\ &=\check P_k-K_kC_k\check P_k-\check P_kC_k^TK_k^T+K_k(C_k\check P_kC_k^T+R_k)K_k^T\end{aligned} P^k=E[e^ke^kT]=E[(x^kxk)(x^kxk)T]=E[(xˇk+Kk(Ckxk+nkCkxˇk)xk)(xˇk+Kk(Ckxk+nkCkxˇk)xk)T]=E[((1KkCk)(xˇkxk)+Kknk)((1KkCk)(xˇkxk)+Kknk)T]=(1KkCk)E[(xˇkxk)(xˇkxk)T](1KkCk)T+KkE[CkCkT]KkT=(1KkCk)Pˇk(1KkCk)T+KkRkKkT=PˇkKkCkPˇkPˇkCkTKkT+Kk(CkPˇkCkT+Rk)KkT

接下来最小均方差开始正式登场了。由于协方差矩阵的对角线元素就是方差,这样一来,把协方差矩阵的对角线元素求和,用 t r tr tr来表示这种算子,它的学名叫矩阵的迹。

于是,可以由它定义出一个代价函数:

J ( K k ) = t r ( E [ e ^ k e ^ k T ] ) = t r ( P ˇ k ) − 2 t r ( K k C k P ˇ k ) + t r ( K k ( C k P ˇ k C k T + R k ) K k T ) \begin{aligned}J(K_k)&=tr(E[\hat e_k\hat e_k^T])\\&=tr(\check P_k)-2tr(K_kC_k\check P_k)+tr(K_k(C_k\check P_kC_k^T+R_k)K_k^T)\end{aligned} J(Kk)=tr(E[e^ke^kT])=tr(Pˇk)2tr(KkCkPˇk)+tr(Kk(CkPˇkCkT+Rk)KkT)

最小均方差就是使得 J ( K k ) J(K_k) J(Kk)最小,对未知量 K k K_k Kk求导,令导函数等于0:

d J ( K k ) d K k = − 2 ( C k P ˇ k ) T + 2 K k ( C k P ˇ k C k T + R k ) \frac{dJ(K_k)}{dK_k}=-2(C_k\check P_k)^T+2K_k(C_k\check P_kC_k^T+R_k) dKkdJ(Kk)=2(CkPˇk)T+2Kk(CkPˇkCkT+Rk)

因此:

K k = P ˇ k C k T ( C k P ˇ k C k T + R k ) − 1 K_k=\check P_kC_k^T(C_k\check P_kC_k^T+R_k)^{-1} Kk=PˇkCkT(CkPˇkCkT+Rk)1

这正是卡尔曼增益的通常表达式。

关于卡尔曼滤波的讨论

以下是卡尔曼滤波的要点:

  1. 对于高斯噪声的线性系统,卡尔曼滤波器是最优线性无偏估计
  2. 必须有初始状态: { x ˇ 0 , P ˇ 0 } \{\check x_0,\check P_0\} {xˇ0,Pˇ0}
  3. 协方差部分与均值部分可以独立地递推。有时甚至可以计算一个固定的 K k K_k Kk,用于所有时刻的均值修正,这种做法称为固定状态的卡尔曼滤波。

相关文章:

【状态估计】线性高斯系统的状态估计——离散时间的递归滤波

前两篇文章介绍了离散时间的批量估计、离散时间的递归平滑,本文着重介绍离散时间的递归滤波。 前两篇位置:【状态估计】线性高斯系统的状态估计——离散时间的批量估计、【状态估计】线性高斯系统的状态估计——离散时间的递归平滑。 离散时间的递归滤波…...

架构设计上中的master三种架构,单节点,主从节点,多节点分析

文章目录 背景单节点优点缺点 主从节点优点缺点 多节点优点缺点 多节点,多backup设计优点缺点 总结 背景 在很多分布式系统里会有master,work这种结构。 master 节点负责管理资源,分发任务。下面着重讨论下master 数量不同带来的影响 单节点 优点 1.设…...

如何在 SQL 中删除一条记录?

如何在 SQL 中删除一条记录? 在 SQL 中,您可以使用DELETE查询和WHERE子句删除表中的一条记录。在本文中,我将向您介绍如何使用DELETE查询和WHERE子句删除记录。我还将向您展示如何一次从表中删除多条记录 如何在 SQL 中使用 DELETE 这是使…...

JavaSE (Java基础):面向对象(上)

8 面向对象 面向对象编程的本质就是:以类的方法组织代码,以对象的组织(封装)数据。 8.1 方法的回顾 package com.oop.demo01;// Demo01 类 public class Demo01 {// main方法public static void main(String[] args) {int c 10…...

flink使用StatementSet降低资源浪费

背景 项目中有很多ods层(mysql 通过cannal)kafka,需要对这些ods kakfa做一些etl操作后写入下一层的kafka(dwd层)。 一开始采用的是executeSql方式来执行每个ods→dwd层操作,即类似: def main(…...

FineDataLink4.1.9支持Kettle调用

FDL更新至4.1.9后,新增kettle调用功能,支持不增加额外负担的情况下,将现有的Kettle任务平滑迁移到FineDataLink。 一、更新版本前存在的问题与痛点 在此次功能更新前,用户可能会遇到以下问题: 1.对于仅使用kettle的…...

SwanLinkOS首批实现与HarmonyOS NEXT互联互通,软通动力子公司鸿湖万联助力鸿蒙生态统一互联

在刚刚落下帷幕的华为开发者大会2024上,伴随全场景智能操作系统HarmonyOS Next的盛大发布,作为基于OpenHarmony的同根同源系统生态,软通动力子公司鸿湖万联全域智能操作系统SwanLinkOS首批实现与HarmonyOS NEXT互联互通,率先攻克基…...

Win11禁止右键菜单折叠的方法

背景 在使用windows11的时候,会发现默认情况下,右键菜单折叠了。以至于在使用一些软件的右键菜单时总是要点击“显示更多选项”菜单展开所有菜单,然后再点击。而且每次在显示菜单时先是全部展示,再隐藏一下,看着着实难…...

Maven列出所有的依赖树

在 IntelliJ IDEA 中,你可以使用 Maven 插件来列出项目的依赖树。Maven 插件提供了一个名为dependency:tree的目标,可以帮助你获取项目的依赖树详细信息。 要列出项目的依赖树,可以执行以下步骤: 打开 IntelliJ IDEA,…...

测试开发面试题和答案

Python 请解释Python中的列表推导式(List Comprehension)是什么,并给出一个示例。 答案: 列表推导式是Python中一种简洁的构建列表的方法。它允许从一个已存在的列表创建新列表,同时应用一个表达式来修改或选择元素。…...

llm学习-3(向量数据库的使用)

1:数据读取和加载 接着上面的常规操作 加载环境变量---》获取所有路径---》加载文档---》切分文档 代码如下: import os from dotenv import load_dotenv, find_dotenvload_dotenv(find_dotenv()) # 获取folder_path下所有文件路径,储存在…...

【01-02】Mybatis的配置文件与基于XML的使用

1、引入日志 在这里我们引入SLF4J的日志门面&#xff0c;使用logback的具体日志实现&#xff1b;引入相关依赖&#xff1a; <!--日志的依赖--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version&g…...

Linux-进程间通信(IPC)

进程间通信&#xff08;IPC&#xff09;介绍 进程间通信&#xff08;IPC&#xff0c;InterProcess Communication&#xff09;是指在不同的进程之间传播或交换信息。IPC 的方式包括管道&#xff08;无名管道和命名管道&#xff09;、消息队列、信号量、共享内存、Socket、Stre…...

C++ STL: std::vector与std::array的深入对比

什么是 std::vector 和 std::array 首先&#xff0c;让我们简要介绍一下这两种容器&#xff1a; • std::vector&#xff1a;一个动态数组&#xff0c;可以根据需要动态调整其大小。 • std::array&#xff1a;一个固定大小的数组&#xff0c;其大小在编译时确定。 虽然…...

哈哈看到这条消息感觉就像是打开了窗户

在这个信息爆炸的时代&#xff0c;每一条动态可能成为我们情绪的小小触发器。今天&#xff0c;当我无意间滑过那条由杜海涛亲自发布的“自曝式”消息时&#xff0c;不禁心头一颤——如果这是我的另一半&#xff0c;哎呀&#xff0c;那画面&#xff0c;简直比烧烤摊还要“热辣”…...

10、matlab中字符、数字、矩阵、字符串和元胞合并为字符串并将字符串以不同格式写入读出excel

1、前言 在 MATLAB 中&#xff0c;可以使用不同的数据类型&#xff08;字符、数字、矩阵、字符串和元胞&#xff09;合并为字符串&#xff0c;然后将字符串以不同格式写入 Excel 文件。 以下是一个示例代码&#xff0c;展示如何将不同数据类型合并为字符串&#xff0c;并以不…...

如何正确面对GPT-5技术突破

随着人工智能技术的快速发展&#xff0c;预训练语言模型在自然语言处理领域取得了显著的成果。其中&#xff0c;GPT系列模型作为代表之一&#xff0c;受到了广泛关注。2023年&#xff0c;GPT-5模型的发布引起了业界的热烈讨论。本文将从以下几个方面分析GPT-5的发布及其对人工智…...

HarmonyOS ArkUi 官网踩坑:单独隐藏导航条无效

环境&#xff1a; 手机&#xff1a;Mate 60 Next版本&#xff1a; NEXT.0.0.26 导航条介绍 导航条官网设计指南 setSpecificSystemBarEnabled 设置实际效果&#xff1a; navigationIndicator&#xff1a;隐藏导航条无效status&#xff1a;会把导航条和状态栏都隐藏 官方…...

解决跨域问题(vite、axios/koa)

两种方法选其一即可 一、后端koa设置中间件 app.use(async (ctx, next)> {ctx.set(Access-Control-Allow-Origin, *);ctx.set(Access-Control-Allow-Headers, Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild);ctx.set(Access-C…...

echarts实现3D柱状图(视觉层面)

一、第一种效果 效果图 使用步骤 完整实例&#xff0c;copy就可直接使用 <template><div :class"className" :style"{height:height,width:width}" /> </template><script>import echarts from echartsrequire(echarts/theme/…...

K8S集群进行分布式负载测试

使用K8S集群执行分布式负载测试 本教程介绍如何使用Kubernetes部署分布式负载测试框架&#xff0c;该框架使用分布式部署的locust 产生压测流量&#xff0c;对一个部署到 K8S集群的 Web 应用执行负载测试&#xff0c;该 Web 应用公开了 REST 格式的端点&#xff0c;以响应传入…...

20.《C语言》——【移位操作符】

&#x1f339;开场语 亲爱的读者&#xff0c;大家好&#xff01;我是一名正在学习编程的高校生。在这个博客里&#xff0c;我将和大家一起探讨编程技巧、分享实用工具&#xff0c;并交流学习心得。希望通过我的博客&#xff0c;你能学到有用的知识&#xff0c;提高自己的技能&a…...

你想活出怎样的人生?

hi~好久不见&#xff0c;距离上次发文隔了有段时间了&#xff0c;这段时间&#xff0c;我是裸辞去感受了一下前端市场的水深火热&#xff0c;那么这次咱们不聊技术&#xff0c;就说一说最近这段时间的经历和一些感触吧。 先说一下自己的个人情况&#xff0c;目前做前端四年&am…...

py黑帽子学习笔记_burp

配置burp kali虚机默认装好了社区版burp和java&#xff0c;其他os需要手动装 burp是用java&#xff0c;还得下载一个jython包&#xff0c;供burp用 配apt国内源&#xff0c;然后apt install jython --download-only&#xff0c;会只下载包而不安装&#xff0c;下载的目录搜一…...

selenium,在元素块下查找条件元素

def get_norms_ele_text(self):elementsself.get_norms_elements()locBy.CSS_SELECTOR,"div.sku-select-row-label"by loc[0] # 获取By类型&#xff0c;例如By.CSS_SELECTORvalue loc[1] # 获取具体的CSS选择器字符串&#xff0c;例如"div.sku-select-row-l…...

认识String类

文章目录 String类字符串的遍历字符串的比较字符串的替换字符串的转换字符串的切割字符串的切片字符串的查找 总结 String类 在C语言中已经涉及到字符串了&#xff0c;但是在C语言中要表示字符串只能使用字符数组或者字符指针&#xff0c;可以使用标准库提 供的字符串系列函数完…...

计算机图形学入门23:蒙特卡洛路径追踪

1.前言 前面几篇文章介绍了Whitted-style光线追踪&#xff0c;还介绍了基于物理渲染的基础知识&#xff0c;包括辐射度量学、BRDF以及渲染方程&#xff0c;但并没有给出解渲染方程的方法&#xff0c;或者说如何通过该渲染方程计算出屏幕上每一个坐标的像素值。 Whitted-style光…...

探索 TensorFlow 模型的秘密:TensorBoard 详解与实战

简介 TensorBoard 是 TensorFlow 提供的可视化工具&#xff0c;帮助开发者监控和调试机器学习模型。它提供了多种功能&#xff0c;包括查看损失和精度曲线、可视化计算图、检查数据分布等。下面将介绍如何使用 TensorBoard。 1. 安装 TensorBoard 如果尚未安装 TensorBoard&…...

yolov8obb角度预测原理解析

预测头 ultralytics/nn/modules/head.py class OBB(Detect):"""YOLOv8 OBB detection head for detection with rotation models."""def __init__(self, nc80, ne1, ch()):"""Initialize OBB with number of classes nc and la…...

CICD之Git版本管理及基本应用

CICD:持续集成,持续交付--让对应的资料,对应的项目流程更加规范--提高效率 CICD 有很多的工具 GIT就是其中之一 1.版本控制概念与环境搭建 GIT的概念: Git是一款分布式源代码管理工具(版本控制工具) ,一个协同的工具。 Git得其数据更像是一系列微型文件系统的快照。使用Git&am…...

Python作用域及其应用

Python的作用域规则决定了变量在代码中的可见性和访问性。全局作用域中定义的变量可以在整个程序中访问&#xff0c;而局部作用域中定义的变量则只能在其被创建的函数或代码块中访问。 全局作用域与局部作用域 全局作用域中的变量通常在程序的顶层定义&#xff0c;可以被整个…...

谷歌上架,应用被Google play下架之后,活跃用户会暴跌?这是为什么?

在Google play上架应用&#xff0c;开发者们最不想到看到就是应用被下架了。这意味着所有的努力都将付诸东流&#xff0c;因为有的应用一但被下架&#xff0c;活跃用户也随之嗖嗖地往下掉&#xff0c;这事儿可真不是闹着玩的&#xff0c;严重影响了收益&#xff01; 为什么你的…...

web安全渗透测试十大常规项(一):web渗透测试之Fastjson反序列化

渗透测试之Java反序列化 1. Fastjson反序列化1.1 FastJson反序列化链知识点1.2 FastJson反序列化链分析1.3.1 FastJson 1.2.24 利用链分析1.3.2 FastJson 1.2.25-1.2.47 CC链分析1.3.2.1、开启autoTypeSupport:1.2.25-1.2.411.3.2.2 fastjson-1.2.42 版本绕过1.3.2.3 fastjson…...

Unity 3D软件下载安装;Unity 3D游戏制作软件资源包获取!

Unity3D&#xff0c;它凭借强大的功能和灵活的特性&#xff0c;在游戏开发和互动内容创作领域发挥着举足轻重的作用。 作为一款顶尖的游戏引擎&#xff0c;Unity3D内置了先进的物理引擎——PhysX。这一物理引擎堪称业界翘楚&#xff0c;能够为开发者提供全方位、高精度的物理模…...

PyTorch之nn.Module与nn.functional用法区别

文章目录 1. nn.Module2. nn.functional2.1 基本用法2.2 常用函数 3. nn.Module 与 nn.functional3.1 主要区别3.2 具体样例&#xff1a;nn.ReLU() 与 F.relu() 参考资料 1. nn.Module 在PyTorch中&#xff0c;nn.Module 类扮演着核心角色&#xff0c;它是构建任何自定义神经网…...

2024.06.24 校招 实习 内推 面经

绿*泡*泡VX&#xff1a; neituijunsir 交流*裙 &#xff0c;内推/实习/校招汇总表格 1、校招 | 昂瑞微2025届校园招聘正式启动 校招 | 昂瑞微2025届校园招聘正式启动 2、实习 | 东风公司研发总院暑期实习生火爆招募中 实习 | 东风公司研发总院暑期实习生火爆招募中 3、实习…...

【C++】using namespace std 到底什么意思

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文作为 JohnKi 的学习笔记&#xff0c;引用了部分大佬的案例 &#x1f4e2;未来很长&a…...

基于ESP32 IDF的WebServer实现以及OTA固件升级实现记录(三)

经过前面两篇的前序铺垫&#xff0c;对webserver以及restful api架构有了大体了解后本篇描述下最终的ota实现的代码以及调试中遇到的诡异bug。 eps32的实际ota实现过程其实esp32官方都已经基本实现好了&#xff0c;我们要做到无非就是把要升级的固件搬运到对应ota flash分区里面…...

116-基于5VLX110T FPGA FMC接口功能验证6U CPCI平台

一、板卡概述 本板卡是Xilinx公司芯片V5系列芯片设计信号处理板卡。由一片Xilinx公司的XC5VLX110T-1FF1136 / XC5VSX95T-1FF1136 / XC5VFX70T-1FF1136芯片组成。FPGA接1片DDR2内存条 2GB&#xff0c;32MB Nor flash存储器&#xff0c;用于存储程序。外扩 SATA、PCI、PCI expres…...

Android - Json/Gson

Json数据解析 json对象&#xff1a;花括号开头和结尾&#xff0c;中间是键值对形式————”属性”:属性值”” json数组&#xff1a;中括号里放置 json 数组&#xff0c;里面是多个json对象或者数字等 JSONObject 利用 JSONObject 解析 1.创建 JSONObject 对象&#xff0c;传…...

盲信号处理的发展现状

盲源分离技术最早在上个世纪中期提出&#xff0c;在1991年Herault和Jutten提出基于反馈神经网络的盲源分离方法&#xff0c;但该方法缺乏理论基础&#xff0c;后来Tong和Liu分析了盲源分离问题的可辨识性和不确定性&#xff0c;Cardoso于1993年提出了基于高阶统计的联合对角化盲…...

二轴机器人装箱机:重塑物流效率,精准灵活,引领未来装箱新潮流

在现代化物流领域&#xff0c;高效、精准与灵活性无疑是各大企业追求的核心目标。而在这个日益追求自动化的时代&#xff0c;二轴机器人装箱机凭借其较佳的性能和出色的表现&#xff0c;正逐渐成为装箱作业的得力助手&#xff0c;引领着未来装箱新潮流。 一、高效&#xff1a;重…...

使用python做飞机大战

代码地址: 点击跳转...

Python面向对象编程:派生

本套课在线学习视频&#xff08;网盘地址&#xff0c;保存到网盘即可免费观看&#xff09;&#xff1a; ​​https://pan.quark.cn/s/69d1cc25d4ba​​ 面向对象编程&#xff08;OOP&#xff09;是一种编程范式&#xff0c;它通过将数据和操作数据的方法封装在一起&#xff0…...

华为仓颉编程语言

目录 一、引言 二、仓颉编程语言概述 三、技术特征 四、应用场景 五、社区支持 六、结论与展望 一、引言 随着信息技术的快速发展&#xff0c;编程语言作为软件开发的核心工具&#xff0c;其重要性日益凸显。近年来&#xff0c;华为公司投入大量研发资源&#xff0c;成功…...

【微信小程序开发实战项目】——如何制作一个属于自己的花店微信小程序(2)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…...

解锁数据资产的无限潜能:深入探索创新的数据分析技术,挖掘其在实际应用场景中的广阔价值,助力企业发掘数据背后的深层信息,实现业务的持续增长与创新

目录 一、引言 二、创新数据分析技术的发展 1、大数据分析技术 2、人工智能与机器学习 3、可视化分析技术 三、创新数据分析技术在实际应用场景中的价值 1、市场洞察与竞争分析 2、客户细分与个性化营销 3、业务流程优化与风险管理 4、产品创新与研发 四、案例分析 …...

Bridging nonnull in Objective-C to Swift: Is It Safe?

Bridging nonnull in Objective-C to Swift: Is It Safe? In the world of iOS development, bridging between Objective-C and Swift is a common practice, especially for legacy codebases (遗留代码库) or when integrating (集成) third-party libraries. One importa…...

算法训练 | 图论Part1 | 98.所有可达路径

目录 98.所有可达路径 深度搜索法 98.所有可达路径 题目链接&#xff1a;98. 所有可达路径 文章讲解&#xff1a;代码随想录 深度搜索法 代码一&#xff1a;邻接矩阵写法 #include <iostream> #include <vector> using namespace std; vector<vector<…...

【JVM基础篇】垃圾回收

文章目录 垃圾回收常见内存管理方式手动回收&#xff1a;C内存管理自动回收(GC)&#xff1a;Java内存管理自动、手动回收优缺点 应用场景垃圾回收器需要对哪些部分内存进行回收&#xff1f;不需要垃圾回收器回收需要垃圾回收器回收 方法区的回收代码测试手动调用垃圾回收方法Sy…...

pytest-yaml-sanmu(七):使用fixture返回值

fixture 是 pytest 中非常重要的功能&#xff0c;大部分项目都可能会用到 fixture。 pytest 的内置标记 usefixtures 可以帮助用例自动的使用 fixture 1. 创建 fixture pytest 中的 fixtures 大致有两个用途 在用例执行之前、执行之后&#xff0c;自动的执行 通过 fixture …...

ES6模块化学习

1. 回顾&#xff1a;node.js 中如何实现模块化 node.js 遵循了 CommonJS 的模块化规范。其中&#xff1a; 导入其它模块使用 require() 方法 模块对外共享成员使用 module.exports 对象 模块化的好处&#xff1a; 大家都遵守同样的模块化规范写代码&#xff…...

从零开始使用WordPress搭建个人网站并一键发布公网详细教程

文章目录 前言1. 搭建网站&#xff1a;安装WordPress2. 搭建网站&#xff1a;创建WordPress数据库3. 搭建网站&#xff1a;安装相对URL插件4. 搭建网站&#xff1a;内网穿透发布网站4.1 命令行方式&#xff1a;4.2. 配置wordpress公网地址 5. 固定WordPress公网地址5.1. 固定地…...

边缘计算节点 BEC 实践:如何快速准备裸金属服务器 Windows 自定义镜像?

很多小伙伴在某些场景下&#xff0c;需要基于 Windows 镜像的裸金属服务器创建自定义镜像&#xff0c;本文将介绍在进行裸金属服务器制作 Windows 自定义镜像前&#xff0c;你需要准备哪些内容、准备的步骤是怎么样的。 在之前我们也发过 快速上手 PC-Farm 服务器的教程&#…...

理解SurfaceFlinger在Android中的作用

理解SurfaceFlinger在Android中的作用 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们来探讨Android系统中一个关键的组件——SurfaceFlinger&#xff…...

[数据集][目标检测]水面垃圾水面漂浮物检测数据集VOC+YOLO格式3749张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;3749 标注数量(xml文件个数)&#xff1a;3749 标注数量(txt文件个数)&#xff1a;3749 标注…...

Tims天好中国一季报:系统销售额同比增7.1%自营门店EBITDA7个

5日晚间,全球知名连锁咖啡品牌Tim Hortons中国及炸鸡品牌Popeyes中国(以下简称“Tims天好中国”;NASDAQ: THCH)公布了2024年第一季度财报:总营收人民币3.468亿元,同比增长3.1%;系统销售额3.635亿元,同比增长7.1%。2024年以来,咖啡行业竞争持续加剧,Tims天好中国以可持续…...

Instagram运营必备工具合集

Instagram的运营不仅仅涉及数据分析&#xff0c;还包括内容规划、发布管理、互动提升和广告优化等多个方面。以下是一些海外社媒Instagram运营必备的工具&#xff0c;这些工具可以帮助您更有效地管理和提升您的Instagram账号。 Instagram 运营必备工具合集 数据分析工具 1、Ins…...

AWS安全性身份和合规性之Amazon Detective

分析和直观呈现安全数据&#xff0c;以调查潜在的安全问题。 Amazon Detective使您可以更轻松地分析、调查和快速确定潜在安全问题或可疑活动的根本原因。Amazon Detective会自动从您地AWS资源中收集日志数据并使用机器学习、统计分析和图论来构建一组关联的数据&#xff0c;使…...

48、spfa求最短路

spfa求最短路 题目描述 给定一个n个点m条边的有向图&#xff0c;图中可能存在重边和自环&#xff0c; 边权可能为负数。 请你求出1号点到n号点的最短距离&#xff0c;如果无法从1号点走到n号点&#xff0c;则输出impossible。 数据保证不存在负权回路。 输入格式 第一行包…...

前端大文件上传

首先&#xff0c;我们需要使用Blob对象的 slice 方法将文件切分成多个切片。 const CHUNK_SIZE 1024 * 1024; // 我们选择1MB作为每个切片的大小 let file document.getElementById("upload").files[0]; // 得到所选文件 let totalSize file.size; let chunks […...

Golang | Leetcode Golang题解之第107题二叉树的层序遍历II

题目&#xff1a; 题解&#xff1a; func levelOrderBottom(root *TreeNode) [][]int {levelOrder : [][]int{}if root nil {return levelOrder}queue : []*TreeNode{}queue append(queue, root)for len(queue) > 0 {level : []int{}size : len(queue)for i : 0; i < …...