罰函數之乘子法


外罰函數主要用於對於等式約束問題的求解,內點法主要是對於不等式問題的求解,一般問題中包含等式約束以及不等式約束,故需要使用乘子法解決問題。

1、 乘子法概述

(1)等式約束乘子法描述:

min f(x) 

s.t. gi(x) =0

廣義乘子法是拉格朗日乘子法與罰函數法的結合,構造增廣函數:

φ (x,λ,σ)=f(x)+λTg(x)+1/2σgT(x)g(x)

在罰函數的基礎上增加了乘子項,首先在σ足夠大的基礎上,獲得ϕ的極小值,然后在調整λ獲得原問題的最優解。

(2)包含等式約束以及不等式約束問題描述:

min f(x) 

        s.t. hi(x) =0,i=1,...,l  

               gi(x)≥0,i=1,...m

其基本思想是:先引進輔助變量把不等式約束化為等式約束,然后利用最優性條件消去輔助變量,主要是通過構造增廣拉格朗日函數,進行外迭代與內迭代綜合,帶入乘子迭代公式,進而得出得出,故針對上述一般問題構造拉格朗日函數為:

 

4、其代碼實現為

function [x,mu,lambda,output]=multphr(fun,hf,gf,dfun,dhf,dgf,x0)

%功能:用乘子法解一般約束問題:min f(x),s.t. h(x)=0.g(x)>=0

%輸入:x0是初始點,fun,dfun分別是目標函數及其梯度;

%hf,dhf分別是等式約束(向量)函數及其jacobi矩陣的轉置;

%gf,dgf分別是不等式約束(向量)函數及其jacobi矩陣的轉置;

%輸出:x是近似最優點,mu,lambda分別是相應於等式約束和不等式

%     等式約束的乘子向量;output是結構變量,輸出近似極小值f,迭代次數,內迭代次數等

 

%%%%%%c初始化相關參數%%%%%%%%%%%

maxk=500;       %最大迭代次數

sigma=2.0;      %罰因子

eta=2.0;    theta=0.8;  %PHR算法中的實參數

k=0; ink=0;  %k,ink分別是外迭代和內迭代次數

epsilon=1e-5;%終止誤差值

x=x0;he=feval(hf,x);gi=feval(gf,x);%he=feval(hf,x)=hf(x)

n=length(x);l=length(he);m=length(gi);

%選取乘子向量的初始值

mu=0.1*ones(1,1);lambda=0.1*ones(m,1);%ones為生成m*n的全1矩陣

btak=10;    btaold=10;  %用來檢驗終止條件的兩個值

while (btak>epsilon & k<maxk)

    %%%%%%c先求解無約束問題%%%%%%%%%%%

    %調用BFGS算法程序求解無約束子問題

    [x,v,ik]=bfgs('mpsi','dmpsi',x0,fun,hf,gf,dfun,dhf,dgf,mu,lambda,sigma);%%其中x為最優點,val為最優值,ik為迭代次數

    ink=ink+ik;

    he=feval(hf,x);gi=feval(gf,x);

    %%%%%%%%%%計算btak%%%%%%%%%%%

    btak=0.0;

    for(i=1:l),btak=btak+he(i)^2;   end

    for(i=1:m)

        temp=min(gi(i),lambda(i)/sigma);

        btak=btak+temp^2;

    end

    btak=sqrt(btak);

    if btak>epsilon

        %%%%%%%%%%%更新罰參數%%%%%%%%%%%

        if(k>=2 & btak>theta*btaold)

            sigma=eta*sigma;

        end

        %%%%%%%%%%%更新乘子向量%%%%%%%%%%%%

        for(i=1:l),mu(i)=mu(i)-sigma*he(i);end

        for(i=1:m)

            %lambda(i)=max(0.0,lambda(i)-sigma*gi(i));

lambda(i)=max(0.0,lambda(i)-gi(i));

        end

    end

     %%%%%%%%%%%迭代%%%%%%%%%%%%

    k=k+1;

    btaold=btak;

    x0=x;

end

f=feval(fun,x);

output.fval=f;

output.iter=k;

output.inner_iter=ink;

output.bta=btak;

 

BFGS算法部分:

function [x,val,k]=bfgs(fun,gfun,x0,varargin)

%功能:用BFGS算法求解無約束問題:minf(x)

%輸入:x0是初始點,fun,gfun分別是目標函數及其梯度

%varargin是輸入的可變參數變量,簡單調用bfgs時可以忽略,其他程序調用則尤為重要

%輸出:x為最優點,val為最優值,k時迭代次數

maxk=500;%給出最大迭代次數

rho=0.55;sigma=0.4;epsilon=1e-5;

k=0;n=length(x0);

Bk=eye(n);%Bk=feval('Hess',x0)

while(k<maxk)

    gk=feval(gfun,x0,varargin{:});%計算梯度

    if(norm(gk)<epsilon),break;end%檢驗終止准則

    dk=-Bk\gk;%解方程組,計算搜索方向

    m=0;mk=0;

    while(m<20)%搜索求步長

        newf=feval(fun,x0+rho^m*dk,varargin{:});

        oldf=feval(fun,x0,varargin{:});

        if(newf<oldf+sigma*rho^m*gk'*dk)

            mk=m;break;

        end

        m=m+1;

    end

       %bfgs校正

    x=x0+rho^mk*dk;

    sk=x-x0;yk=feval(gfun,x,varargin{:})-gk;

    if(yk'*sk>0)

        Bk=Bk-(Bk*sk*sk'*Bk)/(sk'*Bk*sk)+(yk*yk')/(yk'*sk);

    end

    k=k+1;x0=x;

end

val=feval(fun,x0,varargin{:});

 

主函數部分為:

%目標函數文件

function f=f1(x)

f=(x(1)-2.0)^2+(x(2)-1.0)^2;

%等式約束條件

function he=h1(x)

he=x(1)-2.0*x(2)+1.0;

%不等式約束條件

function gi=g1(x)

gi=-0.25*x(1)^2-x(2)^2+1;

%目標函數的梯度文件

function g=df1(x)

g=[2.0*(x(1)-2.0),2.0*(x(2)-1.0)]';

%等式函數的Jacobi(轉置)矩陣文件

function dhe=dh1(x)

dhe=[1.0,-2.0]';

%不等式約束函數的Jacobi矩陣(轉置矩陣)

function dgi=dg1(x)

dgi=[-0.5*x(1),-2.0*x(2)]';

命令行指令為:

x0=[3,3]'

[x,mu,lambda,output]=multphr('f1','h1','g1','df1','dh1','dg1',x0)

輸出結果如下:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM