最优控制:从变分法到庞特里亚金原理

典型问题

根据系统的建模可以划分为:

  • 线性系统: x ˙ = A x + B u \mathbf{\dot{x}} = \boldsymbol{A}\mathbf{x}+\boldsymbol{B}\mathbf{u} x˙=Ax+Bu
  • 非线性系统 x ˙ ( t ) = f ( x ( t ) , u ( t ) , t ) \dot{\mathbf{x}}(t) = \mathbf{f}(\mathbf{x}(t), \mathbf{u}(t), t) x˙(t)=f(x(t),u(t),t)
    • 可以通过一些手段进行线性化

根据约束类型可以划分为:

  • 控制约束: u ( t ) ∈ U ⊆ R m \mathbf{u}(t) \in \mathbb{U} \subseteq \mathbb{R}^m u(t)URm
  • 状态约束: f ( x ) ≤ 0 \mathbf{f}(\mathbf{x}) \le 0 f(x)0 or g ( x ) = 0 \mathbf{g}(\mathbf{x}) = 0 g(x)=0

其实无论是线性系统/非线性系统,控制约束/状态约束,使用最优化方法解决时都是约束,都需要使用庞特里亚金极小值原理解决

一个最优控制的典型问题形式如下:

  • 被控系统(动态约束): x ˙ ( t ) = f ( x ( t ) , u ( t ) , t ) , x ( t 0 ) = x 0 \dot{\mathbf{x}}(t) = \mathbf{f}(\mathbf{x}(t), \mathbf{u}(t), t), \quad \mathbf{x}(t_0) = \mathbf{x}_0 x˙(t)=f(x(t),u(t),t),x(t0)=x0
  • 目标函数: J = Φ [ x ( t f ) ] + ∫ t 0 t f L [ x ( t ) , u ( t ) , t ] d t J = \varPhi \left[ \boldsymbol{x}(t_f) \right] + \int_{t_0}^{t_f} L \left[ \boldsymbol{x}(t), \boldsymbol{u}(t), t \right] \mathrm{d}t J=Φ[x(tf)]+t0tfL[x(t),u(t),t]dt
    • 寻找最优控制 u ∗ ( t ) \mathbf{u}^*(t) u(t) 和最优轨迹 x ∗ ( t ) \mathbf{x}^*(t) x(t),使 J J J 最小化(或最大化),同时满足状态方程和控制约束 u ( t ) ∈ U \mathbf{u}(t) \in \mathbb{U} u(t)U
  • 约束条件:
    • 输入约束: u ( t ) ∈ U ⊆ R m \mathbf{u}(t) \in \mathbb{U} \subseteq \mathbb{R}^m u(t)URm
    • 状态约束,末尾状态也可以设定为一个约束

典型方法

变分法

