设等式约束优化问题
{
minimize
f
(
x
)
s.t.
h
(
x
)
=
o
(
1
)
\begin{cases} \text{minimize}\quad f(\boldsymbol{x})\\ \text{s.t. }\quad\quad\boldsymbol{h}(\boldsymbol{x})=\boldsymbol{o} \end{cases}\quad\quad{(1)}
{minimizef(x)s.t. h(x)=o(1)
其中
f
:
R
n
→
R
f:\text{R}^n\rightarrow\text{R}
f:Rn→R,
h
:
R
n
→
R
l
\boldsymbol{h}:\text{R}^n\rightarrow\text{R}^l
h:Rn→Rl,在
R
n
\text{R}^n
Rn上连续。可行域
Ω
=
{
x
∣
h
(
x
)
=
o
}
\Omega=\{\boldsymbol{x}|\boldsymbol{h}(\boldsymbol{x})=\boldsymbol{o}\}
Ω={x∣h(x)=o}。构造罚函数
P
(
x
)
=
1
2
h
(
x
)
⊤
h
(
x
)
P(\boldsymbol{x})=\frac{1}{2}\boldsymbol{h}(\boldsymbol{x})^\top\boldsymbol{h}(\boldsymbol{x})
P(x)=21h(x)⊤h(x)
称
R
n
→
R
\text{R}^n\rightarrow\text{R}
Rn→R函数
F
(
x
,
σ
)
=
f
(
x
)
+
σ
P
(
x
)
F(\boldsymbol{x},\sigma)=f(\boldsymbol{x})+\sigma P(\boldsymbol{x})
F(x,σ)=f(x)+σP(x)
为问题(1)的{\heiti{增广目标函数}},其中
σ
>
0
\sigma>0
σ>0,称为罚因子。注意到
F
(
x
,
σ
)
=
f
(
x
)
F(\boldsymbol{x},\sigma)=f(\boldsymbol{x})
F(x,σ)=f(x),当且仅当
x
∈
Ω
\boldsymbol{x}\in\Omega
x∈Ω。考虑无约束优化问题
{
minimize
F
(
x
,
σ
)
s.t.
x
∈
R
n
,
(
2
)
\begin{cases} \text{minimize}\quad F(\boldsymbol{x},\sigma)\\ \text{s.t.\ \ }\quad\quad\boldsymbol{x}\in\text{R}^n \end{cases},\quad\quad{(2)}
{minimizeF(x,σ)s.t. x∈Rn,(2)
称为(1)的子问题。给定罚因子
σ
>
0
\sigma>0
σ>0,设子问题(2)最优解
x
σ
=
arg
min
x
∈
R
n
F
(
x
,
σ
)
\boldsymbol{x}_{\sigma}=\arg\min\limits_{\boldsymbol{x}\in\text{R}^n}F(\boldsymbol{x},\sigma)
xσ=argx∈RnminF(x,σ)。若
x
σ
∈
Ω
\boldsymbol{x}_{\sigma}\in\Omega
xσ∈Ω,则
σ
P
(
x
σ
)
=
0
\sigma P(\boldsymbol{x}_{\sigma})=0
σP(xσ)=0,且
F
(
x
σ
,
σ
)
=
f
(
x
σ
)
F(\boldsymbol{x}_{\sigma},\sigma)=f(\boldsymbol{x}_{\sigma})
F(xσ,σ)=f(xσ)。故
x
σ
\boldsymbol{x}_{\sigma}
xσ可以视为
f
(
x
)
f(\boldsymbol{x})
f(x)最优解的近似值。否则,即
x
σ
∉
Ω
\boldsymbol{x}_{\sigma}\not\in\Omega
xσ∈Ω,则
σ
P
(
x
σ
)
\sigma P(\boldsymbol{x}_\sigma)
σP(xσ)是一个正数,其存在是对
x
σ
\boldsymbol{x}_\sigma
xσ脱离
Ω
\Omega
Ω的一种“惩罚”。此时,若加大
σ
′
>
σ
\sigma'>\sigma
σ′>σ,再次尝试求解子问题
x
σ
′
=
arg
min
x
∈
R
n
F
(
x
,
σ
′
)
\boldsymbol{x}_{\sigma'}=\arg\min\limits_{\boldsymbol{x}\in\text{R}^n} F(\boldsymbol{x},\sigma')
xσ′=argx∈RnminF(x,σ′),意欲迫使
x
σ
′
\boldsymbol{x}_{\sigma'}
xσ′向
Ω
\Omega
Ω靠拢。可以证明以下命题
定理1:若约束优化问题(1)存在唯一最优解
x
0
\boldsymbol{x}_0
x0,子问题(2)对任意
σ
>
0
\sigma>0
σ>0,均有最优解
x
σ
\boldsymbol{x}_\sigma
xσ。给定序列
0
<
σ
1
<
σ
2
<
⋯
<
σ
k
<
⋯
0<\sigma_1<\sigma_2<\cdots<\sigma_k<\cdots
0<σ1<σ2<⋯<σk<⋯,且
lim
k
→
∞
σ
k
=
+
∞
\lim\limits_{k\rightarrow\infty}\sigma_k=+\infty
k→∞limσk=+∞。按迭代式
x
k
=
arg
min
x
∈
R
n
F
(
x
,
σ
k
)
\boldsymbol{x}_k=\arg\min_{\boldsymbol{x}\in\text{R}^n}F(\boldsymbol{x},\sigma_k)
xk=argx∈RnminF(x,σk)
算得序列
{
x
k
}
\{\boldsymbol{x}_k\}
{xk},则必有
{
lim
k
→
∞
x
k
=
x
0
lim
k
→
∞
σ
k
P
(
x
k
)
=
0
.
\begin{cases} \lim\limits_{k\rightarrow\infty}\boldsymbol{x}_k=\boldsymbol{x}_0\\ \lim\limits_{k\rightarrow\infty}\sigma_k P(\boldsymbol{x}_k)=0 \end{cases}.
⎩
⎨
⎧k→∞limxk=x0k→∞limσkP(xk)=0.
对一般的有约束优化问题
{
minimize
f
(
x
)
s.t.
h
(
x
)
=
o
g
(
x
)
≥
o
(
3
)
\begin{cases} \text{minimize}\quad f(\boldsymbol{x})\\ \text{s.t.\ \ }\quad\quad\boldsymbol{h}(\boldsymbol{x})=\boldsymbol{o}\\ \quad\quad\quad\quad\boldsymbol{g}(\boldsymbol{x})\geq\boldsymbol{o} \end{cases}\quad\quad{(3)}
⎩
⎨
⎧minimizef(x)s.t. h(x)=og(x)≥o(3)
其中,
f
:
R
n
→
R
f:\text{R}^n\rightarrow\text{R}
f:Rn→R,
h
:
R
n
→
R
l
\boldsymbol{h}:\text{R}^n\rightarrow\text{R}^l
h:Rn→Rl,
g
:
R
n
→
R
m
\boldsymbol{g}:\text{R}^n\rightarrow\text{R}^m
g:Rn→Rm。
f
(
x
)
f(\boldsymbol{x})
f(x),
h
(
x
)
\boldsymbol{h}(\boldsymbol{x})
h(x),
g
(
x
)
\boldsymbol{g}(\boldsymbol{x})
g(x)在
R
n
\text{R}^n
Rn上连续。可行域
Ω
=
{
x
∣
h
(
x
)
=
o
,
g
(
x
)
≥
o
}
\Omega=\{\boldsymbol{x}|\boldsymbol{h}(\boldsymbol{x})=\boldsymbol{o},\boldsymbol{g}(\boldsymbol{x})\geq\boldsymbol{o}\}
Ω={x∣h(x)=o,g(x)≥o}。定义罚函数
P
(
x
)
=
h
(
x
)
⊤
h
(
x
)
+
g
1
(
x
)
⊤
g
1
(
x
)
.
P(\boldsymbol{x})=\boldsymbol{h}(\boldsymbol{x})^\top\boldsymbol{h}(\boldsymbol{x})+\boldsymbol{g}_1(\boldsymbol{x})^\top\boldsymbol{g}_1(\boldsymbol{x}).
P(x)=h(x)⊤h(x)+g1(x)⊤g1(x).
其中,
g
1
(
x
)
=
min
(
o
,
g
(
x
)
)
=
(
min
(
0
,
g
1
(
x
)
)
⋮
min
(
0
,
g
m
(
x
)
)
)
\boldsymbol{g}_1(\boldsymbol{x})=\boldsymbol{\min}(\boldsymbol{o},\boldsymbol{g}(\boldsymbol{x}))=\begin{pmatrix}\min(0,g_1(\boldsymbol{x}))\\\vdots\\\min(0,g_m(\boldsymbol{x}))\end{pmatrix}
g1(x)=min(o,g(x))=
min(0,g1(x))⋮min(0,gm(x))
。不难证实
{
P
(
x
)
=
0
x
∈
Ω
P
(
x
)
>
0
x
∉
Ω
,
\begin{cases} P(\boldsymbol{x})=0&\boldsymbol{x}\in\Omega\\ P(\boldsymbol{x})>0&\boldsymbol{x}\not\in\Omega \end{cases},
{P(x)=0P(x)>0x∈Ωx∈Ω,
且在
R
n
\text{R}^n
Rn上连续。取罚因子
σ
>
0
\sigma>0
σ>0,定义增广目标函数:
F
(
x
,
σ
)
=
f
(
x
)
+
σ
P
(
x
)
.
F(\boldsymbol{x},\sigma)=f(\boldsymbol{x})+\sigma P(\boldsymbol{x}).
F(x,σ)=f(x)+σP(x).
及子问题
{
minimize
F
(
x
,
σ
)
s.t.
x
∈
R
n
(
4
)
\begin{cases} \text{minimize}\quad F(\boldsymbol{x},\sigma)\\ \text{s.t.}\quad\quad\quad\boldsymbol{x}\in\text{R}^n \end{cases}\quad\quad{(4)}
{minimizeF(x,σ)s.t.x∈Rn(4)
则关于等式约束优化问题(1)及其子问题(2)的定理1的结论对问题(3)及其子问题(4)均成立。根据定理1,对问题(4)给定罚因子初始值
σ
1
>
0
\sigma_1>0
σ1>0(典型值为10)、放大系数
c
>
1
c>1
c>1(典型值为2.5)及容错误差
ε
>
0
\varepsilon>0
ε>0,按
x
k
+
1
=
arg
min
x
∈
R
n
F
(
x
,
σ
k
)
\boldsymbol{x}_{k+1}=\arg\min_{\boldsymbol{x}\in\text{R}^n}F(\boldsymbol{x},\sigma_k)
xk+1=argx∈RnminF(x,σk)
做迭代,直至
σ
k
P
(
x
k
)
<
ε
\sigma_k P(\boldsymbol{x}_k)<\varepsilon
σkP(xk)<ε为止。所得当前
x
k
\boldsymbol{x}_k
xk即为问题(3)的最优解近似值。由于罚函数是关于约束函数的二次式,故此算法常称为二次罚函数算法。该算法以一系列子问题的最优解来逼近问题的最优解,也被称为序列无约束极小化方法简记为SUMT方法。
下列代码实现罚函数算法。
import numpy as np #导入numpy
from scipy.optimize import minimize,OptimizeResult #导入minimize,OptimizeResult
def sumt(f, x1, h = None, g = None, eps = 1e-5):
if not callable(h): #没有等式约束
h = lambda x: np.zeros(1) #置零
if callable(g):
m = g(x1).size #g的维数
zero = np.zeros(m)
g1 = lambda x: np.minimum(zero, g(x)) #转换不等式约束
else: #没有不等式约束
g1 = lambda x: np.zeros(1) #置零
sigmak = 10.0 #初始罚因子
c = 2.5 #罚因子放大系数
sPk = 10.0 #初始罚项
k = 0 #初始迭代数
xk = x1 #初始迭代解向量
P = lambda x: 0.5 * (np.dot(h(x), h(x)) + np.dot(g1(x), g1(x))) #罚函数
F = lambda x: f(x) + sigmak * P(x) #子问题目标函数
while sPk >= eps: #迭代
k += 1 #迭代次数自增1
result = minimize(F,xk) #求解子问题
xk = result.x #子问题最优解
sPk = result.fun - f(xk) #罚项
sigmak *= c #放大罚因子
return OptimizeResult(fun = f(xk), x = xk, nit = k)
程序的第3~25行定义的sumt函数实现求解一般约束优化问题的二次罚函数算法(序列无约束极小化SUMT方法)。该函数的参数f,x1表示约束优化问题的目标函数
f
(
x
)
f(\boldsymbol{x})
f(x)和初始解向量
x
1
\boldsymbol{x}_1
x1。h表示等式约束函数
h
(
x
)
\boldsymbol{h}(\boldsymbol{x})
h(x)缺省值为None,表示优化问题无等式约束。g表示不等式约束函数
g
(
x
)
\boldsymbol{g}(\boldsymbol{x})
g(x),缺省值为None,表示问题无不等式约束。参数eps表示容错误差
ε
\varepsilon
ε。
函数体内第4~5行对无等式约束的情况将h置为零函数,以便统一代码。第6~11行的if-else语句根据是否有不等式约束,设置表示
g
1
(
x
)
=
min
(
g
(
x
)
,
o
)
\boldsymbol{g}_1(\boldsymbol{x})=\boldsymbol{\min}(\boldsymbol{g}(\boldsymbol{x}),\boldsymbol{o})
g1(x)=min(g(x),o)便于统一代码的形式。第12~16行分别对罚因子
σ
k
\sigma_k
σk、罚因子放大系数
c
c
c、罚项
σ
k
P
(
x
k
)
\sigma_kP(\boldsymbol{x}_k)
σkP(xk)、迭代次数
k
k
k及解向量
x
k
\boldsymbol{x}_k
xk作初始化操作。第19~24行的while语句完成算法的迭代。其中,第21行调用scipy.optimize模块中的minimize函数求解子问题,返回值赋予result。第22行读取迭代解向量xk,第23行计算罚项
σ
k
P
(
x
k
)
=
F
(
x
k
,
σ
k
)
−
f
(
x
k
)
\sigma_kP(\boldsymbol{x}_k)=F(\boldsymbol{x}_k,\sigma_k)-f(\boldsymbol{x}_k)
σkP(xk)=F(xk,σk)−f(xk),赋予sPk。第24行放大罚因子
σ
k
=
c
×
σ
k
\sigma_k=c\times\sigma_k
σk=c×σk。迭代结束,第25行返回问题的最优解近似值
x
k
\boldsymbol{x}_k
xk、最优值近似值
f
(
x
k
)
f(\boldsymbol{x}_k)
f(xk)和迭代次数
k
k
k。
例1:用函数sumt求解求解线性规划
{
minimize
x
1
−
x
2
s.t.
−
x
1
+
2
x
2
+
x
3
≤
2
−
4
x
1
+
4
x
2
−
x
3
=
4
x
1
−
x
3
=
0
x
1
,
x
2
,
x
3
≥
0
,
\begin{cases} \text{minimize}\quad\quad x_1-x_2\\ \text{s.t.\ \ \ \ \ }\quad\quad -x_1+2x_2+x_3\leq2\\ \quad\quad\quad\quad\quad -4x_1+4x_2-x_3=4\\ \quad\quad\quad\quad\quad x_1-x_3=0\\ \quad\quad\quad\quad\quad x_1,x_2,x_3\geq0 \end{cases},
⎩
⎨
⎧minimizex1−x2s.t. −x1+2x2+x3≤2−4x1+4x2−x3=4x1−x3=0x1,x2,x3≥0,
给定初始迭代点
x
1
=
o
\boldsymbol{x}_1=\boldsymbol{o}
x1=o。
解:这个线性规划的数据矩阵为
c
=
(
1
−
1
0
)
,
A
e
q
=
(
−
4
4
−
1
1
0
−
1
)
,
b
e
q
=
(
4
0
)
,
A
i
q
=
(
1
−
2
−
1
1
0
0
0
1
0
0
0
1
)
,
b
i
q
=
(
−
2
0
0
0
)
.
\boldsymbol{c}=\begin{pmatrix}1\\-1\\0\end{pmatrix},\boldsymbol{A}_{eq}=\begin{pmatrix}-4&4&-1\\1&0&-1\end{pmatrix},\boldsymbol{b}_{eq}=\begin{pmatrix}4\\0\end{pmatrix},\boldsymbol{A}_{iq}=\begin{pmatrix}1&-2&-1\\1&0&0\\0&1&0\\0&0&1\end{pmatrix},\boldsymbol{b}_{iq}=\begin{pmatrix}-2\\0\\0\\0\end{pmatrix}.
c=
1−10
,Aeq=(−4140−1−1),beq=(40),Aiq=
1100−2010−1001
,biq=
−2000
.
于是
f
(
x
)
=
c
⊤
x
,
h
(
x
)
=
A
e
q
−
b
e
q
,
g
(
x
)
=
A
i
q
−
b
i
p
.
f(\boldsymbol{x})=\boldsymbol{c}^\top\boldsymbol{x},\quad\boldsymbol{h}(\boldsymbol{x})=\boldsymbol{A}_{eq}-\boldsymbol{b}_{eq},\quad\boldsymbol{g}(\boldsymbol{x})=\boldsymbol{A}_{iq}-\boldsymbol{b}_{ip}.
f(x)=c⊤x,h(x)=Aeq−beq,g(x)=Aiq−bip.
利用这些数据,下列代码完成计算。
import numpy as np #导入numpy
c = np.array([1, -1, 0]) #向量c
Ae = np.array([[-4, 4, -1], #矩阵Aeq
[1, 0, -1]])
be = np.array([4, 0]) #向量beq
Ai = np.array([[1, -2, -1], #矩阵Aiq
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
bi = np.array([-2, 0, 0, 0]) #向量biq
f = lambda x: np.dot(c, x) #目标函数
h = lambda x: np.matmul(Ae, x) - be #等式约束函数
g = lambda x: np.matmul(Ai, x) - bi #不等式约束函数
x1 = np.zeros(3) #初始迭代点
print(sumt(f, x1, h, g))
借助代码内的注释信息,不难理解本程序。第15行调用sumt函数,计算问题最优解近似值并输出。运行程序,输出
fun: -1.0000094540269446
nit: 8
x: array([-6.39954354e-06, 1.00000305e+00, 6.29523189e-06])
意味着经过8次迭代,算得本问题的最优解为
x
0
=
(
0
1
0
)
\boldsymbol{x}_0=\begin{pmatrix}0\\1\\0\end{pmatrix}
x0=
010
,最优解处函数值为
f
(
x
0
)
=
−
1
f(\boldsymbol{x}_0)=-1
f(x0)=−1。
例2:用sumt函数求解二次规划
{
minimize
x
1
2
+
x
1
x
2
+
2
x
2
2
+
x
3
2
−
6
x
1
−
2
x
2
−
12
x
3
s.t.
x
1
+
x
2
+
x
3
−
2
=
0
x
1
−
2
x
2
+
3
≥
0
x
1
,
x
2
,
x
3
≥
0
,
\begin{cases} \text{minimize}\quad x_1^2+x_1x_2+2x_2^2+x_3^2-6x_1-2x_2-12x_3\\ \text{s.t.\ \ }\quad\quad\quad x_1+x_2+x_3-2=0\\ \quad\quad\quad\quad\quad x_1-2x_2+3\geq0\\ \quad\quad\quad\quad\quad x_1,x_2,x_3\geq0 \end{cases},
⎩
⎨
⎧minimizex12+x1x2+2x22+x32−6x1−2x2−12x3s.t. x1+x2+x3−2=0x1−2x2+3≥0x1,x2,x3≥0,
给定初始可行解
x
1
=
(
1
1
0
)
\boldsymbol{x}_1=\begin{pmatrix}1\\1\\0\end{pmatrix}
x1=
110
。
解:本二次规划的数据矩阵为
H
=
(
2
1
0
1
4
0
0
0
2
)
,
c
=
(
−
6
−
2
−
12
)
A
e
q
=
(
1
1
1
)
,
b
e
q
=
(
2
)
A
i
q
=
(
1
−
2
0
1
0
0
0
1
0
0
0
1
)
,
b
i
q
=
(
−
3
0
0
0
)
\begin{array}{l} \boldsymbol{H}=\begin{pmatrix}2&1&0\\1&4&0\\0&0&2\end{pmatrix},\boldsymbol{c}=\begin{pmatrix}-6\\-2\\-12\end{pmatrix}\\ \boldsymbol{A}_{eq}=\begin{pmatrix}1&1&1\end{pmatrix},\boldsymbol{b}_{eq}=(2)\\ \boldsymbol{A}_{iq}=\begin{pmatrix}1&-2&0\\1&0&0\\0&1&0\\0&0&1\end{pmatrix},\boldsymbol{b}_{iq}=\begin{pmatrix}-3\\0\\0\\0\end{pmatrix} \end{array}
H=
210140002
,c=
−6−2−12
Aeq=(111),beq=(2)Aiq=
1100−20100001
,biq=
−3000
下列代码完成计算。
import numpy as np #导入numpy
H = np.array([[2, 1, 0], #矩阵H
[1, 4, 0],
[0, 0, 2]])
c = np.array([-6, -2, -12]) #向量c
Ae = np.array([[1, 1, 1]]) #矩阵Aeq
be = np.array([2]) #向量beq
Ai = np.array([[-1, -2, 0], #矩阵Aiq
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
bi = np.array([-3, 0, 0, 0]) #向量biq
x1 = np.array([1, 1, 0]) #初始迭代点
f = lambda x: 0.5 * np.matmul(x, np.matmul(H, x)) + np.matmul(c, x) #目标函数
h = lambda x: np.matmul(Ae, x) - be #等式约束函数
g = lambda x: np.matmul(Ai, x) - bi #不等式约束函数
print(sumt(f, x1, h, g))
对照代码内的注释信息,不难理解程序。运行程序,输出
fun: -20.000011166902542
nit: 16
x: array([-2.22198421e-07, -6.51694981e-07, 2.00000173e+00])
这意味着经过16次迭代,算得本问题的最优解
x
0
=
(
0
0
2
)
\boldsymbol{x}_0=\begin{pmatrix}0\\0\\2\end{pmatrix}
x0=
002
,最优值
f
(
x
0
)
=
−
20
f(\boldsymbol{x}_0)=-20
f(x0)=−20。
例3:用sumt函数求解优化问题
{
minimize
x
1
2
+
x
2
2
−
16
x
1
−
10
x
2
s.t.
−
x
1
2
+
6
x
1
−
4
x
2
+
11
≥
0
x
1
x
2
−
3
x
2
−
e
x
1
−
3
+
1
≥
0
x
1
,
x
2
≥
0
,
\begin{cases} \text{minimize}\quad x_1^2+x_2^2-16x_1-10x_2\\ \text{s.t.\ \ }\quad\quad\quad -x_1^2+6x_1-4x_2+11\geq0\\ \quad\quad\quad\quad\quad x_1x_2-3x_2-e^{x_1-3}+1\geq0\\ \quad\quad\quad\quad\quad x_1,x_2\geq0 \end{cases},
⎩
⎨
⎧minimizex12+x22−16x1−10x2s.t. −x12+6x1−4x2+11≥0x1x2−3x2−ex1−3+1≥0x1,x2≥0,
给定初始迭代点
x
1
=
o
\boldsymbol{x}_1=\boldsymbol{o}
x1=o。
解:下列代码完成计算:
import numpy as np #导入numpy
f = lambda x: x[0] ** 2 + x[1] ** 2 - 16 * x[0] - 10 * x[1] #目标函数
g = lambda x: np.array([-x[0] ** 2 + 6 * x[0] - 4 * x[1] + 11, #不等式约束函数
x[0] * x[1] - 3 * x[1] - np.exp(x[0] - 3) + 1,
x[0],
x[1]])
x1 = np.zeros(2) #初始迭代点
print(sumt(f, x1, g = g))
借助代码内注释信息,不难理解本程序。需要注意,本问题只有不等式约束g,第8行调用sumt时应表示等式约束的参数h使用缺省值,在其后的不等式约束参数g须使用赋值形式传递。运行程序,输出
fun: -79.80782889081777
nit: 11
x: array([5.23961012, 3.74603874])
意味着经过11次迭代,算得线性规划问题最优解近似值
x
0
=
(
5.3296
3.7460
)
\boldsymbol{x}_0=\begin{pmatrix}5.3296\\3.7460\end{pmatrix}
x0=(5.32963.7460),最优值
f
(
x
0
)
≈
−
79.8078
f(\boldsymbol{x}_0)\approx-79.8078
f(x0)≈−79.8078。
写博不易,敬请支持:
如果阅读本文于您有所获,敬请点赞、评论、收藏,谢谢大家的支持!