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)