本文讨论内点罚函数法。
对于一个有不等式约束的优化问题:
这个问题通俗来讲就是在满足的条件下,寻找
使得
最小。我们将满足这个条件的
形成的集合叫做
的可行域,即
为了将它转化成无约束条件的优化问题,我们构造一个所谓的惩罚函数:
其中是连续函数,当点x从可行域内趋于可行域边界时,
的值要趋于无穷大。根据这个条件,
可以有两种形式:
或者
容易看出,若在可行域内部,当
逐渐趋于0时,
的最优解就趋于
的最优解。
对于固定的,由于
的存在,我们在可行域内求
的最小值这个问题,实际上和在全域内寻找
的最小值是可以等同起来的,因为在计算过程中
一旦接近可行域的边界(函数值非常大了),我们求最小值的程序肯定会将
马上退回到内部,所以我们可以认为这是一个无约束问题(约束是自动形成的)。
由于迭代总是在可行域内进行,每一个中间结果都是一个可行解,因此中间的结果可作为近似解。
从上面的分析可以看到内点法的缺点,第一,内点法不能求解等式约束;第二,迭代的初值必须是可行域内部的点。所以我们必须在寻优之前,先找一个内点作为初值。
下面的过程可以找到一个内点作为初始值
假设我们有一个任意的,代入到
中,可以有以下结果:
①所有条件均满足,则就是内点;
②一部分满足,一部分不满足或者都不满足:
令
然后构造新的目标函数,约束条件为
,因为
就是新的可行域的内点,所以直接以
为初值用内点罚函数法求
的最小值,
的最小值点
让
不断向大于零的方向发展,如此循环直到
。此时的
就是原可行域的内点了。
下面附上内点罚函数的matlab代码:
% 需要求解的目标函数f(x)
function [y] = func(x)
y=x(1)+x(2);
end
% 约束函数(需是大于等于0形式)
function [G] = conf(x)
g1=-x(1).^2+x(2);
g2=x(1);
G=[g1;g2];
end
% 内点法求解函数
function[X,fX,k]=InteriorPFM(fun,conf,X0,r,tol,Klimit,nonconf)
% IPFM(Interior penalty function method)
% 适用范围
% 约束条件是不等式
% 需要寻找内点作为初始点
% 输入参数
% fun:目标函数
% con: 约束条件(列向量形式,都是大于等于号)
% 例如:
% con(X)=[-x1+x2;x1^2+x2] 表示约束条件是
% -x1+x2>=0;
% x1^2+x2>=0
% X0: 任意取值(编程实现初始值的选取)
% r: 障碍因子(r>0)
% tol: 允许误差
% Klimit:最大迭代次数
% nonconf: 无约束多变量求解方法(降维法、梯度法、模式法等,可以用matlab内置函数fminbnd)
% 输出参数
% X: 最优点
% fx: 目标函数的最小值
% k: 迭代次数
k=0;
rt=r; % 求解初始值使用的障碍因子
G=conf(X0); % 约束方程的值
% 找到G中值>0的下标,此为内点下标集合
% 其他的就是非内点集合
T=find(G>0); % 内点下标
S=find(G<=0); % 非内点下标
% 判断S是否为空(isempty(S)=1或者size(S)=0),如果为空,说明X0就是内点
% 把下标为非内点下标的约束函数的相反数作为“目标函数”
% 把下标为内点下标的约束函数作为“约束函数”
function N_G=t_noconf(X)
Gt=conf(X);
N_G=-sum(Gt(S))-rt*sum(log(Gt(T)));
end
while isempty(S)~=1
f=@t_noconf;
% f函数可以看做是全局搜索最小值,因为它的形式保证了在边界处很大
X1=nonconf(f,X0);
X0=X1;
G=conf(X0); % 约束方程的值
T=find(G>0); % 内点下标
S=find(G<=0); % 非内点下标
rt=rt*0.1;
end
% 此时X0是内点可以作为初始值
function N_G=new_noconf(X)
Gt=conf(X);
Gt(Gt<0)=0;
N_G=fun(X)-r*sum(log(Gt));
end
f=@new_noconf;
X1=nonconf(f,X0);
while abs(norm(X1-X0))>tol %迭代终止条件
X0=X1;
r=r*0.1;
k=k+1;
disp(['迭代次数',num2str(k)])
f=@new_noconf;
X1=nonconf(f,X0);
if k>Klimit
break;
end
end
X=X1;
fX=fun(X);
end
下面是求解的结果(只画出了在可行域内部的目标函数的图像)