终端时刻固定、终端状态固定
x ′ = − x + u x'=-x+u x′=−x+u, x ( 0 ) = 2 x(0)=2 x(0)=2, x ( 1 ) = 1 x(1)=1 x(1)=1, J = 0.5 ∫ 0 1 ( x 2 + u 2 ) d t J=0.5\int_0^1(x^2+u^2)\text{d}t J=0.5∫01(x2+u2)dt,求使 J J J最小的解u*(t)。
经典变分定义法
设
x
(
t
)
=
x
0
(
t
)
+
ϵ
η
(
t
)
x(t)=x_0(t)+\epsilon\eta(t)
x(t)=x0(t)+ϵη(t),则
J
=
0.5
∫
0
1
f
(
x
,
x
′
,
u
)
d
t
=
0.5
∫
0
1
(
(
x
0
+
ϵ
η
)
2
+
u
2
)
d
t
d
J
d
ϵ
=
∫
0
1
(
∂
f
∂
x
∂
x
∂
ϵ
+
∂
f
∂
u
∂
u
∂
ϵ
)
d
t
=
∫
0
1
(
x
η
+
u
(
η
′
+
η
)
)
d
t
=
∫
0
1
(
x
η
+
(
x
+
x
′
)
(
η
′
+
η
)
)
d
t
=
∫
0
1
(
(
2
x
+
x
′
)
η
+
(
x
+
x
′
)
η
′
)
d
t
=
∫
0
1
(
2
x
+
x
′
)
η
d
t
+
∫
0
1
(
x
+
x
′
)
d
η
=
∫
0
1
(
2
x
−
x
′
′
)
η
d
t
+
[
(
x
+
x
′
)
η
]
0
1
\begin{aligned} J&=0.5\int_0^1f(x,x',u)\text{d}t=0.5\int_0^1((x_0+\epsilon\eta)^2+u^2)\text{d}t \\ \frac{\text{d}J}{\text{d}\epsilon} &=\int_0^1(\frac{\partial f}{\partial x}\frac{\partial x}{\partial \epsilon}+\frac{\partial f}{\partial u}\frac{\partial u}{\partial \epsilon})\text{d}t \\ &=\int_0^1(x\eta+u(\eta'+\eta))\text{d}t \\ &=\int_0^1(x\eta+(x+x')(\eta'+\eta))\text{d}t \\ &=\int_0^1((2x+x')\eta+(x+x')\eta')\text{d}t \\ &=\int_0^1(2x+x')\eta\text{d}t+\int_0^1(x+x')\text{d}\eta \\ &=\int_0^1(2x-x'')\eta\text{d}t+\left[(x+x')\eta\right]_0^1 \\ \end{aligned}
JdϵdJ=0.5∫01f(x,x′,u)dt=0.5∫01((x0+ϵη)2+u2)dt=∫01(∂x∂f∂ϵ∂x+∂u∂f∂ϵ∂u)dt=∫01(xη+u(η′+η))dt=∫01(xη+(x+x′)(η′+η))dt=∫01((2x+x′)η+(x+x′)η′)dt=∫01(2x+x′)ηdt+∫01(x+x′)dη=∫01(2x−x′′)ηdt+[(x+x′)η]01
因为
η
(
0
)
=
η
(
1
)
\eta(0)=\eta(1)
η(0)=η(1),所以
2
x
−
x
′
′
=
0
2x-x''=0
2x−x′′=0,
x
(
t
)
=
C
1
e
2
t
+
C
2
e
−
2
t
x(t)=C_1\text{e}^{\sqrt{2}t}+C_2\text{e}^{-\sqrt{2}t}
x(t)=C1e2t+C2e−2t,代入起止条件解得
x
(
t
)
=
0.13275162522663497
e
2
t
+
1.867248374773365
e
−
2
t
x(t)=0.13275162522663497\text{e}^{\sqrt{2}t}+1.867248374773365\text{e}^{-\sqrt{2}t}
x(t)=0.13275162522663497e2t+1.867248374773365e−2t
经典变分法
2 f = x 2 + u 2 = x 2 + ( x + x ′ ) 2 = x ′ 2 + 2 x x ′ + 2 x 2 ∂ f ∂ x = d d t ∂ f ∂ x ′ x ′ + 2 x = ( x + x ′ ) ′ x ′ ′ = 2 x \begin{aligned} & 2f=x^2+u^2=x^2+(x+x')^2=x'^2+2xx'+2x^2 \\ & \frac{\partial f}{\partial x}=\frac{\text{d}}{\text{d}t}\frac{\partial f}{\partial x'} \\ & x'+2x=(x+x')' \\ & x''=2x \\ \end{aligned} 2f=x2+u2=x2+(x+x′)2=x′2+2xx′+2x2∂x∂f=dtd∂x′∂fx′+2x=(x+x′)′x′′=2x
哈密顿方程组法
H
=
f
(
x
,
x
′
,
u
)
+
p
(
x
)
g
(
x
)
=
0.5
(
x
2
+
u
2
)
+
p
(
−
x
+
u
)
∂
H
∂
u
=
0
=
u
+
p
∂
H
∂
p
=
x
′
=
−
x
+
u
∂
H
∂
x
=
−
p
′
=
x
−
p
\begin{aligned} & H=f(x,x',u)+p(x)g(x)=0.5(x^2+u^2)+p(-x+u) \\ & \frac{\partial H}{\partial u}=0=u+p \\ & \frac{\partial H}{\partial p}=x'=-x+u \\ & \frac{\partial H}{\partial x}=-p'=x-p \\ \end{aligned}
H=f(x,x′,u)+p(x)g(x)=0.5(x2+u2)+p(−x+u)∂u∂H=0=u+p∂p∂H=x′=−x+u∂x∂H=−p′=x−p
解得
x
′
′
=
2
x
x''=2x
x′′=2x。
仿真结果
x: 1
x’: 0.13022268764
u: 1.13022268764
J: 1.01806017092
终端时刻固定、终端状态自由
在前面问题的基础上, x ( 1 ) x(1) x(1)为任意值。由 x ( 1 ) + x ′ ( 1 ) = 0 x(1)+x'(1)=0 x(1)+x′(1)=0计算得到 x x x。
仿真结果
x: 0.563939069277
x’: -0.563939069277
u: -3.10862446895e-14
J: 0.771637192373
相关代码
import numpy as np
from scipy import integrate
def f(t):
tx = np.sqrt(2)
ty = np.exp(tx)
C2 = (2*ty-1)/(ty-1/ty)
C1 = 2-C2
x = C1*np.exp(tx*t) + C2*np.exp(-tx*t)
x1 = C1*tx*np.exp(tx*t) - C2*tx*np.exp(-tx*t)
u = x + x1
return 0.5*(u*u + x*x)
v, err=integrate.quad(f, 0, 1)
print(v, err)
#include <iostream>
#include "simucpp.hpp"
using namespace simucpp;
using namespace std;
class Funcu: public UserFunc
{
public:
virtual double Function(double t) const {
double tx = sqrt(2);
double ty = exp(tx);
double C2 = (2*ty-1)/(ty-1/ty);
double C1 = 2-C2;
// double C1 = 2/(1+exp(2*sqrt(2)));
// double C2 = 2 - C1;
double x = C1*exp(tx*t) + C2*exp(-tx*t);
double x1 = C1*tx*exp(tx*t) - C2*tx*exp(-tx*t);
return x + x1;
}
};
class FuncJ: public UserFunc
{
public:
virtual double Function(double *u) const {
return 0.5*(u[0]*u[0]+u[1]*u[1]);
}
};
int main()
{
Simulator sim1(1);
FMInput(minu, &sim1);
FMSum(msumx, &sim1);
FMFcnMISO(mfcnJ, &sim1);
FMIntegrator(mintx, &sim1);
FMIntegrator(mintJ, &sim1);
FMOutput(moutu, &sim1);
FMOutput(moutx, &sim1);
sim1.connect(minu, msumx);
sim1.connect(msumx,mintx);
sim1.connect(mintx, msumx);
msumx->Set_InputGain(-1);
sim1.connect(mintx, mfcnJ);
sim1.connect(minu, mfcnJ);
sim1.connect(mfcnJ, mintJ);
sim1.connect(minu, moutu);
sim1.connect(mintx, moutx);
Funcu *funcu = new Funcu;
FuncJ *funcJ = new FuncJ;
minu->Set_Function(funcu);
mfcnJ->Set_Function(funcJ);
mintx->Set_InitialValue(2);
sim1.Initialize();
sim1.Simulate();
cout.precision(12);
cout << "x" <<": "<< mintx->Get_OutValue() <<endl;
cout << "x'" <<": "<< msumx->Get_OutValue() <<endl;
cout << "u" <<": "<< minu->Get_OutValue() <<endl;
cout << "J" <<": "<< mintJ->Get_OutValue() <<endl;
sim1.Plot();
return 0;
}
参考
python3通过scipy实现定积分
张杰,王飞跃. 最优控制:数学理论与智能方法(上册).