学习笔记:强化学习与最优控制(Chapter 1)

本博客参考课本Reinforcement Learning and Optimal Control,由Dimitri P. Bertsekas书写。
主要目的是按照自己的思路梳理一下课本,加上自己的一些理解,记录学习过程。

1.1 Deterministic Programming

1.1.1 Deterministic Problems

  1. finite horizon problems: 包含有限的决策序列
  2. deterministic dynamic programming problem:
    一个决定性的动态规划问题包括具有如下形式的离散动态规划系统 x k + 1 = f k ( x k , u k ) x_{k+1}=f_k(x_k,u_k) xk+1=fk(xk,uk) k k k为时间序号即时刻, x k x_k xk为系统状态, u k u_k uk为从集合 U k ( x k ) U_k(x_k) Uk(xk)得到的控制或者决策变量, f k f_k fk为系统状态从 k k k时刻变化到 k + 1 k+1 k+1时刻的转换机制。
    给定初始状态 x 0 x_0 x0,对于控制序列 { u 0 , u 1 … , u N − 1 } \{u_0,u_1\dots,u_{N-1}\} {u0,u1,uN1},其总代价函数为
    J ( x 0 ; u 0 … , u N − 1 ) = g N ( x N ) + ∑ k = 0 N − 1 g k ( x k , u k ) (1) \tag{1}J(x_0;u_0\dots,u_{N-1})=g_N(x_N)+\sum\limits_{k=0}^{N-1}g_k(x_k,u_k) J(x0;u0,uN1)=gN(xN)+k=0N1gk(xk,uk)(1),其中 g N ( x N ) g_N(x_N) gN(xN)为终止代价, g k ( x k , u k ) g_k(x_k,u_k) gk(xk,uk)为时刻 k k k所花费的代价。
    这个问题的优化目标为:给定初始状态 x 0 x_0 x0,找到一个控制序列 { u 0 , … , u N − 1 } \{u_0,\dots,u_{N-1}\} {u0,,uN1}使得系统的总代价函数最小,即最小化公式 (1):
    J ∗ ( x 0 ) = min ⁡ u k ∈ U k ( x k ) , k = 0 , … , N − 1 J ( x 0 ; u 0 , … , u N − 1 ) J^*(x_0)=\min\limits_{u_k\in U_k(x_k),k=0,\dots,N-1}J(x_0;u_0,\dots,u_{N-1}) J(x0)=ukUk(xk),k=0,,N1minJ(x0;u0,,uN1)
  3. 当状态空间和控制空间都是离散的,并且具有有限个元素,那么deterministic dynamic programming问题可以转化为最短路径问题:构造一张图,图中每个结点表示一个状态 x k x_k xk,图中每条边表示一个(状态、控制)对 ( x k , u k ) (x_k,u_k) (xk,uk),长度为 g k ( x k , u k ) g_k(x_k,u_k) gk(xk,uk),为了处理最终状态,我们人为地添加一个终止节点 t t t,对于最后 N N N阶段的每个结点 x N x_N xN,我们将其与 t t t相连,边长为 g N ( x N ) g_N(x_N) gN(xN)
  4. Generally, deterministic optimal control problems with continuous state and state and control spaces can ve solved using nonlinear programming, such as gradient, Newton’s method

