先考虑仅含不等式约束的二次规划
{
minimize
1
2
x
⊤
H
x
+
c
⊤
x
s.t.
A
x
≥
b
.
(
1
)
\begin{cases} \text{minimize}\quad \frac{1}{2}\boldsymbol{x}^\top\boldsymbol{Hx}+\boldsymbol{c}^\top\boldsymbol{x}\\ \text{s.t.\ \ }\quad\quad\quad\boldsymbol{Ax}\geq\boldsymbol{b} \end{cases}.\quad\quad{(1)}
{minimize21x⊤Hx+c⊤xs.t. Ax≥b.(1)
其中,
H
∈
R
n
×
n
\boldsymbol{H}\in\text{R}^{n\times n}
H∈Rn×n对称正定,
A
=
(
a
1
a
2
⋮
a
m
)
∈
R
m
×
n
\boldsymbol{A}=\begin{pmatrix}\boldsymbol{a}_1\\\boldsymbol{a}_2\\\vdots\\\boldsymbol{a}_m\end{pmatrix}\in\text{R}^{m\times n}
A=
a1a2⋮am
∈Rm×n且rank
A
=
m
\boldsymbol{A}=m
A=m,可行域
Ω
=
{
x
∣
A
x
=
b
}
\Omega=\{\boldsymbol{x}|\boldsymbol{Ax}=\boldsymbol{b}\}
Ω={x∣Ax=b}。
解决问题(1)的方法是每次迭代利用有效集将其转换为求解仅含等式约束的二次型问题。具体而言,对当前可行迭代点
x
k
\boldsymbol{x}_k
xk,设在
x
k
\boldsymbol{x}_k
xk处有效集为
I
k
I_k
Ik,即
I
k
=
{
i
∣
1
≤
i
≤
m
,
a
i
x
k
=
b
i
}
.
I_k=\{i|1\leq i\leq m,\boldsymbol{a}_i\boldsymbol{x}_k=b_i\}.
Ik={i∣1≤i≤m,aixk=bi}.
记
f
(
x
)
=
1
2
x
⊤
H
x
+
c
⊤
x
f(\boldsymbol{x})=\frac{1}{2}\boldsymbol{x}^\top\boldsymbol{Hx}+\boldsymbol{c}^\top\boldsymbol{x}
f(x)=21x⊤Hx+c⊤x,
A
k
=
(
a
i
)
i
∈
I
k
\boldsymbol{A}_k=(\boldsymbol{a}_i)_{i\in I_k}
Ak=(ai)i∈Ik,
b
k
=
(
b
i
)
i
∈
I
k
\boldsymbol{b}_k=(b_i)_{i\in I_k}
bk=(bi)i∈Ik。考虑等式约束二次规划
{
minimize
f
(
x
)
s.t.
A
k
x
=
b
k
.
(
2
)
\begin{cases} \text{minimize}\quad f(\boldsymbol{x})\\ \text{s.t.\ \ }\quad\boldsymbol{A}_k\boldsymbol{x}=\boldsymbol{b}_k \end{cases}.\quad\quad{(2)}
{minimizef(x)s.t. Akx=bk.(2)
称为二次规划(1)的子问题。若设
x
=
x
k
+
d
\boldsymbol{x}=\boldsymbol{x}_k+\boldsymbol{d}
x=xk+d,即
d
=
x
−
x
k
\boldsymbol{d}=\boldsymbol{x}-\boldsymbol{x}_k
d=x−xk。于是
f
(
x
)
=
f
(
x
k
+
d
)
=
1
2
(
x
k
+
d
)
⊤
H
(
x
k
+
d
)
+
c
⊤
(
x
k
+
d
)
=
1
2
d
⊤
H
d
+
x
k
⊤
H
d
+
c
⊤
d
+
1
2
x
k
⊤
H
x
k
+
c
⊤
x
k
=
1
2
d
⊤
H
d
+
d
⊤
∇
f
(
x
k
)
+
f
(
x
k
)
.
\begin{align*} f(\boldsymbol{x})&=f(\boldsymbol{x}_k+\boldsymbol{d})=\frac{1}{2}(\boldsymbol{x}_k+\boldsymbol{d})^\top\boldsymbol{H}(\boldsymbol{x}_k+\boldsymbol{d})+\boldsymbol{c}^\top(\boldsymbol{x}_k+\boldsymbol{d})\\ &=\frac{1}{2}\boldsymbol{d}^\top\boldsymbol{Hd}+\boldsymbol{x}_k^\top\boldsymbol{Hd}+\boldsymbol{c}^\top\boldsymbol{d}+\frac{1}{2}\boldsymbol{x}_k^\top\boldsymbol{Hx}_k+\boldsymbol{c}^\top\boldsymbol{x}_k\\ &=\frac{1}{2}\boldsymbol{d}^\top\boldsymbol{Hd}+\boldsymbol{d}^\top\nabla f(\boldsymbol{x}_k)+f(\boldsymbol{x}_k). \end{align*}
f(x)=f(xk+d)=21(xk+d)⊤H(xk+d)+c⊤(xk+d)=21d⊤Hd+xk⊤Hd+c⊤d+21xk⊤Hxk+c⊤xk=21d⊤Hd+d⊤∇f(xk)+f(xk).
所以,求子问题(2)等价与求解
{
minimize
1
2
d
⊤
H
d
+
∇
f
(
x
k
)
⊤
d
s.t.
A
k
d
=
o
.
(
3
)
\begin{cases} \text{minimize}\quad\frac{1}{2}\boldsymbol{d}^\top\boldsymbol{Hd}+\nabla f(\boldsymbol{x}_k)^\top\boldsymbol{d}\\ \text{s.t.\ \ }\quad\quad\quad\boldsymbol{A}_k\boldsymbol{d}=\boldsymbol{o} \end{cases}.\quad\quad{(3)}
{minimize21d⊤Hd+∇f(xk)⊤ds.t. Akd=o.(3)
由
H
\boldsymbol{H}
H的正定性及
A
k
\boldsymbol{A}_k
Ak行满秩,可用等式约束二次规划的拉格朗日算法(见博文《最优化方法Python计算:二次规划的拉格朗日算法》)求解问题(3),设最优解
d
∗
=
arg
min
A
k
d
=
o
(
1
2
d
⊤
H
d
+
∇
f
(
x
k
)
⊤
d
)
\boldsymbol{d}^{*}=\arg\min_{\boldsymbol{A}_k\boldsymbol{d}=\boldsymbol{o}}\left(\frac{1}{2}\boldsymbol{d}^\top\boldsymbol{Hd}+\nabla f(\boldsymbol{x}_k)^\top\boldsymbol{d}\right)
d∗=argAkd=omin(21d⊤Hd+∇f(xk)⊤d)
对应的乘子为
λ
∗
\boldsymbol{\lambda}^{*}
λ∗。
(I)若
d
∗
=
o
\boldsymbol{d}^{*}=\boldsymbol{o}
d∗=o,则
x
k
\boldsymbol{x}_k
xk是子问题(2)的最优解。此时需判断
x
k
\boldsymbol{x}_k
xk是否为原问题(1)的最优解,这可通过检验对应的拉格朗日因子
λ
∗
\boldsymbol{\lambda}^{*}
λ∗是否满足
λ
∗
≥
o
\boldsymbol{\lambda}^{*}\geq\boldsymbol{o}
λ∗≥o
来完成。若上式成立,则
(
x
k
λ
∗
)
\begin{pmatrix}\boldsymbol{x}_k\\\boldsymbol{\lambda}^{*}\end{pmatrix}
(xkλ∗)为原问题(1)的KKT点。由于
H
\boldsymbol{H}
H是正定的,故
x
k
\boldsymbol{x}_k
xk即为原问题(1)的最优解。否则,计算,
j
=
arg
min
i
∈
I
k
{
λ
i
∗
}
,
j=\arg\min_{i\in I_k}\{\lambda^{*}_i\},
j=argi∈Ikmin{λi∗},
剔除有效约束
a
j
x
=
a
j
(
x
k
+
d
)
=
b
j
\boldsymbol{a}_j\boldsymbol{x}=\boldsymbol{a}_j(\boldsymbol{x}_k+\boldsymbol{d})=b_j
ajx=aj(xk+d)=bj,即使得
{
a
j
d
>
0
a
i
d
=
0
i
∈
I
k
,
i
≠
j
.
(
∗
)
\begin{cases} \boldsymbol{a}_j\boldsymbol{d}>0\\ \boldsymbol{a}_i\boldsymbol{d}=0&i\in I_k,i\not=j \end{cases}.\quad\quad{(*)}
{ajd>0aid=0i∈Ik,i=j.(∗)
由于
x
k
\boldsymbol{x}_k
xk为子问题(2)的最优解,故
o
=
∇
x
L
(
x
k
,
λ
∗
)
=
∇
f
(
x
k
)
−
A
k
⊤
λ
∗
\boldsymbol{o}=\nabla_{\boldsymbol{x}}L(\boldsymbol{x}_k,\boldsymbol{\lambda}^{*})=\nabla f(\boldsymbol{x}_k)-\boldsymbol{A}_k^\top\boldsymbol{\lambda}^{*}
o=∇xL(xk,λ∗)=∇f(xk)−Ak⊤λ∗
其中,
L
(
x
,
λ
)
=
f
(
x
)
−
(
A
k
x
−
b
k
)
⊤
λ
L(\boldsymbol{x},\boldsymbol{\lambda})=f(\boldsymbol{x})-(\boldsymbol{A}_k\boldsymbol{x}-\boldsymbol{b}_k)^\top\boldsymbol{\lambda}
L(x,λ)=f(x)−(Akx−bk)⊤λ为子问题(2)的拉格朗日函数。即
∇
f
(
x
k
)
=
A
k
⊤
λ
∗
\nabla f(\boldsymbol{x}_k)=\boldsymbol{A}_k^\top\boldsymbol{\lambda}^{*}
∇f(xk)=Ak⊤λ∗
对满足式
(
∗
)
(*)
(∗)的向量
d
\boldsymbol{d}
d,
∇
f
(
x
k
)
⊤
d
=
λ
∗
⊤
A
k
d
=
λ
j
a
j
d
<
0.
\nabla f(\boldsymbol{x}_k)^\top\boldsymbol{d}=\boldsymbol{\lambda}^{*\top}\boldsymbol{A}_k\boldsymbol{d}=\lambda_j\boldsymbol{a}_j\boldsymbol{d}<0.
∇f(xk)⊤d=λ∗⊤Akd=λjajd<0.
即
d
\boldsymbol{d}
d是问题(3)的可行下降方向。于是修改有效集下标集
I
k
=
I
k
−
{
j
}
,
I_k=I_k-\{j\},
Ik=Ik−{j},
重新求解子问题(2),即可得到原问题(1)下降可行方向
d
∗
\boldsymbol{d}^{*}
d∗。
若
d
∗
≠
o
\boldsymbol{d}^{*}\not=\boldsymbol{o}
d∗=o,取搜索方向
d
k
=
d
∗
\boldsymbol{d}_k=\boldsymbol{d}^{*}
dk=d∗。
(II)此时,若
x
k
+
d
k
\boldsymbol{x}_k+\boldsymbol{d}_k
xk+dk是原问题(7.4)的可行解,即
x
k
+
d
k
∈
Ω
\boldsymbol{x}_k+\boldsymbol{d}_k\in\Omega
xk+dk∈Ω,则取
x
k
+
1
=
x
k
+
d
k
\boldsymbol{x}_{k+1}=\boldsymbol{x}_k+\boldsymbol{d}_k
xk+1=xk+dk
作为下一个迭代点。
(III)若
x
k
+
d
k
∉
Ω
\boldsymbol{x}_k+\boldsymbol{d}_k\not\in\Omega
xk+dk∈Ω,寻求搜索步长
α
k
\alpha_k
αk,使得
x
k
+
α
k
d
k
∈
Ω
\boldsymbol{x}_k+\alpha_k\boldsymbol{d}_k\in\Omega
xk+αkdk∈Ω,作为下一个迭代点。为此,需
a
i
(
x
k
+
α
k
d
k
)
≥
b
i
,
i
∈
I
k
‾
.
(
∗
∗
)
\boldsymbol{a}_i(\boldsymbol{x}_k+\alpha_k\boldsymbol{d}_k)\geq b_i,\quad i\in \overline{I_k}.\quad\quad{(**)}
ai(xk+αkdk)≥bi,i∈Ik.(∗∗)
其中
I
k
‾
=
{
1
,
2
,
⋯
,
m
}
−
I
k
\overline{I_k}=\{1,2,\cdots,m\}-I_k
Ik={1,2,⋯,m}−Ik。由于
x
k
∈
Ω
\boldsymbol{x}_k\in\Omega
xk∈Ω,故
A
x
k
≥
b
k
\boldsymbol{Ax}_k\geq\boldsymbol{b}_k
Axk≥bk。因此,若
a
i
d
k
≥
0
\boldsymbol{a}_i\boldsymbol{d}_k\geq0
aidk≥0,则对任意
α
k
>
0
\alpha_k>0
αk>0,式
(
∗
∗
)
(**)
(∗∗)均成立。往设存在
i
∈
I
k
‾
i\in \overline{I_k}
i∈Ik,使得
a
i
d
k
<
0
\boldsymbol{a}_i\boldsymbol{d}_k<0
aidk<0。这时,取
0
<
α
k
≤
b
i
−
a
i
x
k
a
i
d
k
0<\alpha_k\leq\frac{b_i-\boldsymbol{a}_i\boldsymbol{x}_k}{\boldsymbol{a}_i\boldsymbol{d}_k}
0<αk≤aidkbi−aixk
则必有
a
i
(
x
k
+
α
k
d
k
)
≥
b
i
\boldsymbol{a}_i(\boldsymbol{x}_k+\alpha_k\boldsymbol{d}_k)\geq b_i
ai(xk+αkdk)≥bi。于是,令
α
^
k
=
min
(
b
i
−
a
i
x
k
a
i
d
k
∣
i
∈
I
k
‾
,
a
i
d
k
<
0
)
\hat{\alpha}_k=\min\left(\frac{b_i-\boldsymbol{a}_i\boldsymbol{x}_k}{\boldsymbol{a}_i\boldsymbol{d}_k}\Big|i\in\overline{I_k},\boldsymbol{a}_i\boldsymbol{d}_k<0\right)
α^k=min(aidkbi−aixk
i∈Ik,aidk<0)
则可保证式
a
i
(
x
k
+
α
^
k
d
k
)
≥
b
i
,
i
∈
I
k
‾
\boldsymbol{a}_i(\boldsymbol{x}_k+\hat{\alpha}_k\boldsymbol{d}_k)\geq b_i,\quad i\in \overline{I_k}
ai(xk+α^kdk)≥bi,i∈Ik
成立。综合(II)和(III),令
α
k
=
min
{
1
,
α
^
k
}
\alpha_k=\min\{1,\hat{\alpha}_k\}
αk=min{1,α^k}
则当
d
k
=
d
∗
≠
o
\boldsymbol{d}_k=\boldsymbol{d}^{*}\not=\boldsymbol{o}
dk=d∗=o时
x
k
+
1
=
x
k
+
α
k
d
k
∈
Ω
\boldsymbol{x}_{k+1}=\boldsymbol{x}_k+\alpha_k\boldsymbol{d}_k\in\Omega
xk+1=xk+αkdk∈Ω
可作为下一个迭代点。此时,需更新
x
k
+
1
\boldsymbol{x}_{k+1}
xk+1的有效集
I
k
+
1
=
{
i
∣
1
≤
i
≤
m
,
a
i
x
k
+
1
=
b
i
}
.
I_{k+1}=\{i|1\leq i\leq m,\boldsymbol{a}_i\boldsymbol{x}_{k+1}=b_i\}.
Ik+1={i∣1≤i≤m,aixk+1=bi}.
对既有等式约束亦有不等式约束的二次规划
{
minimize
1
2
x
⊤
H
x
+
c
⊤
x
s.t.
A
e
q
x
−
b
e
q
=
o
A
i
q
x
−
b
i
q
≥
o
(
4
)
\begin{cases} \text{minimize}\quad \frac{1}{2}\boldsymbol{x}^\top\boldsymbol{Hx}+\boldsymbol{c}^\top\boldsymbol{x}\\ \text{s.t.\ \ }\quad\quad\quad\boldsymbol{A}_{eq}\boldsymbol{x}-\boldsymbol{b}_{eq}=\boldsymbol{o}\\ \quad\quad\quad\quad\quad\boldsymbol{A}_{iq}\boldsymbol{x}-\boldsymbol{b}_{iq}\geq\boldsymbol{o} \end{cases}\quad\quad{(4)}
⎩
⎨
⎧minimize21x⊤Hx+c⊤xs.t. Aeqx−beq=oAiqx−biq≥o(4)
其中,
H
\boldsymbol{H}
H对称正定,
A
e
q
∈
R
l
×
n
\boldsymbol{A}_{eq}\in\text{R}^{l\times n}
Aeq∈Rl×n,
A
i
q
∈
R
m
×
n
\boldsymbol{A}_{iq}\in\text{R}^{m\times n}
Aiq∈Rm×n,且rank
(
A
e
q
A
i
q
)
=
l
+
m
\begin{pmatrix}\boldsymbol{A}_{eq}\\\boldsymbol{A}_{iq}\end{pmatrix}=l+m
(AeqAiq)=l+m。令
A
=
(
A
e
q
A
i
q
)
=
(
a
1
⋮
a
l
a
l
+
1
⋮
a
l
+
m
)
\boldsymbol{A}=\begin{pmatrix}\boldsymbol{A}_{eq}\\\boldsymbol{A}_{iq}\end{pmatrix}=\begin{pmatrix}\boldsymbol{a}_1\\\vdots\\\boldsymbol{a}_l\\\boldsymbol{a}_{l+1}\\\vdots\\\boldsymbol{a}_{l+m}\end{pmatrix}
A=(AeqAiq)=
a1⋮alal+1⋮al+m
,
b
=
(
b
e
q
b
i
q
)
=
(
b
1
⋮
b
l
b
l
+
1
⋮
b
l
+
m
)
\boldsymbol{b}=\begin{pmatrix}\boldsymbol{b}_{eq}\\\boldsymbol{b}_{iq}\end{pmatrix}=\begin{pmatrix}b_1\\\vdots\\b_l\\b_{l+1}\\\vdots\\b_{l+m}\end{pmatrix}
b=(beqbiq)=
b1⋮blbl+1⋮bl+m
。记
E
=
{
1
,
⋯
,
l
}
E=\{1,\cdots,l\}
E={1,⋯,l},
I
=
{
l
+
1
,
⋯
,
l
+
m
}
I=\{l+1,\cdots,l+m\}
I={l+1,⋯,l+m},对任一
x
∈
Ω
=
{
x
∣
A
e
q
x
=
b
e
q
,
A
i
q
x
≥
b
i
q
}
\boldsymbol{x}\in\Omega=\{\boldsymbol{x}|\boldsymbol{A}_{eq}\boldsymbol{x}=\boldsymbol{b}_{eq},\boldsymbol{A}_{iq}\boldsymbol{x}\geq\boldsymbol{b}_{iq}\}
x∈Ω={x∣Aeqx=beq,Aiqx≥biq},
I
(
x
)
=
{
i
∣
i
∈
I
,
a
i
x
=
0
}
I(\boldsymbol{x})=\{i|i\in I,\boldsymbol{a}_i\boldsymbol{x}=0\}
I(x)={i∣i∈I,aix=0}为
x
\boldsymbol{x}
x的有效集。
S
(
x
)
=
E
∪
I
(
x
)
S(\boldsymbol{x})=E\cup I(\boldsymbol{x})
S(x)=E∪I(x)为子问题(2)的约束下标集。即可用有效约束集方法求解问题(4)。下列代码实现求解一般二次规划(4)的有效集算法。
import numpy as np #导入numpy
from scipy.optimize import OptimizeResult #导入OptimizeResult
def qpact(H, c, x1, Aeq = None, beq = None, Aiq = None, biq = None):
l = 0 #等式约束个数
if isinstance(Aeq, np.ndarray):
A = Aeq.copy()
b = beq.copy()
l, n = Aeq.shape
m = 0 #不等式约数个数
if isinstance(Aiq, np.ndarray):
if isinstance(Aeq, np.ndarray):
A = np.vstack((A, Aiq))
b = np.concatenate((b, biq))
m = biq.size
else:
A = Aiq.copy()
b = biq.copy()
m, n = Aiq.shape
gk = lambda x: np.matmul(H, x) + c #目标函数梯度函数
E = np.arange(l) #等式约束下标集
I = np.arange(l, l + m) #不等式约束下标集
k = 0 #迭代数
xk = x1 #当前迭代点
b1 = np.zeros(l + m)
Ik = np.where(np.abs(np.matmul(A[l:,:],xk) - b[l:])<1e-10)[0] + l #有效集
Sk = np.concatenate((E, Ik)) #子问题约束
opt = False
while not opt:
dk, lamdk = qlag(H, A[Sk], b1[Sk], gk(xk)) #计算搜索方向
if np.linalg.norm(dk) > 1e-6: #搜索方向非零
Ikb = np.setdiff1d(I, Ik) #非有效集
neg = np.where(np.matmul(A[Ikb], dk) < 0)[0]
arr = (b[Ikb[neg]] - np.matmul(A[Ikb[neg]], xk)) / np.matmul(A[Ikb[neg]], dk)
alpha1 = 1
if arr.size > 0:
alpha1 = np.min(arr)
alpha = min(1, alpha1) #搜索步长
xk = xk + alpha * dk
Ik = np.where(np.abs(np.matmul(A[l:,:], xk) - b[l:]) < 1e-10)[0] + l#重置有效集
Sk = np.concatenate((E, Ik)) #重置子问题约束
k += 1
else:
minlamd = 0.0
if lamdk.size > l:
minlamd = np.min(lamdk[l:])
if minlamd < 0: #乘子存在负值元素
j = np.argmin(lamdk[l:])
Ik = np.delete(Ik, j) #修改有效集
Sk = np.concatenate((E, Ik)) #更新子问题约束集
else: #乘子非负
opt = True
bestx = xk
besty = 0.5 * np.matmul(xk, np.matmul(H, xk)) + np.matmul(c, xk)
return OptimizeResult(fun = besty, x = bestx, nit = k)
程序的第3~54行定义的qpact函数实现求解二次规划问题(4)的有效集算法。该函数的参数H,c,Aeq,beq,Aiq,biq分别表示问题(1)
{
minimize
1
2
x
⊤
H
x
+
c
⊤
x
s.t.
A
e
q
x
−
b
e
q
=
o
A
i
q
x
−
b
i
q
≥
o
\begin{cases} \text{minimize}\quad \frac{1}{2}\boldsymbol{x}^\top\boldsymbol{Hx}+\boldsymbol{c}^\top\boldsymbol{x}\\ \text{s.t.\ \ }\quad\quad\quad\boldsymbol{A}_{eq}\boldsymbol{x}-\boldsymbol{b}_{eq}=\boldsymbol{o}\\ \quad\quad\quad\quad\quad\boldsymbol{A}_{iq}\boldsymbol{x}-\boldsymbol{b}_{iq}\geq\boldsymbol{o} \end{cases}
⎩
⎨
⎧minimize21x⊤Hx+c⊤xs.t. Aeqx−beq=oAiqx−biq≥o
中的
H
\boldsymbol{H}
H、
c
\boldsymbol{c}
c、
A
e
q
\boldsymbol{A}_{eq}
Aeq、
b
e
q
\boldsymbol{b}_{eq}
beq、
A
i
q
\boldsymbol{A}_{iq}
Aiq和
b
i
q
\boldsymbol{b}_{iq}
biq,x1表示问题的初始可行解
x
1
\boldsymbol{x}_1
x1。其中,Aeq,beq,Aiq和biq是命名参数,缺省值为无类型常量None。
函数体内,第4~{}18行将表示
A
e
q
\boldsymbol{A}_{eq}
Aeq和
A
i
q
\boldsymbol{A}_{iq}
Aiq的Aeq和Aiq叠加成
A
=
(
A
e
q
A
i
q
)
\boldsymbol{A}=\begin{pmatrix}\boldsymbol{A}_{eq}\\\boldsymbol{A}_{iq}\end{pmatrix}
A=(AeqAiq),赋予A。将表示
b
e
q
\boldsymbol{b}_{eq}
beq和
b
i
q
\boldsymbol{b}_{iq}
biq的beq和biq叠加成
b
=
(
b
e
q
b
i
q
)
\boldsymbol{b}=\begin{pmatrix}\boldsymbol{b}_{eq}\\\boldsymbol{b}_{iq}\end{pmatrix}
b=(beqbiq),赋予b。记录下等式约束个数l和不等式约束个数m。
第19行定义问题(4)的目标函数的梯度
∇
f
(
x
)
=
H
x
+
c
\nabla f(\boldsymbol{x})=\boldsymbol{Hx}+\boldsymbol{c}
∇f(x)=Hx+c赋予gk。第20、21行设置等式约束下标集E和不等式约束下标集I。第22~24初始化迭代次数k,迭代点xk,零向量b1。第25初始化xk处的有效集Ik,第26行初始化子问题的等式约束下标集Sk。
第28~51行的while循环,执行算法的迭代运算。其中,第29行调用博文《最优化方法Python计算:二次规划的拉格朗日算法》定义的拉格朗日算法函数qlag,求解
{
minimize
1
2
d
⊤
H
d
+
∇
f
(
x
k
)
⊤
d
s.t.
a
i
d
=
0
,
i
∈
I
k
,
\begin{cases} \text{minimize}\quad\frac{1}{2}\boldsymbol{d}^\top\boldsymbol{Hd}+\nabla f(\boldsymbol{x}_k)^\top\boldsymbol{d}\\ \text{s.t.\ \ }\quad\quad\quad\boldsymbol{a}_i\boldsymbol{d}=0,\quad i\in I_k \end{cases},
{minimize21d⊤Hd+∇f(xk)⊤ds.t. aid=0,i∈Ik,
以求搜索方向
d
k
\boldsymbol{d}_k
dk及其对应的拉格朗日乘子
λ
k
\boldsymbol{\lambda}_k
λk,赋予dk和lamdk。第30~41行处理当搜索方向
d
k
≠
o
\boldsymbol{d}_k\not=\boldsymbol{o}
dk=o时,按
α
k
=
min
{
1
,
α
^
k
}
\alpha_k=\min\{1,\hat{\alpha}_k\}
αk=min{1,α^k}
其中,
α
^
k
=
min
(
b
i
−
a
i
x
k
a
i
d
k
∣
i
∈
I
k
‾
,
a
i
d
k
<
0
)
\hat{\alpha}_k=\min\left(\frac{b_i-\boldsymbol{a}_i\boldsymbol{x}_k}{\boldsymbol{a}_i\boldsymbol{d}_k}\Big|i\in\overline{I_k},\boldsymbol{a}_i\boldsymbol{d}_k<0\right)
α^k=min(aidkbi−aixk
i∈Ik,aidk<0),计算搜索步长
α
k
\alpha_k
αk,赋予alpha。以xk+alpha*dk更新迭代点xk,并更新有效集Ik和子问题等式约束下标集Sk。第42~51行处理所得搜索方向
d
k
=
o
\boldsymbol{d}_k=\boldsymbol{o}
dk=o的情形。根据拉格朗日乘子
λ
k
\boldsymbol{\lambda}_k
λk是否存在负值元素,或更新有效集并进入下一轮迭代(第44~49行)或完成迭代置标志opt为True(第51行)。第52~54行返回最优解xk及最优目标近似值。
例1: 用qpact函数求二次规划
{
minimize
x
1
2
+
2
x
2
2
+
x
3
2
−
2
x
1
x
2
+
x
3
s.t.
x
1
+
x
2
+
x
3
=
4
2
x
1
−
x
2
+
x
3
=
2
,
\begin{cases} \text{minimize}\quad x_1^2+2x_2^2+x_3^2-2x_1x_2+x_3\\ \text{s.t.\ \ }\quad\quad\quad x_1+x_2+x_3=4\\ \quad\quad\quad\quad\quad 2x_1-x_2+x_3=2 \end{cases},
⎩
⎨
⎧minimizex12+2x22+x32−2x1x2+x3s.t. x1+x2+x3=42x1−x2+x3=2,
给定初始可行解
x
1
=
(
2
2
0
)
\boldsymbol{x}_1=\begin{pmatrix}2\\2\\0\end{pmatrix}
x1=
220
。
解:本题中,
H
=
(
2
−
2
0
−
2
4
0
0
0
2
)
,
A
e
q
=
(
1
1
1
2
−
1
1
)
,
b
e
q
=
(
4
2
)
,
c
=
(
0
0
1
)
\boldsymbol{H}=\begin{pmatrix}2&-2&0\\-2&4&0\\0&0&2\end{pmatrix},\boldsymbol{A}_{eq}=\begin{pmatrix}1&1&1\\2&-1&1\end{pmatrix},\boldsymbol{b}_{eq}=\begin{pmatrix}4\\2\end{pmatrix},\boldsymbol{c}=\begin{pmatrix}0\\0\\1\end{pmatrix}
H=
2−20−240002
,Aeq=(121−111),beq=(42),c=
001
下列代码完成计算。
import numpy as np #导入numpy
from fractions import Fraction as F #设置输出格式
np.set_printoptions(formatter={'all':lambda x:
str(F(x).limit_denominator())})
H = np.array([[2, -2, 0], #矩阵H
[-2, 4, 0],
[0, 0, 2]])
c = np.array([0, 0, 1]) #向量c
Ae = np.array([[1, 1, 1], #矩阵Aeq
[2, -1, 1]])
be = np.array([4, 2]) #向量beq
x = np.array([2, 2, 0]) #初始可行解
print(qpact(H, c, x, Ae, be))
借助代码内部注释信息,不难理解本程序。需要注意的是本问题只有等式约束,没有不等式约束。所以,第14行调用qpact函数时向形参Aeq和beq(位于形参Aiq和biq之前)直接传递实际参数Ae、be即可。参数Aiq和biq使用缺省值。运行程序,输出
fun: 3.977272727272721
nit: 1
x: array([21/11, 43/22, 3/22])
仅迭代1次即算得最优解
x
0
=
(
21
11
43
22
3
22
)
\boldsymbol{x}_0=\begin{pmatrix}\frac{21}{11}\\\frac{43}{22}\\\frac{3}{22}\end{pmatrix}
x0=
11212243223
。
例2:用qpact函数求解二次规划
{
minimize
x
1
2
−
x
1
x
2
+
2
x
2
2
−
x
1
−
10
x
2
s.t.
−
3
x
1
−
2
x
2
≥
−
6
x
1
,
x
2
≥
0
,
\begin{cases} \text{minimize}\quad x_1^2-x_1x_2+2x_2^2-x_1-10x_2\\ \text{s.t.\ \ }\quad\quad -3x_1-2x_2\geq-6\\ \quad\quad\quad\quad\quad x_1,x_2\geq0 \end{cases},
⎩
⎨
⎧minimizex12−x1x2+2x22−x1−10x2s.t. −3x1−2x2≥−6x1,x2≥0,
给定初始可行解
x
1
=
o
\boldsymbol{x}_1=\boldsymbol{o}
x1=o。
解:本题中
H
=
(
2
−
1
−
1
4
)
,
c
=
(
−
1
−
10
)
,
x
1
=
(
0
0
)
,
A
i
q
=
(
−
3
−
2
1
0
0
1
)
,
b
i
q
=
(
−
6
0
0
)
.
\boldsymbol{H}=\begin{pmatrix}2&-1\\-1&4\end{pmatrix},\boldsymbol{c}=\begin{pmatrix}-1\\-10\end{pmatrix},\boldsymbol{x}_1=\begin{pmatrix}0\\0\end{pmatrix},\boldsymbol{A}_{iq}=\begin{pmatrix}-3&-2\\1&0\\0&1\end{pmatrix},\boldsymbol{b}_{iq}=\begin{pmatrix}-6\\0\\0\end{pmatrix}.
H=(2−1−14),c=(−1−10),x1=(00),Aiq=
−310−201
,biq=
−600
.
下列代码利用这些数据完成本例计算。
import numpy as np #导入numpy
from utility import qpact #导入qpact
from fractions import Fraction as F #设置输出格式
np.set_printoptions(formatter={'all':lambda x:
str(F(x).limit_denominator())})
H = np.array([[2, -1], #矩阵H
[-1, 4]])
c = np.array([-1, -10]) #向量c
Ai = np.array([[-3, -2], #矩阵Ai
[1, 0],
[0, 1]])
bi = np.array([-6, 0, 0]) #向量bi
x = np.array([0, 0]) #初始可行解
print(qpact(H, c, x, Aiq=Ai, biq=bi))
注意本问题只有不等式约束,没有等式约束。所以,第13行调用qpact函数传递实际参数Ai、bi时,须用赋值形式将其传递给形式参数Aiq和biq(位于形参Aeq和beq之后)。参数Aeq和beq使用缺省值。运行程序,输出
fun: -13.75
nit: 3
x: array([1/2, 9/4])
这意味着,经过3此迭代,有效集算法算得本问题最优解
x
0
=
(
1
2
9
4
)
\boldsymbol{x}_0=\begin{pmatrix}\frac{1}{2}\\\frac{9}{4}\end{pmatrix}
x0=(2149),最优值
f
(
x
0
)
≈
−
13.75
f(\boldsymbol{x}_0)\approx-13.75
f(x0)≈−13.75。
例3:用qpact函数求解二次规划
{
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
。
{\heiti{解}}:本问题中的数据矩阵表示为
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
from utility import qpact #导入qpact
from fractions import Fraction as F #设置输出格式
np.set_printoptions(formatter={'all':lambda x:
str(F(x).limit_denominator())})
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向量
x = np.array([1, 1, 0]) #初始可行解
print(qpact(H, c, x, Ae, be, Ai, bi))
由于本问题既有等式约束,又有不等式约束,第17行调用qpact时,所有实际参数按形式参数的顺序传递即可。运行程序,输出
fun: -20.0
nit: 2
x: array([0, 0, 2])
即2次迭代,算得最优解为
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。
写博不易,敬请支持:
如果阅读本文于您有所获,敬请点赞、评论、收藏,谢谢大家的支持!