将问题理解为求代价泛函 J [ y ] J[y] J[y]极小值函数 y y y,一般用于无约束问题,如果遇见约束问题,需要构建拉格朗日函数,将原问题的约束条件 “嵌入” 到新构造的增广代价泛函中,从而将有约束的优化问题转化为无约束的极值问题。
变分法基础
变分法研究泛函的极值,泛函以函数为自变量(如曲线长度、物理作用量)。通过变分 δ y ( x ) \delta y(x) δy(x),函数的微小扰动),将泛函极值转化为微分方程求解。

  • 泛函示例: J [ y ] = ∫ x 1 x 2 F ( x , y , y ′ ) d x J[y] = \int_{x_1}^{x_2} F(x, y, y') dx J[y]=x1x2F(x,y,y)dx其中 $ y(x)$ 是函数, y ′ = d y / d x y' = dy/dx y=dy/dx,求函数 y ∗ ( x ) y^*(x) y(x)使得泛函取得最极值。
  • 变分:泛函的自变量(函数)的微小变化称为变分,记作 δ y \delta y δy
  • 变分与微分/积分满足可交换性: δ ( d y d x ) = d d x ( δ y ) , δ ∫ L d x = ∫ δ L d x \delta\left(\frac{dy}{dx}\right)=\frac{d}{dx}(\delta y),\delta\int Ldx = \int\delta Ldx δ(dxdy)=dxd(δy),δLdx=δLdx
  • 变分满足链式法则, δ F = ∂ F ∂ x δ x + ∂ F ∂ y δ y + ∂ F ∂ y ˙ δ y ˙ \delta F = \frac{\partial F}{\partial x} \delta x + \frac{\partial F}{\partial y} \delta y + \frac{\partial F}{\partial \dot{y}} \delta \dot{y} δF=xFδx+yFδy+y˙Fδy˙,其中根据变分与微分的交换律: δ y ˙ = d d x ( δ y ) \delta \dot{y} = \frac{d}{dx} (\delta y) δy˙=dxd(δy) ,自变量x的变分 δ x = 0 \delta x = 0 δx=0

欧拉-拉格朗日(E-L)方程

E-L 方程描述了极值曲线在函数空间中的 “驻点”,即沿任何变分方向的泛函变化率为零,类似于函数极值的一阶导数为零。
E-L方程是泛函极值的必要条件,推导如下:

  • 邻近曲线:设 y ( x ) = y ( x ) + ϵ δ y ( x ) y(x) = y(x) + \epsilon\delta y(x) y(x)=y(x)+ϵδy(x) δ \delta δ就是变分,需要任意可微,为了固定边界确保端点不变还需要满足 δ ( x 1 ) = δ ( x 2 ) = 0 \delta(x_1)=\delta(x_2)=0 δ(x1)=δ(x2)=0 ϵ → 0 \epsilon \to 0 ϵ0
  • 此时泛函可写做: J ( y ) = ∫ x 1 x 2 F ( x , y + ϵ δ y , y ′ + ϵ δ y ′ ) d x J(y) = \int_{x_1}^{x_2} F(x, y + \epsilon \delta y, y' + \epsilon \delta y') \, dx J(y)=x1x2F(x,y+ϵδy,y+ϵδy)dx
  • 泛函导数:对 J [ ϵ ] J[\epsilon] J[ϵ] 求导并令 ϵ = 0 \epsilon=0 ϵ=0,分部积分后得: ∫ δ ( ∂ F ∂ y − d d x ( ∂ F ∂ y ′ ) ) d x = 0 \int \delta \left( \frac{\partial F}{\partial y} - \frac{d}{dx}\left(\frac{\partial F}{\partial y'}\right) \right) dx = 0 δ(yFdxd(yF))dx=0
    • 推导:利用莱布尼兹法则,对 ϵ \epsilon ϵ求导保留线性部分: δ J ( ϵ ) = ∫ x 1 x 2 ( ∂ F ∂ ( y + ϵ δ y ) ⋅ δ y + ∂ F ∂ ( y ′ + ϵ δ y ′ ) ⋅ δ y ′ ) d x \delta J(\epsilon) = \int_{x_1}^{x_2} \left( \frac{\partial F}{\partial (y + \epsilon \delta y)} \cdot \delta y + \frac{\partial F}{\partial (y' + \epsilon \delta y')} \cdot \delta y' \right) dx δJ(ϵ)=x1x2((y+ϵδy)Fδy+(y+ϵδy)Fδy)dx
    • 根据变分定义,令 ϵ = 0 \epsilon = 0 ϵ=0,得到泛函在 y ( x ) y(x) y(x)处沿 η ( x ) \eta(x) η(x) 方向的变分导数: δ J = ∫ x 1 x 2 ( ∂ F ∂ y δ + ∂ F ∂ y ′ δ y ′ ) d x \delta J = \int_{x_1}^{x_2} \left( \frac{\partial F}{\partial y} \delta + \frac{\partial F}{\partial y'} \delta y' \right) dx δJ=x1x2(yFδ+yFδy)dx
    • 然后取出后半部分进行分部积分以消除 δ y ′ \delta y' δy ∫ x 1 x 2 ∂ F ∂ y ′ δ y ′ d x = [ ∂ F ∂ y ′ δ y ] x 1 x 2 − ∫ x 1 x 2 d d x ( ∂ F ∂ y ′ ) δ y d x \int_{x_1}^{x_2} \frac{\partial F}{\partial y'} \delta y' \, dx = \left[ \frac{\partial F}{\partial y'} \delta y \right]_{x_1}^{x_2} - \int_{x_1}^{x_2} \frac{d}{dx}\left( \frac{\partial F}{\partial y'} \right) \delta y \, dx x1x2yFδydx=[yFδy]x1x2x1x2dxd(yF)δydx
    • 由于 δ y ( x 1 ) = δ y ( x 2 ) = 0 \delta y(x_1) = \delta y(x_2) = 0 δy(x1)=δy(x2)=0,带入后化简可得: δ J = ∫ x 1 x 2 ( ∂ F ∂ y − d d x ( ∂ F ∂ y ′ ) ) δ y d x = 0 \delta J = \int_{x_1}^{x_2} \left( \frac{\partial F}{\partial y} - \frac{d}{dx}\left( \frac{\partial F}{\partial y'} \right) \right) \delta y \, dx = 0 δJ=x1x2(yFdxd(yF))δydx=0
  • 由于 δ \delta δ任意,根据变分引理则被积函数必恒为零。故 E − L 方程 E-L方程 EL方程 ∂ F ∂ y − d d x ( ∂ F ∂ y ′ ) = 0 \frac{\partial F}{\partial y} - \frac{d}{dx}\left(\frac{\partial F}{\partial y'}\right) = 0 yFdxd(yF)=0
    • 变分引理:若连续函数 G ( x ) G(x) G(x)对于任意 η ∈ C 2 ( [ x 1 , x 2 ] ) \eta \in C^2([x_1,x_2]) ηC2([x1,x2])满足 ∫ G η d x = 0 \int G\eta dx = 0 Gηdx=0,则 G ( x ) ≡ 0 G(x) \equiv 0 G(x)0

求解E-L方程就可以得到极值处的函数 y ∗ ( x ) y^*(x) y(x),这个过程可以结合导数的概念来理解,,函数空间中一个点 y ( x ) y(x) y(x),临近曲线 y ( x ) + ϵ δ y y(x) + \epsilon\delta y y(x)+ϵδy就是在这个点附近的点,且 ϵ → 0 \epsilon \to 0 ϵ0,泛函对 ϵ \epsilon ϵ求导得到的就是 y ( x ) y(x) y(x)这个点在 δ y ( x ) \delta y(x) δy(x)这个方向的导数,满足朝向任何方向 δ y ( x ) \delta y(x) δy(x)上的导数都为0的点自然就是极值点。最优控制的庞特里亚金原理中的哈密顿函数,本质是变分法在动态系统的扩展(含协态变量的E-L方程推广)。

  • 如果F含高阶导数,则E-L方程也要扩展, ∂ F ∂ y − d d x ( ∂ F ∂ y ′ ) + d 2 d x 2 ( ∂ F ∂ y ′ ′ ) − ⋯ = 0 \frac{\partial F}{\partial y}-\frac{d}{dx}\left(\frac{\partial F}{\partial y^{\prime}}\right)+\frac{d^2}{dx^2}\left(\frac{\partial F}{\partial y^{\prime\prime}}\right)-\cdots=0 yFdxd(yF)+dx2d2(y′′F)=0
  • 如果存在约束,则需要使用拉格朗日乘子构造增广泛函

拉格朗日函数(Lagrange Function)

拉格朗日函数(Lagrange Function)是数学优化理论中的核心工具,用于求解带有约束条件的极值问题。它通过引入拉格朗日乘数(Lagrange Multiplier),将原问题转化为无约束的极值问题,从而利用微积分中的求导方法求解。以下是详细介绍:
假设我们需要优化(最大化或最小化)一个目标函数 f ( x ) f(\mathbf{x}) f(x),同时满足若干等式约束 g i ( x ) = 0 ( i = 1 , 2 , … , m ) g_i(\mathbf{x}) = 0( i = 1, 2, \dots, m ) gi(x)=0i=1,2,,m
拉格朗日函数的核心思想是:通过引入拉格朗日乘数 λ i \lambda_i λi,将约束条件与目标函数“合并”为一个新的函数,使得原问题的极值可以通过求解新函数的无约束极值得到。
设目标函数为 f ( x ) f(\mathbf{x}) f(x),约束条件为 m m m 个等式约束 g i ( x ) = 0 , ( x ∈ R n ) g_i(\mathbf{x}) = 0 ,( \mathbf{x} \in \mathbb{R}^n) gi(x)=0,(xRn),且 m < n m < n m<n
拉格朗日函数定义为:
L ( x , λ 1 , λ 2 , … , λ m ) = f ( x ) − ∑ i = 1 m λ i g i ( x ) L(\mathbf{x}, \lambda_1, \lambda_2, \dots, \lambda_m) = f(\mathbf{x}) - \sum_{i=1}^m \lambda_i g_i(\mathbf{x}) L(x,λ1,λ2,,λm)=f(x)i=1mλigi(x)
其中:

  • x = ( x 1 , x 2 , … , x n ) \mathbf{x} = (x_1, x_2, \dots, x_n) x=(x1,x2,,xn)是优化变量,
  • λ i \lambda_i λi是拉格朗日乘数(可以是常数,也可以是函数,取决于优化变量,如果优化变量是一个函数,那拉格朗日乘数就也是个变量,此时的拉格朗日乘数被称为协态,拉格朗日函数称作动态拉格朗日函数,也叫哈密顿函数)。
  • 拉格朗日函数基于对偶原理—— 将原始问题的约束转化为对偶变量(乘子 / 协态)的优化条件,从而在增广空间中消除显式约束。

求解原问题的极值等价于求解拉格朗日函数 L L L的无约束极值。根据微积分理论,极值点处的梯度(各偏导数)必须为零,即:

  • 对优化变量 x i x_i xi 求偏导并令其为零:
    ∂ L ∂ x j = ∂ f ∂ x j − ∑ i = 1 m λ i ∂ g i ∂ x j = 0 ( j = 1 , 2 , … , n ) \frac{\partial L}{\partial x_j} = \frac{\partial f}{\partial x_j} - \sum_{i=1}^m \lambda_i \frac{\partial g_i}{\partial x_j} = 0 \quad (j = 1, 2, \dots, n) xjL=xjfi=1mλixjgi=0(j=1,2,,n)
  • 对拉格朗日乘数 λ i \lambda_i λi 求偏导并令其为零(自动满足约束条件):
    ∂ L ∂ λ i = − g i ( x ) = 0 ( i = 1 , 2 , … , m ) \frac{\partial L}{\partial \lambda_i} = -g_i(\mathbf{x}) = 0 \quad (i = 1, 2, \dots, m) λiL=gi(x)=0(i=1,2,,m)

这组方程(共 m + n m+n m+n个)称为KKT条件(对等式约束情形,KKT条件退化为拉格朗日乘数法的条件),其解 ( x ∗ , λ ∗ ) (\mathbf{x}^*, \lambda^*) (x,λ)即为原问题的候选极值点。
若约束条件包含不等式约束 h i ( x ) ≤ 0 h_i(\mathbf{x}) \leq 0 hi(x)0,则需要使用扩展的拉格朗日函数和KKT条件,此时拉格朗日函数为:
L ( x , λ , μ ) = f ( x ) − ∑ i = 1 m λ i g i ( x ) − ∑ j = 1 k μ j h j ( x ) L(\mathbf{x}, \lambda, \mu) = f(\mathbf{x}) - \sum_{i=1}^m \lambda_i g_i(\mathbf{x}) - \sum_{j=1}^k \mu_j h_j(\mathbf{x}) L(x,λ,μ)=f(x)i=1mλigi(x)j=1kμjhj(x)
其中 μ j ≥ 0 \mu_j \geq 0 μj0 是对应不等式约束的拉格朗日乘数,且需满足互补松弛条件:
μ j h j ( x ) = 0 \mu_j h_j(\mathbf{x}) = 0 \quad μjhj(x)=0(即约束 active 时 h j = 0 h_j = 0 hj=0,否则 μ j = 0 \mu_j = 0 μj=0)

Pontryagin 极小值原理(庞特里亚金极小值原理)

庞特里亚金极小值原理(Pontryagin’s Minimum Principle)是最优控制理论中的核心定理之一,由苏联数学家列夫·庞特里亚金(Lev Pontryagin)及其团队在20世纪50年代提出。用于求解带有约束的动态系统最优控制问题,尤其适用于控制变量存在不等式约束(如幅值限制)的场景,是变分法的扩展和推广,也被称为现代变分法。它通过构造哈密顿函数,将最优控制问题转化为一组微分方程(正则方程)的求解,并给出控制变量的最优条件。

核心推导

问题描述
代价泛函: J a = ∫ t 0 t f L ( x , u , t ) d t + Φ ( x ( t f ) ) J_a = \int_{t_0}^{t_f} L(x, u, t) dt + \Phi(x(t_f)) Ja=t0tfL(x,u,t)dt+Φ(x(tf))
系统约束: x ˙ = f ( x , u , t ) \mathbf{\dot{x}} = \mathbf{f}(\mathbf{x}, \mathbf{u}, t) x˙=f(x,u,t)
首末约束: x ( t 0 ) = x 0 \mathbf{x}(t_0) = \mathbf{x_0} x(t0)=x0

  1. 构造哈密顿函数(Hamiltonian)
    引入协态变量(伴随变量) λ ( t ) ∈ R n \boldsymbol{\lambda}(t) \in \mathbb{R}^n λ(t)Rn(与状态变量维数相同),定义哈密顿函数: H ( x , u , λ , t ) = L ( x , u , t ) + λ T f ( x , u , t ) H(\mathbf{x}, \mathbf{u}, \boldsymbol{\lambda}, t) = L(\mathbf{x}, \mathbf{u}, t) + \boldsymbol{\lambda}^T \mathbf{f}(\mathbf{x}, \mathbf{u}, t) H(x,u,λ,t)=L(x,u,t)+λTf(x,u,t)
    • 协态变量 λ ( t ) \boldsymbol{\lambda}(t) λ(t) 的物理意义可理解为状态变量的“影子价格”或“边际代价”。
    • 如果有状态约束,还需要再加一项,变成: H ( x , u , λ , t ) = L ( x , u , t ) + λ T f ( x , u , t ) + η T ( x − x m ) H(\mathbf{x}, \mathbf{u}, \boldsymbol{\lambda}, t) = L(\mathbf{x}, \mathbf{u}, t) + \boldsymbol{\lambda}^T \mathbf{f}(\mathbf{x}, \mathbf{u}, t)+\boldsymbol{\eta}^T(\mathbf{x}-\mathbf{x_m}) H(x,u,λ,t)=L(x,u,t)+λTf(x,u,t)+ηT(xxm)
  2. 正则方程(协态方程与状态方程)
    根据极小值原理,最优解需满足以下正则方程:
  • 状态方程(与原系统一致): ∂ H ∂ λ = f ( x , u , t ) = x ˙ ( t ) \frac{\partial H}{\partial \boldsymbol{\lambda}} = \mathbf{f}(\mathbf{x}, \mathbf{u}, t) = \dot{\mathbf{x}}(t) λH=f(x,u,t)=x˙(t)
    • λ \lambda λ求变分分析推导出来
  • 协态方程(伴随方程): − ∂ H ∂ x = − [ ∂ L ∂ x + ( ∂ f ∂ x ) T λ ] = λ ˙ ( t ) -\frac{\partial H}{\partial \mathbf{x}} = -\left[ \frac{\partial L}{\partial \mathbf{x}} + \left(\frac{\partial \mathbf{f}}{\partial \mathbf{x}}\right)^T \boldsymbol{\lambda} \right] = \dot{\boldsymbol{\lambda}}(t) xH=[xL+(xf)Tλ]=λ˙(t)
    • 根据变分和积分的交换律,代价函数的变分 δ J = ∫ t 0 t f δ L ( x , u , t ) d t = ∫ t 0 t f ( ∂ L ∂ x δ x + ∂ L ∂ u δ u ) d t \delta J = \int_{t_0}^{t_f} \delta L(x, u, t) dt = \int_{t_0}^{t_f} \left( \frac{\partial L}{\partial x} \delta x + \frac{\partial L}{\partial u} \delta u \right) dt δJ=t0tfδL(x,u,t)dt=t0tf(xLδx+uLδu)dt
    • 构造增广代价泛函: J a = ∫ t 0 t f [ L ( x , u , t ) + λ T ( t ) f ( x , u , t ) ] d t + Φ ( x ( t f ) ) J_a = \int_{t_0}^{t_f} \left[ L(\mathbf{x}, \mathbf{u}, t) + \lambda^T(t) \mathbf{f}(\mathbf{x}, \mathbf{u}, t) \right] dt + \Phi(\mathbf{x}(t_f)) Ja=t0tf[L(x,u,t)+λT(t)f(x,u,t)]dt+Φ(x(tf))
    • 将其中的 λ T x ˙ \lambda^T \dot{x} λTx˙部分进行分部积分得: J a = ∫ t 0 t f [ L + λ T f + λ ˙ T x ] d t − λ T ( t f ) x ( t f ) + λ T ( t 0 ) x ( t 0 ) + Φ ( x ( t f ) ) J_a = \int_{t_0}^{t_f} \left[ L + \boldsymbol{\lambda}^T f + \dot{\boldsymbol{\lambda}}^T x \right] dt - \boldsymbol{\lambda}^T(t_f) x(t_f) + \boldsymbol{\lambda}^T(t_0) x(t_0)+ \Phi(x(t_f)) Ja=t0tf[L+λTf+λ˙Tx]dtλT(tf)x(tf)+λT(t0)x(t0)+Φ(x(tf))
    • 带入哈密顿函数得: J a = ∫ t 0 t f [ H + λ ˙ T x ] d t − λ T ( t f ) x ( t f ) + λ T ( t 0 ) x ( t 0 ) + Φ ( x ( t f ) ) J_a = \int_{t_0}^{t_f} \left[ H + \dot{\boldsymbol{\lambda}}^T x \right] dt - \boldsymbol{\lambda}^T(t_f) x(t_f) + \boldsymbol{\lambda}^T(t_0) x(t_0)+ \Phi(x(t_f)) Ja=t0tf[H+λ˙Tx]dtλT(tf)x(tf)+λT(t0)x(t0)+Φ(x(tf))
    • 对增广泛函进行变分: δ J a = ∫ t 0 t f [ ∂ H ∂ x δ x + ∂ H ∂ u δ u + λ ˙ T δ x ] d t + [ − λ T ( t f ) δ x ( t f ) + ∂ Φ ∂ x ( t f ) δ x ( t f ) ] = 0 \delta J_a = \int_{t_0}^{t_f} \left[ \frac{\partial H}{\partial x} \delta x + \frac{\partial H}{\partial u} \delta u + \dot{\lambda}^T \delta x \right] dt + \left[ -\lambda^T(t_f) \delta x(t_f) + \frac{\partial \Phi}{\partial x(t_f)} \delta x(t_f) \right] = 0 δJa=t0tf[xHδx+uHδu+λ˙Tδx]dt+[λT(tf)δx(tf)+x(tf)Φδx(tf)]=0
    • 分离变分项
      • 状态变分 δ x \delta x δx ∫ t 0 t f ( ∂ H ∂ x + λ ˙ T ) δ x d t + [ ( − λ T ( t f ) + ∂ Φ ∂ x ( t f ) ) δ x ( t f ) ] = 0 \int_{t_0}^{t_f} \left( \frac{\partial H}{\partial x} + \dot{\lambda}^T \right) \delta x \, dt + \left[ \left( -\lambda^T(t_f) + \frac{\partial \Phi}{\partial x(t_f)} \right) \delta x(t_f) \right] = 0 t0tf(xH+λ˙T)δxdt+[(λT(tf)+x(tf)Φ)δx(tf)]=0
      • 控制变分 δ u \delta u δu ∫ t 0 t f ∂ H ∂ u δ u d t = 0 \int_{t_0}^{t_f} \frac{\partial H}{\partial u} \delta u \, dt = 0 t0tfuHδudt=0
    • 对任意 δ x \delta x δx ,变分 δ J a = 0 \delta J_a = 0 δJa=0 需满足以下条件:
      • 积分项为0: ∂ H ∂ x + λ ˙ T = 0 ⇒ λ ˙ = − ( ∂ H ∂ x ) T \frac{\partial H}{\partial x} + \dot{\lambda}^T = 0 \quad \Rightarrow \quad \dot{\lambda} = -\left( \frac{\partial H}{\partial x} \right)^T xH+λ˙T=0λ˙=(xH)T这就是协态方程
      • 剩余项为0: − λ ( t f ) + ∂ Φ ∂ x ( t f ) = 0 ⇒ λ ( t f ) = ∂ Φ ∂ x ( t f ) -\lambda(t_f) + \frac{\partial \Phi}{\partial x(t_f)} = 0 \quad \Rightarrow \quad \lambda(t_f) = \frac{\partial \Phi}{\partial x(t_f)} λ(tf)+x(tf)Φ=0λ(tf)=x(tf)Φ
    • 对任意 δ u \delta u δu,变分 δ J a = 0 \delta J_a = 0 δJa=0 需满足以下条件:
      • ∂ H ∂ u = 0 (无约束时) 或 u ∗ = arg ⁡ min ⁡ u ∈ U H (有约束时) \frac{\partial H}{\partial u} = 0 \quad \text{(无约束时)} \quad \text{或} \quad u^* = \arg \min_{u \in U} H \quad \text{(有约束时)} uH=0(无约束时)u=arguUminH(有约束时)即:无约束时直接求导为0,有约束时必须是最优控制曲线, u ∗ u^* u为函数空间中的 “驻点”,即沿任何变分方向的泛函变化率为零。
  1. 终端条件
    根据终端状态是否固定,终端条件分为:
    • 终端状态固定( x ( t f ) = x f \mathbf{x}(t_f) = \mathbf{x}_f x(tf)=xf 已知): λ ( t f ) = ∂ ϕ ∂ x ( t f ) \boldsymbol{\lambda}(t_f) = \frac{\partial \phi}{\partial \mathbf{x}(t_f)} λ(tf)=x(tf)ϕ
      • 推导见上方协态方程部分
    • 终端状态自由:
      λ ( t f ) = ∂ ϕ ∂ x ( t f ) , H ( t f ) = − ∂ ϕ ∂ t f ( 若  t f 自由 ) \boldsymbol{\lambda}(t_f) = \frac{\partial \phi}{\partial \mathbf{x}(t_f)}, \quad H(t_f) = -\frac{\partial \phi}{\partial t_f} \quad (\text{若 } t_f \text{ 自由}) λ(tf)=x(tf)ϕ,H(tf)=tfϕ( tf 自由)
  2. 极小值条件(核心条件)
    对于所有 t ∈ [ t 0 , t f ] t \in [t_0, t_f] t[t0,tf] u ( t ) ∈ U \mathbf{u}(t) \in \mathbb{U} u(t)U,最优控制 u ∗ ( t ) \mathbf{u}^*(t) u(t) 需满足: H ( x ∗ ( t ) , u ∗ ( t ) , λ ∗ ( t ) , t ) = min ⁡ u ∈ U H ( x ∗ ( t ) , u , λ ∗ ( t ) , t ) H(\mathbf{x}^*(t), \mathbf{u}^*(t), \boldsymbol{\lambda}^*(t), t) = \min_{\mathbf{u} \in \mathbb{U}} H(\mathbf{x}^*(t), \mathbf{u}, \boldsymbol{\lambda}^*(t), t) H(x(t),u(t),λ(t),t)=uUminH(x(t),u,λ(t),t)
    即哈密顿函数在最优控制处取得极小值(若目标为最大化 J J J,则取极大值)。这一条件体现了控制约束 u ∈ U \mathbf{u} \in \mathbb{U} uU 的作用,当控制无约束时,可通过求导 ∂ H ∂ u = 0 \frac{\partial H}{\partial \mathbf{u}} = \mathbf{0} uH=0 直接求解。

步骤总结

  1. 构造哈密顿函数 H H H,包含状态、控制、伴随变量和时间。
  2. 建立正则方程:
  • 解状态方程 x ˙ = ∂ H ∂ λ \dot{\mathbf{x}} = \frac{\partial H}{\partial \boldsymbol{\lambda}} x˙=λH
  • 解协态方程 λ ˙ = − ∂ H ∂ x \dot{\boldsymbol{\lambda}} = -\frac{\partial H}{\partial \mathbf{x}} λ˙=xH
  1. 确定终端条件:根据终端状态和时间是否固定,设定 λ ( t f ) \boldsymbol{\lambda}(t_f) λ(tf) t f t_f tf 的条件。
  2. 求解极小值条件:利用 H H H u \mathbf{u} u 的极小化(或极大化),结合控制约束 U \mathbb{U} U,求出 u ∗ ( t ) \mathbf{u}^*(t) u(t)
  3. 联立方程求解:将 u ∗ ( t ) \mathbf{u}^*(t) u(t) 代入正则方程,解两点边值问题(BVP)得到 x ∗ ( t ) \mathbf{x}^*(t) x(t) λ ∗ ( t ) \boldsymbol{\lambda}^*(t) λ(t)

简单示例:最速降线问题

以下将通过一个典型的双积分器系统最短时间控制问题,详细讲解如何运用庞特里亚金极小值原理求解最优控制问题。我们将从问题建模、哈密顿函数构造、协态方程推导、控制律求解到最优轨迹分析逐步展开,并使用$$环境呈现公式。

问题设定:双积分器系统的最短时间控制
考虑如下二阶线性系统(双积分器): { x ˙ 1 = x 2 , x ˙ 2 = u , \begin{cases} \dot{x}_1 = x_2, \\ \dot{x}_2 = u, \end{cases} {x˙1=x2,x˙2=u,
其中:

  • x 1 ( t ) , x 2 ( t ) x_1(t), x_2(t) x1(t),x2(t) 为状态变量(位置和速度),
  • u ( t ) u(t) u(t) 为控制输入,满足幅值约束 ∣ u ( t ) ∣ ≤ 1 |u(t)| \leq 1 u(t)1
  • 目标:从初始状态 ( x 10 , x 20 ) (x_{10}, x_{20}) (x10,x20) 转移到终端状态 ( 0 , 0 ) (0, 0) (0,0),且时间最短

系统状态方程建模为:
[ x 1 ˙ x 2 ˙ ] = [ 0 1 0 0 ] [ x 1 x 2 ] + [ 0 1 ] u \begin{bmatrix} \dot{x_1}\\\dot{x_2} \end{bmatrix}=\begin{bmatrix}0 & 1\\0 & 0\end{bmatrix}\begin{bmatrix}x_1 \\x_2\end{bmatrix}+\begin{bmatrix}0 \\1\end{bmatrix}u [x1˙x2˙]=[0010][x1x2]+[01]u

性能指标为:
J = min ⁡ u ∫ 0 T 1 d t = T (最小化时间) . J = \min_u \int_0^T 1 \, dt = T \quad \text{(最小化时间)}. J=umin0T1dt=T(最小化时间).

第一步:构造哈密顿函数
根据庞特里亚金极小值原理,定义哈密顿函数 H H H 为:
H = L + λ T x ˙ = λ 1 x ˙ 1 + λ 2 x ˙ 2 + L \begin{aligned} H &= L + \boldsymbol{\lambda}^T\dot{x} \\ &= \lambda_1 \dot{x}_1 + \lambda_2 \dot{x}_2 + L \end{aligned} H=L+λTx˙=λ1x˙1+λ2x˙2+L
其中:

  • λ 1 ( t ) , λ 2 ( t ) \lambda_1(t), \lambda_2(t) λ1(t),λ2(t) 为协态变量(伴随变量),
  • L L L 为性能指标的被积函数(此处 L = 1 L = 1 L=1)。

代入状态方程 x ˙ 1 = x 2 \dot{x}_1 = x_2 x˙1=x2 x ˙ 2 = u \dot{x}_2 = u x˙2=u,得:
H = λ 1 x 2 + λ 2 u + 1. H = \lambda_1 x_2 + \lambda_2 u + 1. H=λ1x2+λ2u+1.
第二步:推导协态方程
根据PMP,协态变量的导数满足:
λ ˙ i = − ∂ H ∂ x i ( i = 1 , 2 ) . \dot{\lambda}_i = -\frac{\partial H}{\partial x_i} \quad (i=1,2). λ˙i=xiH(i=1,2).
计算偏导数:

  • x 1 x_1 x1 ∂ H ∂ x 1 = 0 \frac{\partial H}{\partial x_1} = 0 x1H=0,故 λ ˙ 1 = 0 \dot{\lambda}_1 = 0 λ˙1=0,即 λ 1 \lambda_1 λ1 为常数,记为 λ 1 = c 1 \lambda_1 = c_1 λ1=c1
  • x 2 x_2 x2 ∂ H ∂ x 2 = λ 1 \frac{\partial H}{\partial x_2} = \lambda_1 x2H=λ1,故 λ ˙ 2 = − λ 1 = − c 1 \dot{\lambda}_2 = -\lambda_1 = -c_1 λ˙2=λ1=c1

因此,协态变量 λ 2 ( t ) \lambda_2(t) λ2(t) 是关于时间的线性函数:
λ 2 ( t ) = − c 1 t + c 2 , \lambda_2(t) = -c_1 t + c_2, λ2(t)=c1t+c2,
其中 c 1 , c 2 c_1, c_2 c1,c2 为常数,由边界条件确定。
第三步:利用极小值条件求解控制律
PMP要求控制输入 u ( t ) u(t) u(t) 在每时刻 t t t 最大化哈密顿函数 H H H,即:
u ∗ ( t ) = arg ⁡ min ⁡ ∣ u ∣ ≤ 1 H = arg ⁡ min ⁡ ∣ u ∣ ≤ 1 ( λ 2 u + 其他 ) . u^*(t) = \arg\min_{|u| \leq 1} H = \arg\min_{|u| \leq 1} \left( \lambda_2 u + \text{其他} \right). u(t)=argu1minH=argu1min(λ2u+其他).
由于 λ 2 \lambda_2 λ2 是线性函数,最大化 H H H 等价于取 u u u λ 2 \lambda_2 λ2 同号。因此:
u ∗ ( t ) = sign ( λ 2 ( t ) ) = { + 1 , λ 2 ( t ) < 0 , − 1 , λ 2 ( t ) > 0. u^*(t) = \text{sign}(\lambda_2(t)) = \begin{cases} +1, & \lambda_2(t) < 0, \\ -1, & \lambda_2(t) > 0. \end{cases} u(t)=sign(λ2(t))={+1,1,λ2(t)<0,λ2(t)>0.
λ 2 ( t ) = 0 \lambda_2(t) = 0 λ2(t)=0 时,可能存在切换点,此时控制输入发生翻转。

第四步:分析协态变量与切换特性
由于 λ 2 ( t ) = − c 1 t + c 2 \lambda_2(t) = -c_1 t + c_2 λ2(t)=c1t+c2 是线性函数,其符号最多改变一次,因此最优控制 u ∗ ( t ) u^*(t) u(t) 最多切换一次,属于Bang-Bang控制。分两种情况讨论:

  1. 无切换(直接Bang):若 λ 2 ( t ) \lambda_2(t) λ2(t) 始终非负或非正,则 u ∗ ( t ) u^*(t) u(t) 保持 + 1 +1 +1 − 1 -1 1 不变;
  2. 一次切换(Bang-Bang):若 λ 2 ( t ) \lambda_2(t) λ2(t) 由正变负或由负变正,则存在唯一切换时刻 τ \tau τ,使得:
    u ∗ ( t ) = { + 1 , t < τ , − 1 , t ≥ τ 或 { − 1 , t < τ , + 1 , t ≥ τ . u^*(t) = \begin{cases} +1, & t < \tau, \\ -1, & t \geq \tau \end{cases} \quad \text{或} \quad \begin{cases} -1, & t < \tau, \\ +1, & t \geq \tau. \end{cases} u(t)={+1,1,t<τ,tτ{1,+1,t<τ,tτ.

第五步:利用终端条件求解常数
终端状态固定为 ( 0 , 0 ) (0, 0) (0,0),终端时间 T T T 自由。根据PMP,终端时刻的横截条件为: H ( T ) = 0. H(T) = 0. H(T)=0.代入 H H H 的表达式:
H ( T ) = λ 1 x 2 ( T ) + λ 2 ( T ) u ( T ) + 1 = 0. H(T) = \lambda_1 x_2(T) + \lambda_2(T) u(T) + 1 = 0. H(T)=λ1x2(T)+λ2(T)u(T)+1=0.
由于 x 2 ( T ) = 0 x_2(T) = 0 x2(T)=0(终端速度为0),化简得:
λ 2 ( T ) u ( T ) + 1 = 0. \lambda_2(T) u(T) + 1 = 0. λ2(T)u(T)+1=0.
又因 u ( T ) = sign ( λ 2 ( T ) ) u(T) = \text{sign}(\lambda_2(T)) u(T)=sign(λ2(T)),故:
∣ λ 2 ( T ) ∣ = 1 ⇒ λ 2 ( T ) = ± 1. |\lambda_2(T)| = 1 \quad \Rightarrow \quad \lambda_2(T) = \pm 1. λ2(T)=1λ2(T)=±1.
结合 λ 2 ( t ) = − c 1 t + c 2 \lambda_2(t) = -c_1 t + c_2 λ2(t)=c1t+c2,可得:
λ 2 ( T ) = − c 1 T + c 2 = ± 1. \lambda_2(T) = -c_1 T + c_2 = \pm 1. λ2(T)=c1T+c2=±1.

第六步:求解状态轨迹与最优控制
先正后负切换(+1→-1为例,假设切换时刻为 τ \tau τ,则:

  • t ∈ [ 0 , τ ] t \in [0, \tau] t[0,τ] 时, u = + 1 u = +1 u=+1,状态方程积分得:
    { x 1 ( t ) = x 10 + x 20 t + 1 2 t 2 , x 2 ( t ) = x 20 + t . \begin{cases} x_1(t) = x_{10} + x_{20} t + \frac{1}{2} t^2, \\ x_2(t) = x_{20} + t. \end{cases} {x1(t)=x10+x20t+21t2,x2(t)=x20+t.
  • t ∈ [ τ , T ] t \in [\tau, T] t[τ,T] 时, u = − 1 u = -1 u=1,状态方程积分得:
    { x 1 ( t ) = x 1 ( τ ) + x 2 ( τ ) ( t − τ ) − 1 2 ( t − τ ) 2 , x 2 ( t ) = x 2 ( τ ) − ( t − τ ) . \begin{cases} x_1(t) = x_1(\tau) + x_2(\tau)(t-\tau) - \frac{1}{2}(t-\tau)^2, \\ x_2(t) = x_2(\tau) - (t-\tau). \end{cases} {x1(t)=x1(τ)+x2(τ)(tτ)21(tτ)2,x2(t)=x2(τ)(tτ).
    终端条件 x 1 ( T ) = 0 , x 2 ( T ) = 0 x_1(T) = 0, x_2(T) = 0 x1(T)=0,x2(T)=0 给出方程组,可解出 τ \tau τ T T T

第七步:相平面分析与开关曲线
最优轨迹在相平面 ( x 1 , x 2 ) (x_1, x_2) (x1,x2) 上的形状由开关曲线决定。开关曲线 Γ \Gamma Γ 分为上下两支:
Γ = Γ + ∪ Γ − , \Gamma = \Gamma^+ \cup \Gamma^-, Γ=Γ+Γ,
其中:

  • Γ + \Gamma^+ Γ+(对应 u = − 1 u=-1 u=1 直接到达原点): x 1 = − 1 2 x 2 2 x_1 = -\frac{1}{2} x_2^2 x1=21x22(当 x 2 ≤ 0 x_2 \leq 0 x20),
  • Γ − \Gamma^- Γ(对应 u = + 1 u=+1 u=+1 直接到达原点): x 1 = 1 2 x 2 2 x_1 = \frac{1}{2} x_2^2 x1=21x22(当 x 2 ≥ 0 x_2 \geq 0 x20)。

若初始状态在 Γ \Gamma Γ 上方,则最优控制为先 + 1 +1 +1 − 1 -1 1;若在下方,则为先 − 1 -1 1 + 1 +1 +1;若在 Γ \Gamma Γ 上,则无需切换。
在这里插入图片描述
具体实现代码:

import numpy as np
import matplotlib.pyplot as pltplt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = Falsedef solve_min_time_control(x10, x20):"""求解双积分器系统的最短时间控制参数(切换时间τ和总时间T)参数:x10: 初始位置x20: 初始速度返回:τ: 切换时间T: 总时间u_seq: 控制序列(分段函数)"""# 开关曲线判断:x1 = 0.5*x2²(上支)或x1 = -0.5*x2²(下支)# 初始状态在开关曲线上方时(x10 > 0.5*x20²),切换策略为 -1 → +1(先制动后加速)if (x20 > 0 and x10 > -0.5 * x20**2) or (x20 < 0 and x10 > 0.5 * x20**2):# 推导方程:τ² - 2x20τ + (0.5x20² - x10) = 0(详细推导见说明)a = 1b = -2 * x20c = 0.5 * x20**2 - x10discriminant = b**2 - 4*a*cif discriminant < 0:raise ValueError("无实数解,初始状态无法到达原点")τ = ( -b + np.sqrt(discriminant) ) / (2*a)  # 取较大的根(保证物理意义)T = 2*τ - x20  # 由x2(T)=0推导得到# 定义分段控制律:前τ时间用-1,之后用+1def u(t):if t < τ:return -1.0else:return 1.0return τ, T, u# 初始状态在开关曲线下方时(x10 < -0.5*x20²),切换策略为 +1 → -1(先加速后制动)elif (x20 > 0 and x10 < -0.5 * x20**2) or (x20 < 0 and x10 < 0.5 * x20**2):# 推导方程:τ² + 2x20τ + (x10 + 0.5x20²) = 0a = 1b = 2 * x20c = x10 + 0.5 * x20**2discriminant = b**2 - 4*a*cif discriminant < 0:raise ValueError("无实数解,初始状态无法到达原点")τ = (-b - np.sqrt(discriminant)) / (2*a)  # 取较小的根T = 2*τ + x20  # 由x2(T)=0推导得到def u(t):if t < τ:return 1.0else:return -1.0return τ, T, u# 初始状态在开关曲线上(无需切换)else:if x20 >= 0:# 上开关曲线(x1=0.5x2²)且速度非负时,直接用-1制动T = x20 + np.sqrt(x20**2 - 2*x10)  # 推导自x2(T)=0和x1(T)=0def u(t):return -1.0else:# 下开关曲线(x1=-0.5x2²)且速度负时,直接用+1加速T = -x20 + np.sqrt(x20**2 + 2*x10)def u(t):return 1.0return 0, T, udef simulate_trajectory(x10, x20, τ, T, u):"""模拟状态轨迹(分切换前后两段积分)"""t1 = np.linspace(0, τ, 100)t2 = np.linspace(τ, T, 100)t_total = np.concatenate([t1, t2])# 切换前控制(u=-1或+1)if u(0) == -1:  # 上开关曲线场景:先-1制动x1_1 = x10 + x20*t1 - 0.5*t1**2x2_1 = x20 - t1else:  # 下开关曲线场景:先+1加速x1_1 = x10 + x20*t1 + 0.5*t1**2x2_1 = x20 + t1# 切换后控制(u=+1或-1)x1_τ = x1_1[-1]  # 切换时刻的x1x2_τ = x2_1[-1]  # 切换时刻的x2dt = t2 - τif u(τ+1e-3) == 1:  # 切换后为+1x1_2 = x1_τ + x2_τ*dt + 0.5*dt**2x2_2 = x2_τ + dtelse:  # 切换后为-1x1_2 = x1_τ + x2_τ*dt - 0.5*dt**2x2_2 = x2_τ - dtx1_total = np.concatenate([x1_1, x1_2])x2_total = np.concatenate([x2_1, x2_2])return t_total, x1_total, x2_totaldef visualize_results(x10, x20, τ, T, t_total, x1_total, x2_total, u):"""可视化相平面轨迹和时间响应"""plt.figure(figsize=(12, 6))# 相平面轨迹(x1 vs x2)plt.subplot(1, 2, 1)plt.plot(x2_total, x1_total, 'b-', label='最优轨迹')plt.scatter(x20, x10, c='r', marker='o', label='初始状态')plt.scatter(0, 0, c='g', marker='s', label='终点(原点)')x2_upper = np.linspace(-5, 0, 100)x2_lower = np.linspace(0, 5, 100)x1_switch_upper = 0.5 * x2_upper**2x1_switch_lower = -0.5 * x2_lower**2plt.plot(x2_upper, x1_switch_upper, 'b--', label='上切换曲线u=1')plt.plot(x2_lower, x1_switch_lower, 'r--', label='下切换曲线u=-1')plt.xlabel('速度 $x_2$')plt.ylabel('位置 $x_1$')plt.title('相平面轨迹')plt.legend()plt.grid(True)# 时间响应(x1(t), x2(t), u(t))plt.subplot(1, 2, 2)plt.plot(t_total, x1_total, 'r-', label='$x_1(t)$')plt.plot(t_total, x2_total, 'g-', label='$x_2(t)$')u_values = [u(t) for t in t_total]plt.step(t_total, u_values, 'b--', label='$u(t)$', where='post')plt.xlabel('时间 $t$')plt.ylabel('状态/控制')plt.title('时间响应曲线')plt.legend()plt.grid(True)plt.tight_layout()plt.show()# 主程序运行(示例初始状态)
if __name__ == "__main__":x10, x20 = 2.0, 4.0  # 初始状态(位置=2,速度=1)τ, T, u = solve_min_time_control(x10, x20)t_total, x1_total, x2_total = simulate_trajectory(x10, x20, τ, T, u)print(f"切换时间 τ = {τ:.2f}s,总时间 T = {T:.2f}s")visualize_results(x10, x20, τ, T, t_total, x1_total, x2_total, u)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/web/81739.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DeepSeek 提示词大全

目录 前言一、提示词基础理论 什么是提示词提示词的类型提示词的基本结构 二、提示词设计原则 明确指令结构化表达情境化需求渐进式引导边界与限制 三、场景化提示词模板 写作创作类角色扮演类信息提取类代码编程类教育学习类商业营销类生活助手类 四、提示词优化技巧 迭代式优…

安科瑞Acrelcloud-6200系统:智慧路灯安全用电监控平台架构解析

安科瑞顾强———Acrelgq 智慧路灯作为智慧城市与新基建的核心载体&#xff0c;集成了大量异元异构电子设备&#xff0c;其供电安全与能效管理面临电压多样、权属分散、扩展性不足等挑战。本文提出一种融合统一供电、分路计量、智能防护与远程监控的解决方案&#xff0c;通过构…

DMBOK对比知识点对比(1)

1.CDGP各章活动 章节一级

css设置动态数值:clamp函数

CSS 的 clamp() 函数是一个强大的工具&#xff0c;用于创建响应式且范围可控的动态值。它结合了min() 和max() 的逻辑&#xff0c;允许你定义一个值在最小值和最大值之间动态调整。 语法为&#xff1a; clamp(最小值, 首选值, 最大值)&#xff1b; 工作原理&#xff1a; 当 …

数值计算与数据相关参数剖析:保障模型训练稳定与准确

一、计算类型&#xff1a;以BF16为例 1.1 核心作用 BF16 是一种计算方式&#xff0c;它能让模型训练更快&#xff0c;还省内存。比如训练模型时&#xff0c;用普通方式可能很慢&#xff0c;占内存也多&#xff0c;而 BF16 就像给模型开了 “加速键”&#xff0c;训练起来更高…

数据库读写分离解决方案

数据库读写分离解决方案 一、读写分离核心概念 读写分离(Read/Write Splitting)是通过将数据库的读操作和写操作分离到不同的数据库节点来提升系统整体性能的架构模式。 核心原则:写操作集中在主库(Master),读操作分散到从库(Slave),通过数据复制保持主从一致性 二、技术实…

小白的进阶之路系列之七----人工智能从初步到精通pytorch自动微分优化以及载入和保存模型

本文将介绍Pytorch的以下内容 自动微分函数 优化 模型保存和载入 好了,我们首先介绍一下关于微分的内容。 在训练神经网络时,最常用的算法是反向传播算法。在该算法中,根据损失函数相对于给定参数的梯度来调整参数(模型权重)。 为了计算这些梯度,PyTorch有一个内置…

【图像处理基石】立体匹配的经典算法有哪些?

1. 立体匹配的经典算法有哪些&#xff1f; 立体匹配是计算机视觉中从双目图像中获取深度信息的关键技术&#xff0c;其经典算法按技术路线可分为以下几类&#xff0c;每类包含若干代表性方法&#xff1a; 1.1 基于区域的匹配算法&#xff08;Local Methods&#xff09; 通过…

《Map 到底适合用哪个?HashMap、TreeMap、LinkedHashMap 对比实战》

大家好呀&#xff01;今天我们来聊聊Java中超级重要的Map集合家族 &#x1f3a2;。Map就像是一个神奇的魔法口袋&#xff0c;可以帮我们把东西&#xff08;值&#xff09;和标签&#xff08;键&#xff09;一一对应存放起来。不管你是Java新手还是老司机&#xff0c;掌握Map都是…

TencentOSTiny

开放原子开源基金会 腾讯物联网终端操作系统 _物联网操作系统_物联网OS_TencentOS tiny-腾讯云 GitHub - OpenAtomFoundation/TobudOS: 开放原子开源基金会孵化的物联网操作系统&#xff0c;捐赠前为腾讯物联网终端操作系统TencentOS Tiny 项目简介 TencentOS Tiny 是腾讯…

使用 Selenium 进行自动化测试:入门指南

在现代软件开发中&#xff0c;自动化测试已经成为不可或缺的一部分。它不仅提高了测试效率&#xff0c;还减少了人为错误的可能性。Selenium 是一个强大的开源工具&#xff0c;广泛用于 Web 应用程序的自动化测试。本文将详细介绍如何使用 Selenium 进行自动化测试&#xff0c;…

C54-动态开辟内存空间

1.malloc 原型&#xff1a;void* malloc(size_t size);&#xff08;位于 <stdlib.h> 头文件中&#xff09; 作用&#xff1a;分配一块连续的、未初始化的内存块&#xff0c;大小为 size 字节。 返回值&#xff1a; 成功&#xff1a;返回指向分配内存首地址的 void* 指针…

ELK服务搭建-0-1搭建记录

ELK搭建 需要准备一台linux服务器&#xff08;最好是CentOS7&#xff09;,内存至少4G以上&#xff08;三个组件都比较占用内存&#xff09; 演示基于ElasticSearch采用的是8.5.0版本 1、 Docker安装Elasticsearch 创建一个网络 因为我们还需要部署kibana容器、logstash容器&am…

调参指南:如何有效优化模型训练效果

🚀 调参指南:如何有效优化模型训练效果(深度学习实战) 模型跑通不难,调得好才是本事。本篇文章将系统讲解如何在训练过程中有效调参,从学习率到网络结构,从损失函数到正则化,让你的模型效果“飞升”。 🧠 一、为什么需要调参? 初学者常常以为模型训练完就“任务完…

laya3的2d相机与2d区域

2d相机和2d区域都继承自Sprite。 2d相机必须作为2d区域的子节点&#xff0c;且2d相机必须勾选isMain才能正常使用。 2d区域下如果没有主相机&#xff0c;则他和Sprite无异&#xff0c;他的主要操作皆是针对主相机。 2d相机可以调整自己的移动范围&#xff0c;是否紧密跟随&a…

【保姆级教程】Windows部署LibreTV+cpolar实现远程影音库访问全步骤

文章目录 前言1.关于LibreTV2.docker部署LibreTV3.简单使用LibreTV4.安装cpolar内网穿透5.配置ward公网地址6.配置固定公网地址总结 前言 当周末的闲暇时光来临时&#xff0c;您是否也习惯性地瘫倒在沙发上&#xff0c;渴望通过影视作品缓解一周的疲惫&#xff1f;然而在准备点…

Windows安装Docker部署dify,接入阿里云api-key进行rag测试

一、安装docker 1.1 傻瓜式安装docker Get Docker | Docker Docs Docker原理&#xff08;图解秒懂史上最全&#xff09;-CSDN博客 官网选择好windows的安装包下载&#xff0c;傻瓜式安装。如果出现下面的报错&#xff0c;说明主机没有安装WSL 1.2 解决办法 安装 WSL | Mic…

Cursor 与DeepSeek的完美契合

这两天在看清华大学最近出的一个关于deepseek入门的官方视频中&#xff0c;看了几个deepseek的应用场景还是能够感觉到它的强大之处的&#xff0c;例如根据需求生成各种markdown格式的代码&#xff0c;再结合市面上已有的一些应用平台生成非常好看的流程图&#xff0c;PPT,报表…

【深度学习】13. 图神经网络GCN,Spatial Approach, Spectral Approach

图神经网络 图结构 vs 网格结构 传统的深度学习&#xff08;如 CNN 和 RNN&#xff09;在处理网格结构数据&#xff08;如图像、语音、文本&#xff09;时表现良好&#xff0c;因为这些数据具有固定的空间结构。然而&#xff0c;真实世界中的很多数据并不遵循网格结构&#x…

[Python] 避免 PyPDF2 写入 PDF 出现黑框问题:基于语言自动匹配系统字体的解决方案

在使用 Python 操作 PDF 文件时,尤其是在处理中文、日语等非拉丁字符语言时,常常会遇到一个令人头疼的问题——文字变成“黑框”或“方块”,这通常是由于缺少合适的字体支持所致。本文将介绍一种自动选择系统字体的方式,结合 PyPDF2 模块解决此类问题。 一、问题背景:黑框…