1.1.2 The Dynamic Algorithm

  1. Principle of Optimality: the tail of an optimal sequence is optimal for the tail subproblem
    Let u 0 ∗ , … , u N − 1 ∗ u_0^*,\dots,u_{N-1}^* u0,,uN1 be an optimal control sequence, which together with x 0 x_0 x0 determines the state sequence x 1 ∗ , … , x N ∗ x_1^*,\dots,x_N^* x1,,xN. Consider the subproblem whereby we start at x k ∗ x_k^* xk at time k k k and want to minimize cost from time k k k to N N N:
    min ⁡ g k ( x k ∗ , u k ) + ∑ m = k + 1 N − 1 g m ( x m , u m ) + g N ( x N ) \min g_k(x_k^*,u_k)+\sum\limits_{m=k+1}^{N-1}g_m(x_m,u_m)+g_N(x_N) mingk(xk,uk)+m=k+1N1gm(xm,um)+gN(xN)
    The truncated optimal control sequence { u k ∗ , … , u N − 1 ∗ } \{u_k^*,\dots,u_{N-1}^*\} {uk,,uN1} is optimal for this subproblem.
    Proof: If the truncated control sequence { u k ∗ , … , u N − 1 ∗ } \{u_k^*,\dots,u_{N-1}^*\} {uk,,uN1} is not optimal, then we are able to reduce the cost by switching to an optimal sequence for the subproblem once we reach x k ∗ x_k^* xk
    作用:最优代价函数能够以从后往前的方法计算,先计算包括最后一个stage的tail subproblem的最优代价函数,在计算包含最后两个stage的tail subproblem的最优代价函数,直到计算完整个问题的最优代价函数
  2. 动态规划:动态规划就是基于principle of optimality的思想:先解决时间长度一定的所有tail subproblem,再用这些子问题的解去解决时间长度更长的tail subproblem
  3. 用动态规划解决deterministic finite horizon问题
    临界状态:对于所有的 x N x_N xN,有 J N ∗ ( x N ) = g N ( x N ) J_N^*(x_N)=g_N(x_N) JN(xN)=gN(xN)
    动态规划:对于所有的 x k , k = 0 , 1 … , N − 1 x_k,k=0,1\dots,N-1 xk,k=0,1,N1,让
    J k ∗ ( x k ) = min ⁡ u k ∈ U k ( x k ) [ g k ( x k , u k ) + J k + 1 ∗ ( f k ( x k , u k ) ) ] J_k^*(x_k)=\min\limits_{u_k\in U_k(x_k)}[g_k(x_k,u_k)+J_{k+1}^*(f_k(x_k,u_k))] Jk(xk)=ukUk(xk)min[gk(xk,uk)+Jk+1(fk(xk,uk))]
    这要求我们计算第 j j j个阶段的最优代价时,需要先计算出 k + 1 k+1 k+1阶段所有状态 x k + 1 x_{k+1} xk+1的最优代价函数
    我们称 J k ∗ ( x k ) J_k^*(x_k) Jk(xk) k k k时刻 x k x_k xk状态的optimal cost-to-go,称 J k ∗ J_k^* Jk为时刻 k k k的optimal cost-to-go function。以上方法相当于计算出了每一个时刻每一个状态的最优代价,那么当我们在状态 x k x_k xk时,我们要采取控制来让以后的代价最小,即:
    u k ∗ ∈ arg ⁡ min ⁡ u k ∈ U k ( x k ∗ ) [ g k ( x k ∗ , u k ) + J k + 1 ∗ ( f k ( x k ∗ , u k ) ) ] u_k^*\in\arg\min_{u_k\in U_k(x_k^*)}[g_k(x_k^*,u_k)+J_{k+1}^*(f_k(x_k^*,u_k))] ukargukUk(xk)min[gk(xk,uk)+Jk+1(fk(xk,uk))]
  4. 实际情况中,求出每一个时刻每一个状态的optimal cost-to-go是一件很费时间的事,因为状态空间 x k x_k xk可能非常大。我们可以用以下的方法来解决
    价值空间估计:用估计值 J ~ k \tilde{J}_k J~k来代替optimal cost-to-go function J k ∗ J_k^* Jk,产生suboptimal的控制序列 { u ~ 0 , … , u ~ N − 1 } \{\tilde{u}_0,\dots,\tilde{u}_{N-1}\} {u~0,,u~N1} u ~ k ∈ arg ⁡ min ⁡ u k ∈ U k ( x ~ k ) [ g k ( x ~ k , u k ) + J ~ k + 1 ( f k ( x ~ k , u k ) ) ] (2) \tilde{u}_k\in\arg\min\limits_{u_k\in U_k(\tilde{x}_k)}[g_k(\tilde{x}_k,u_k)+\tilde{J}_{k+1}(f_k(\tilde{x}_k,u_k))]\tag{2} u~kargukUk(x~k)min[gk(x~k,uk)+J~k+1(fk(x~k,uk))](2)
    Q-factor:式子(2)的右边即为 ( x k , u k ) (x_k,u_k) (xk,uk)的Q-factor: Q ~ k ( x k , u k ) = g k ( x ~ k , u k ) + J ~ k + 1 ( f k ( x ~ k , u k ) ) \tilde{Q}_k(x_k,u_k)=g_k(\tilde{x}_k,u_k)+\tilde{J}_{k+1}(f_k(\tilde{x}_k,u_k)) Q~k(xk,uk)=gk(x~k,uk)+J~k+1(fk(x~k,uk)),这提示了我们可以用Q-factor来代替代价函数来进行计算。直接来看的话,用Q-factor求解和用式子(2)求解没什么两样,唯一的区别在于当我们使用on-line方法的时候(往后会说到),Q-factor要求我们保存每一个状态-控制对 ( x k , u k ) (x_k,u_k) (xk,uk)的Q值,而式子(2)只需我们保存每个状态的optimal cost-to-go J ∗ J^* J

