有约束多变量寻优方法——内点罚函数法

本文讨论内点罚函数法

对于一个有不等式约束的优化问题:

\underset{x\in{R^n}}{min} f(x)

s.t. g_i(x)\geq 0,i=1,\cdots m

这个问题通俗来讲就是在满足g_i(x)\geq 0,i=1,\cdots m的条件下,寻找x使得f(x)最小。我们将满足这个条件的x形成的集合叫做f(x)的可行域,即

F=\lbrace x|g_i(x)\geq 0,i=1,\cdots m\rbrace


为了将它转化成无约束条件的优化问题,我们构造一个所谓的惩罚函数:

G(x,r)=f(x)+rB(x)

其中B(x)是连续函数,当点x从可行域内趋于可行域边界时,B(x)的值要趋于无穷大。根据这个条件,B(x)可以有两种形式:

B(x)=\frac {1} {\sum_{1}^{m}g_i(x)}

或者

B(x)=-\sum_{1}^{m}ln(g_i(x))


容易看出,若x在可行域内部,当r逐渐趋于0时,G(x)的最优解就趋于f(x)的最优解。

对于固定的r,由于B(x)的存在,我们在可行域内求G(x)的最小值这个问题,实际上和在全域内寻找G(x)的最小值是可以等同起来的,因为在计算过程中x一旦接近可行域的边界(函数值非常大了),我们求最小值的程序肯定会将x马上退回到内部,所以我们可以认为这是一个无约束问题(约束是自动形成的)。


由于迭代总是在可行域内进行,每一个中间结果都是一个可行解,因此中间的结果可作为近似解。

从上面的分析可以看到内点法的缺点,第一,内点法不能求解等式约束;第二,迭代的初值必须是可行域内部的点。所以我们必须在寻优之前,先找一个内点作为初值。

下面的过程可以找到一个内点作为初始值

假设我们有一个任意的x_0,代入到g_i(x)\geq 0,i=1,\cdots m中,可以有以下结果:

①所有条件均满足,则x_0就是内点;

②一部分满足,一部分不满足或者都不满足:

        令

T=\lbrace{i|g_i(x_0)\geq0,i=1,\cdots ,m}\rbrace

S=\lbrace{i|g_i(x_0)<0,i=1,\cdots ,m}\rbrace

        然后构造新的目标函数ft(x)=-\sum_{i\in S} g_i(x),约束条件为g_i(x)\geq0,i\in T,因为x_0就是新的可行域的内点,所以直接以x_0为初值用内点罚函数法求ft(x)的最小值,ft(x)的最小值点x_0^1g_i(x)不断向大于零的方向发展,如此循环直到S=\varnothing。此时的x_0^k就是原可行域的内点了。


 下面附上内点罚函数的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

 下面是求解的结果(只画出了在可行域内部的目标函数的图像)

有约束多变量寻优方法——内点罚函数法_第1张图片

你可能感兴趣的:(优化方法,算法,matlab)