在我们讨论完无约束最优化问题后,我们接着讨论约束最优化问题。在无约束最优化问题中,我们默认了可行域为 R n R^n Rn,然而在约束最优化问题中,我们需要为可行域做出一些限制,因此衍生出了一些与无约束最优化问题不同的、独有的性质。
一般约束最优化问题的表达为:
{ m i n f ( x ) g i ( x ) ≥ 0 , i ∈ I = { 1 , 2 , . . . , m 1 } h i ( x ) = 0 , j ∈ E = { m 1 + 1 , . . . , m } \begin{cases}minf(x)\\g_i(x)\geq0,i\in I=\{1,2,...,m_1\}\\h_i(x)=0,j\in E=\{m_1+1,...,m\}\end{cases} ⎩⎪⎨⎪⎧minf(x)gi(x)≥0,i∈I={ 1,2,...,m1}hi(x)=0,j∈E={ m1+1,...,m}
其中 g ( x ) g(x) g(x)被称为不等式约束,而 h ( x ) h(x) h(x)被称为等式约束。这些约束限定了 f ( x ) f(x) f(x)的可行域为 D = { x ∣ g i ( x ) ≥ 0 , i ∈ I ; h j ( x ) = 0 , j ∈ E } D=\{x|g_i(x)\geq0,i\in I;h_j(x)=0,j\in E\} D={ x∣gi(x)≥0,i∈I;hj(x)=0,j∈E}
解决约束最优化问题的方法主要有罚函数法和拉格朗日乘子法。其中罚函数法较为简单,基本思想是将约束最优化问题转化为无约束最优化问题再用为无约束最优化问题的方法求解。
约束最优化问题比起理想模型,更多的是在实际生活中尤其是经济学领域的应用模型。比如,在每种原料有限的情况下,如果每种材料需要满足一定配比,如何规划生产可以使得开销最小。因此,约束最优化方法也被称为运筹学。
下面提出一个约束最优化问题实例:
在接下来提出的方法中,我们将测试方法对以上实例的求解效果。
对可行域外的点(即违反约束的点)施加惩罚,内部的点不惩罚,从而使迭代点向可行域D逼近。
如构造函数 F ( x ) = { f ( x ) x ∈ D + ∞ x ∉ D F(x)=\begin{cases}f(x)\quad x\in D\\+∞\quad x\notin D\end{cases} F(x)={ f(x)x∈D+∞x∈/D,但这只是理想的情况,而且无法用无约束问题的方法求解。
构造辅助函数 F μ ( x ) = f ( x ) + μ S ( x ) F_\mu(x)=f(x)+\mu S(x) Fμ(x)=f(x)+μS(x), μ \mu μ为罚参数或罚因子, S ( x ) S(x) S(x)的值的大小反映x偏离可行域D的程度。
对于约束 g i ( x ) ≥ 0 , i ∈ I g_i(x)\geq 0,i\in I gi(x)≥0,i∈I, h i ( x ) = h j ( x ) , j ∈ E h_i(x)=h_j(x),j\in E hi(x)=hj(x),j∈E,有 g i ( − ) ( x ) = m i n { g i ( x ) , 0 } , i ∈ I g_i^{(-)}(x)=min\{g_i(x),0\},i\in I gi(−)(x)=min{ gi(x),0},i∈I, h j ( − ) = h j ( x ) , j ∈ E h_j^{(-)}=h_j(x),j\in E hj(−)=hj(x),j∈E,则 S ( x ) = ∑ i ∈ I [ g i ( − ) ( x ) ] 2 + ∑ j ∈ E [ h j ( − ) ( x ) ] 2 S(x)=\displaystyle\sum_{i\in I}[g_i^{(-)}(x)]^2+\sum_{j\in E}[h_j^{(-)}(x)]^2 S(x)=i∈I∑[gi(−)(x)]2+j∈E∑[hj(−)(x)]2
随着 μ \mu μ不断变大,可行域外的函数值越往可行域边界折叠,像是形成了一堵墙壁,阻止向外迭代。若最优点不在可行域内,最优点也越靠近边界。
步骤:
对于本节中提出的约束最优化问题, x 1 , x 2 , x 3 x_1,x_2,x_3 x1,x2,x3的初值均在 [ 0 , 4 ] [0,4] [0,4]的范围内随机生成,总共生成100组起点。统计迭代成功(在1000步内得到最优解且单次步长搜索迭代次数不超过1000次)的样本的平均迭代步数、平均迭代时间和得到的最优解及开销函数最小值。
迭代步数 | 迭代时间 | 最优解 | 函数最小值 |
---|---|---|---|
1 | 1.95s | x 1 = 1.1048 x 2 = 1.1965 x 3 = 1.5349 x_1=1.1048~x_2=1.1965~x_3=1.5349 x1=1.1048 x2=1.1965 x3=1.5349 | 0.03255 0.03255 0.03255 |
使用共轭梯度PRP+法的外点罚函数法
import numpy as np
from Function import Function #定义法求导工具
from lagb import * #线性代数工具库
from scipy import linalg
n=3 #x的长度
mu=2 #μ的初值
def func(x):
return #函数
def hj(x):
#构造数组h,第j位是第j+1个等式限制条件计算的值
return h
def gi(x):
#构造数组g,第i位是第i+1个等式限制条件计算的值
return g
def S(x):
h=hj(x)
g=gi(x)
return np.sum(np.power(h,2))+np.sum(np.power(np.where(g<0,g,0),2))
def myFunc(x):
return func(x)+S(x)*mu*0.5
sigma2=1.5 #放大因子
e2=0.001
x=np.array([2.0,2.0,2.0]) #初值点
k1=0
while mu*S(x)>=e2:
e=0.001
beta1=1
sigma=0.4
rho=0.55
tar=Function(myFunc)
k=0
d=-tar.grad(x)
while tar.norm(x)>e:
a=1
if not (tar.value(x+a*d)<=tar.value(x)+rho*a*dot(turn(tar.grad(x)),d) and \
np.abs(dot(turn(tar.grad(x+a*d)),d))>=sigma*dot(turn(tar.grad(x)),d)):
a=beta1
while tar.value(x+a*d)>tar.value(x)+rho*a*dot(turn(tar.grad(x)),d):
a*=rho
while np.abs(dot(turn(tar.grad(x+a*d)),d))<sigma*dot(turn(tar.grad(x)),d):
a1=a/rho
da=a1-a
while tar.value(x+(a+da)*d)>tar.value(x)+rho*(a+da)*dot(turn(tar.grad(x)),d):
da*=rho
a+=da
lx=x
x=x+a*d
beta=np.max((dot(turn(tar.grad(x)),tar.grad(x)-tar.grad(lx))/(tar.norm(lx)**2),0)) #PRP+
d=-tar.grad(x)+beta*d
k+=1
print(k1,k)
mu*=sigma2
k1+=1
print(x)