1.2 Stochastic Dynamic Programming

  1. 与determinstic版本的区别
  • 系统的状态转移不仅依赖于状态 x k x_k xk和控制 u k u_k uk,还依赖于一个基于状态 x k x_k xk和控制 u k u_k uk的随机变量 w k ∼ P k ( ⋅ ∣ x k , u k ) w_k\sim P_k(\cdot|x_k,u_k) wkPk(xk,uk),即: x k + 1 = f k ( x k , u k , w k ) , k = 0 , 1 , … , N − 1 x_{k+1}=f_k(x_k,u_k,w_k),k=0,1,\dots,N-1 xk+1=fk(xk,uk,wk),k=0,1,,N1
  • 我们优化的不再是控制(control)序列 u 0 , … , u N − 1 u_0,\dots,u_{N-1} u0,,uN1,而是策略(policy) π = { μ 0 , … , μ N − 1 } \pi=\{\mu_0,\dots,\mu_{N-1}\} π={μ0,,μN1} μ k \mu_k μk将状态 x k x_k xk映射到控制空间,即 u k = μ k ( x k ) u_k=\mu_k(x_k) uk=μk(xk)
  • 代价函数变为对随机变量 w k w_k wk和状态 x k x_k xk的期望值: J π ( x 0 ) = E { g N ( x N ) + ∑ k = 0 N − 1 g k ( x k , μ k ( x k ) , w k ) } J_{\pi}(x_0)=\mathbb{E}\{g_N(x_N)+\sum\limits_{k=0}^{N-1}g_k(x_k,\mu_k(x_k),w_k)\} Jπ(x0)=E{gN(xN)+k=0N1gk(xk,μk(xk),wk)},最优策略 π ∗ \pi^* π即为使得代价函数最小的策略 J ∗ ( x 0 ) = J π ∗ ( x 0 ) = min ⁡ π J π ( x 0 ) J^*(x_0)=J_{\pi^*}(x_0)=\min\limits_{\pi}J_\pi(x_0) J(x0)=Jπ(x0)=πminJπ(x0)
  1. 最优策略求解
  • off-line方法(动态规划)
    临界状态:对于所有的 x N x_N xN,有 J N ∗ ( x N ) = g N ( x N ) J_N^*(x_N)=g_N(x_N) JN(xN)=gN(xN)
    动态规划:对于所有的 x k , k = 0 , 1 … , N − 1 x_k,k=0,1\dots,N-1 xk,k=0,1,N1,让
    J k ∗ ( x k ) = min ⁡ u k ∈ U k ( x k ) E [ g k ( x k , u k , w k ) + J k + 1 ∗ ( f k ( x k , u k , w k ) ) ] (3) J_k^*(x_k)=\min\limits_{u_k\in U_k(x_k)}\mathbb{E}[g_k(x_k,u_k,w_k)+J_{k+1}^*(f_k(x_k,u_k,w_k))]\tag{3} Jk(xk)=ukUk(xk)minE[gk(xk,uk,wk)+Jk+1(fk(xk,uk,wk))](3)
    如果策略得到的控制序列等于等式(3)得到的最优控制序列即 μ k ( x k ) = u k ∗ = ( x k ) \mu_k(x_k)=u_k^*=(x_k) μk(xk)=uk=(xk),那么策略 π = { μ 0 , … , μ N − 1 } \pi=\{\mu_0,\dots,\mu_{N-1}\} π={μ0,,μN1}为最优策略,我们可以线下求解后将其保存,需要用时直接查表调用找到最优控制
  • on-line方法(one-step lookahead minimization)
    通常,这种方法并不用于真正求解动态规划即 J ∗ J^* J,而是用来估计动态规划的解即 J ~ k \tilde{J}_k J~k:
    μ k ( x k ) ∈ arg ⁡ min ⁡ u k ∈ U k ( x k ) E [ g k ( x k , u k , w k ) + J ~ k + 1 ( f k ( x k , u k , w k ) ) ] (4) \mu_k(x_k)\in\arg\min\limits_{u_k\in U_k(x_k)}\mathbb{E}[g_k(x_k,u_k,w_k)+\tilde{J}_{k+1}(f_k(x_k,u_k,w_k))] \tag{4} μk(xk)argukUk(xk)minE[gk(xk,uk,wk)+J~k+1(fk(xk,uk,wk))](4)
    乍一看,这个式子和动态规划的求解式子(3)没有什么区别,这是因为one-step lookahead只向前精确探索一步,即尝试对于状态 x k x_k xk来说所有的控制 u k u_k uk,当状态转移到 f k ( x k , u k , w k ) f_k(x_k,u_k,w_k) fk(xk,uk,wk)后,不再精确计算这个状态的optimal cost-to-go J ∗ J^* J,而是用代价估计函数 J ~ \tilde{J} J~来估计这个状态的代价函数和。当我们采用multi-step即向前探索多步时,式子(4)会与动态规划求解式子有明显差别。
    多说两句,原文在次并没有解释采用multi-step lookahead方式的好处,我的理解是multi-step不用我们求出精确的optimal cost-to-go J ∗ J^* J,它只需要我们用其估计值 J ~ \tilde{J} J~。这个估计值可以不准,因为我们可以采用增加look-head步数的方法降低对 J ~ \tilde{J} J~估计准确性的需求。

1.3 Variations and Simplifications

1.3.1 变化

  1. 怎样将一个最优控制问题转化为可以用动态规划求解的形式
  • 找到每个时刻的控制 u k u_k uk
  • 找到每个时刻的状态 x k x_k xk:状态 x k x_k xk应该包含对于选择最优控制 u k u_k uk有帮助的所有信息
  1. 问题变式:问题涉及的状态为partial or imperfect state information
    我们收集到的不是直接的状态 x k x_k xk,而是状态的衡量 I k I_k Ik(比如温度和温度计示数),此时更好的表示方法是用条件概率分布来表示状态,即 P k ( x k ∣ I k ) P_k(x_k|I_k) Pk(xkIk),称为信念(belief state)。

1.3.2 经典问题

往后的许多强化学习问题都可以归约到如下的几类基本问题

  1. 确定性最短路径问题 a i j a_{ij} aij表示从 i i i j j j的路径长, t t t为人造的终止节点
    解决方案
    临界状态: J N − 1 ∗ ( i ) = a i t J_{N-1}^*(i)=a_{it} JN1(i)=ait
    动态规划: J k ∗ ( i ) = min ⁡ A l l   a r c s   ( i , j ) [ a i j + J k + 1 ∗ ( j ) ] \begin{aligned}J_k^*(i)&=\min\limits_{All\ arcs\ (i,j)}[a_{ij}+J_{k+1}^*(j)]\end{aligned} Jk(i)=All arcs (i,j)min[aij+Jk+1(j)]
    J k ∗ ( i ) J_k^*(i) Jk(i)表示用 N − k N-k Nk步从结点 i i i到终止节点 t t t的最小代价
  2. 带有终止状态的问题:终止状态 t t t为无代价无转移的状态即 g k ( t , u k , w k ) = 0 , f k ( t , u k , w k ) = t , ∀ u k , w k g_k(t,u_k,w_k)=0,f_k(t,u_k,w_k)=t,\forall u_k,w_k gk(t,uk,wk)=0,fk(t,uk,wk)=t,uk,wk,此时问题可以理解
    为如何用最多 N N N步以最小的代价转移到终止状态,可以直接用原始的动态规划式子求解。
  3. Forecast:在时刻 k k k可以得到对下一个时刻的扰动 w k + 1 w_{k+1} wk+1分布的预测,其分布从一个分布集合 { P 1 , … , P m } \{P_1,\dots,P_m\} {P1,,Pm}中得到,如果我们在 k k k时刻的forecast为 i i i,即 ξ k = i \xi_k=i ξk=i,那么下一个时刻的扰动 w k + 1 w_{k+1} wk+1具有分布 P i P_i Pi。因为每一个时刻的forecast是对下一个时刻有用的,所以我们将每个时刻的 ξ k \xi_k ξk保留到下一个时刻,用 y k + 1 y_{k+1} yk+1来表示,即 y k + 1 = ξ k y_{k+1}=\xi_k yk+1=ξk
    解决方案:将 k k k时刻得到的forecast与下一个状态 x k + 1 x_{k+1} xk+1相结合得到新的状态 x ~ k + 1 = ( x k + 1 , y k + 1 ) = ( f k ( x k , u k , w k ) , ξ k ) , w k + 1 = ( w k , ξ k ) \tilde{x}_{k+1}=(x_{k+1},y_{k+1})=(f_k(x_k,u_k,w_k),\xi_k),w_{k+1}=(w_k,\xi_k) x~k+1=(xk+1,yk+1)=(fk(xk,uk,wk),ξk),wk+1=(wk,ξk)
    初始状态: J N ∗ ( x N , y N ) = g N ( x N ) J_N^*(x_N,y_N)=g_N(x_N) JN(xN,yN)=gN(xN)
    动态规划: J k ∗ ( x k , y k ) = min ⁡ u k ∈ U k ( x k ) E w k [ g k ( x k , u k , w k ) + ∑ i = 1 m p i J k + 1 ∗ ( f k ( x k , u k , w k ) , i ) ∣ y k ] J_k^*(x_k,y_k)=\min\limits_{u_k\in U_k(x_k)}\mathbb{E}_{w_k}[g_k(x_k,u_k,w_k)\\+\sum\limits_{i=1}^mp_iJ_{k+1}^*(f_k(x_k,u_k,w_k),i)|y_k] Jk(xk,yk)=ukUk(xk)minEwk[gk(xk,uk,wk)+i=1mpiJk+1(fk(xk,uk,wk),i)yk]
  4. 带有不可控状态的问题
    许多问题中,状态有许多组成部分,他们是不受控制决策的影响的,即每个时刻的状态由两部分组成 ( x k , y k ) (x_k,y_k) (xk,yk) x k x_k xk是收到决策 u k u_k uk影响的, y k y_k yk是不受我们任何控制的影响的。它符合条件分布 y k ∼ P k ( y k ∣ x k ) y_k\sim P_k(y_k|x_k) ykPk(ykxk),其与扰动的区别在于在 k k k时刻做决策之前,我们可以观测到 y k y_k yk,但是扰动 w k w_k wk是在做出控制 u k u_k uk之后才由分布 p ( w k ∣ x k , u k ) p(w_k|x_k,u_k) p(wkxk,uk)决定的。
    状态转移方程为: x k + 1 = f k ( x k , y k , u k , w k ) x_{k+1}=f_k(x_k,y_k,u_k,w_k) xk+1=fk(xk,yk,uk,wk),并且扰动的分布 P k ( w k ∣ x k , y k , u k ) P_k(w_k|x_k,y_k,u_k) Pk(wkxk,yk,uk)是给定的。
    我们的动态规划方程只能基于可控的状态,所以我们要对不可控的部分 y k y_k yk取期望来消除它,即optimal cost-to-go变为 J ^ k ( x k ) = E y k [ J k ∗ ( x k , y k ) ∣ x k ] \hat{J}_k(x_k)=\mathbb{E}_{y_k}[J_k^*(x_k,y_k)|x_k] J^k(xk)=Eyk[Jk(xk,yk)xk]
    动态规划 J ^ k ( x k ) = E y k { min ⁡ u k ∈ U k ( x k ) E w k [ g k ( x k , y k , u k , w k ) + J ^ k + 1 ( f k ( x k , y k , u k , w k ) ) ∣ x k , y k , u k ] ∣ x k } \hat{J}_k(x_k)=\mathbb{E}_{y_k}\{\min\limits_{u_k\in U_k(x_k)}\mathbb{E}_{w_k}[g_k(x_k,y_k,u_k,w_k)+\hat{J}_{k+1}(f_k(x_k,y_k,u_k,w_k))|x_k,y_k,u_k]|x_k\} J^k(xk)=Eyk{ukUk(xk)minEwk[gk(xk,yk,uk,wk)+J^k+1(fk(xk,yk,uk,wk))xk,yk,uk]xk}
    即对于我们考虑每一个可控状态 x k x_k xk,其最优代价等于考虑所有不可控状态 y k y_k yk后的期望,对于给定状态 ( x k , y k ) (x_k,y_k) (xk,yk)其最优代价的计算和之前一样。
  5. 部分状态信息和信念状态
    状态的一些组分是不可直接观测到的,所以对他们的观测需要用到仪器,这带来一定的误差。我们把这个不准确的状态称为不完美状态信息
    解决方案:用信念状态 b k b_k bk来替代不准确的状态 x k x_k xk,信念 b k b_k bk实际上是 x k x_k xk的一个分布,即当给定观测状态后,我们相信系统状态为每一个 x k x_k xk的概率
    对于信念 b k b_k bk我们可以采用相似的动态规划方案,更为详细的介绍会在后面的笔记中
  6. 具有不可知参数的系统
    系统的转移方程是不可知的,比如汽车的行驶控制系统,用 x k x_k xk表示 k k k时刻的速度,则下一时刻速度为 x k + 1 = x k + b u k x_{k+1}=x_k+bu_k xk+1=xk+buk,其中 b b b是变化的,无法准确建模的,因为它可能取决于某个随时间变化的条件。
    解决方案:将不可知参数作为不可观测的状态部分引入到状态表示中即 y k = θ k y_k=\theta_k yk=θk,这样状态变为上述的不完美状态。状态转移方程变为 x k + 1 = f k ( x k , θ k , u k , w k ) x_{k+1}=f_k(x_k,\theta_k,u_k,w_k) xk+1=fk(xk,θk,uk,wk),为了简化,我们假设不可知参数 θ k \theta_k θk不随时间变化,即 θ k = θ \theta_k=\theta θk=θ。这样 x ~ k = ( x k , y k ) \tilde{x}_k=(x_k,y_k) x~k=(xk,yk)即为新的状态。
    因为新的状态有一部分是不可观测的,我们采用adaptive control的方法将控制过程分为两部分:参数估计部分(对不可知参数进行估计)、控制部分(根据参数的估计做出控制决策)。
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会尽力回答你的问题。关于通过UDP传输音视频,我了解一些相关的知识,下面是一些学习笔记: 1. gstreamer是一个流媒体框架,用于创建、处理和播放多媒体流。它支持多种音视频格式,可以通过插件扩展功能。 2. 通过gstreamer可以使用UDP协议传输音视频数据。UDP协议是一种无连接的协议,不保证数据传输的可靠性和顺序性,但是传输效率高。 3. 首先需要创建一个gstreamer的pipeline,包括音视频源、编码器、UDP发送端等组件。例如: ``` gst-launch-1.0 -v filesrc location=test.mp4 ! decodebin ! x264enc ! rtph264pay ! udpsink host=192.168.1.100 port=5000 ``` 这个pipeline的作用是从test.mp4文件读取音视频流,解码后使用x264编码器进行压缩,然后使用rtph264pay将数据打包成RTP数据包,最后通过udpsink发送到指定的IP地址和端口。 4. 接收端需要创建一个gstreamer的pipeline,包括UDP接收端、解包器、解码器等组件。例如: ``` gst-launch-1.0 -v udpsrc port=5000 ! application/x-rtp, payload=96 ! rtpjitterbuffer ! rtph264depay ! avdec_h264 ! autovideosink ``` 这个pipeline的作用是从UDP端口5000接收音视频数据,使用rtpjitterbuffer解决网络抖动问题,使用rtph264depay将RTP数据包解包成原始的H.264数据流,然后使用avdec_h264解码器进行解码,最后使用autovideosink播放视频。 5. 在实际使用过程中,还需要考虑数据的带宽限制、网络延迟等问题,以保证音视频传输的效果。 希望这些笔记能对你有帮助。如果你还有其他问题,可以继续问我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值