罚函数法——乘子法

罚函数法——乘子法

  • 乘子法

乘子法

例题
罚函数法——乘子法_第1张图片
代码

function [x,mu,lam,output]=multphr(fun,hf,gf,dfun,dhf,dgf,x0)
maxk=1000;
sigma=2.0;
theta=0.8; 
eta=2.0; 
k=0; 
ink=0;
epsilon=1e-5;
x=x0; 
he=feval(hf,x); 
gi=feval(gf,x);
n=length(x); 
l=length(he); 
m=length(gi);
mu=0.1*ones(l,1); 
lam=0.1*ones(m,1);
betak=10; 
betaold=10;
while(betak>epsilon && k<maxk)
    [ik,x,val]=bfgs('mpsi','dmpsi',x0,fun,hf,gf,dfun,dhf,dgf,mu,lam,sigma);
    ink=ink+ik;
    he=feval(hf,x); 
    gi=feval(gf,x);
    betak=sqrt(norm(he,2)^2+norm(min(gi,lam/sigma),2)^2);
    if betak>epsilon
        mu=mu-sigma*he;
        lam=max(0.0,lam-sigma*gi);
        if(k>=2 && betak>theta*betaold)
            sigma=eta*sigma;
        end
    end
    k=k+1;
    betaold=betak;
    x0=x;
end
f=feval(fun,x);
output.fval=f;
output.iter=k;
output.inner_iter=ink;
output.beta=betak;

function psi=mpsi(x,fun,hf,gf,dfun,dhf,dgf,mu,lam,sigma)
f=feval(fun,x); he=feval(hf,x); gi=feval(gf,x);
l=length(he); m=length(gi);
psi=f; s1=0.0;
for i=1:l
    psi=psi-he(i)*mu(i);
    s1=s1+he(i)^2;
end
psi=psi+0.5*sigma*s1;
s2=0.0;
for i=1:m
    s3=max(0.0,lam(i)-sigma*gi(i));
    s2=s2+s3^2-lam(i)^2;
end
psi=psi+s2/(2.0*sigma);

function dpsi=dmpsi(x,fun,hf,gf,dfun,dhf,dgf,mu,lam,sigma)
dpsi=feval(dfun,x);
he=feval(hf,x); 
gi=feval(gf,x);
dhe=feval(dhf,x); 
dgi=feval(dgf,x);
l=length(he); 
m=length(gi);
for(i=1:l)
    dpsi=dpsi+(sigma*he(i)-mu(i))*dhe(:,i);
end
for(i=1:m)
    dpsi=dpsi+(sigma*gi(i)-lam(i))*dgi(:,i);
end
function f=f1(x)
f=-3*x(1)^2-x(2)^2-2*x(3)^2;
function he=h1(x)
he=x(1)^2+x(2)^2+x(3)^2-3;
function gi=g1(x)
gi=zeros(2,1);
gi(1)=-x(1)+x(2);
gi(2)=x(1);
function g=df1(x)
g=[-6*x(1);-2*x(2);-4*x(3)];
function dhe=dh1(x)
dhe=[2*x(1), 2*x(2), 2*x(3)]';
function dgi=dg1(x)
dgi=[-1 1; 1 0; 0 0];
function[k,x,val]=bfgs(fun,gfun,x0,varargin)
N=1000;
epsilon=1.e-5;
beta=0.55;
sigma=0.4;
n=length(x0);
Bk=eye(n);
k=0;
while(k<N)
    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+beta^m*dk,varargin{:});
        oldf=feval(fun,x0,varargin{:});
        if(newf<=oldf+sigma*beta^m*gk'*dk)
            mk=m;
            break;
        end
        m=m+1;
    end
    x=x0+beta^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{:});

测试文件

clear;
clc;
 x0=[0,0,0]';
[x,mu,lam,output]=multphr('f1','h1','g1','df1','dh1','dg1',x0)

输出结果
罚函数法——乘子法_第2张图片

你可能感兴趣的:(#,最优化方法)