愿你搜索到人生的最优解

ADMM优化算法(附MATLAB代码)_matlab代码



文案:挽月

排版:随心390


本期推文目录:

01 ADMM算法的基本思想

02 ADMM算法的改进思路

03 ADMM算法的实例讲解







01 | ADMM算法的基本思想


ADMM算法并不是一个很新的算法,他只是整合了不少经典优化思路,然后结合现代统计学习所遇到的问题,提出了一个比较好实施的分布式计算框架

ADMM针对的是等式约束的凸优化问题

ADMM优化算法(附MATLAB代码)_留言板_02

ADMM优化算法(附MATLAB代码)_留言板_03


ADMM算法的核心是原始对偶算法的增广拉格朗日法(ALM)。拉格朗日函数是解决了多个约束条件下的优化问题,这种方法可以求解一个有n个变量与k个约束条件的优化问题。构造拉格朗日函数的方法在一般的高等数学教材中找到。

ADMM优化算法(附MATLAB代码)_matlab代码_04


原来带约束求解  ,现在求解对偶问题,两个问题等价 

ADMM优化算法(附MATLAB代码)_留言板_05

拆成两步:

第一步,先固定  然后求解:

ADMM优化算法(附MATLAB代码)_matlab代码_06


第二步,将求解后的x带入到拉格朗日函数当中,用类似于梯度下降的方法,得到 







02 | ADMM算法的改进思路


有时候为了加快算法收敛速度,会再增加一些惩罚函数加快收敛,于是就有增广拉格朗日:

ADMM优化算法(附MATLAB代码)_matlab代码_07


同理固定另外两个变量,更新其中一个变量:

ADMM优化算法(附MATLAB代码)_留言板_08







03 | ADMM算法的实例讲解


下面我们来看一个例子:

ADMM优化算法(附MATLAB代码)_matlab代码_09

我们可以构造出该目标函数的拉格朗日表达式:

ADMM优化算法(附MATLAB代码)_多目标_10

使用matlab编程,目标函数:


function  fval  = compute_fval(x,y)
fval = (x-1)^2 + (y-2)^2;
end


由于目标函数是二次函数所以使用quadprog函数进行求解。

function [H,F] = getHession_F(fn)
% fn : function name
% H :hessian matrix
% F :一次项数系数
syms x y lambda rho;
if strcmp(fn,'f1')
f = (x-1)^2 + lambda*(2*x + 3*y -5) + rho/2*(2*x + 3*y -5)^2;
H = hessian(f,x);
F = (2*lambda + (rho*(12*y - 20))/2 - 2);
fcol = collect(f,{'x'});%固定y,默认x为符号变量
disp(fcol);
elseif strcmp(fn,'f2')
f = (y-2)^2 + lambda*(2*x + 3*y -5) + rho/2*(2*x + 3*y -5)^2;
H = hessian(f,y);
F = (3*lambda + (rho*(12*x - 30))/2 - 4);
fcol = collect(f,{'y'});%固定x,默认y为符号变量

disp(fcol);
end
end


使用quadprog进行交替求解x,y 


function [x,y] = solve_admm(param)

x = param.x0;
y = param.y0;
lambda = param.lambda;
beta = param.beta;
rho = param.rho;
Hx = param.Hx;
Fx = param.Fx;
Hy = param.Hy;
Fy = param.Fy;
%%
xlb = 0;
xub = 3;
ylb = 1;
yub = 4;
maxIter = param.maxIter;
i = 1;
funval = zeros(maxIter-1,1);
iterNum = zeros(maxIter-1,1);
while 1
if i == maxIter
break;
end
% solve x
Hxx = eval(Hx);
Fxx = eval(Fx);
x = quadprog(Hxx,Fxx,[],[],[],[],xlb,xub,[]);
% solve y
Hyy = eval(Hy);
Fyy = eval(Fy);
y=quadprog(Hyy,Fyy,[],[],[],[],ylb,yub,[]);
% update lambda
lambda = lambda + rho*(2*x + 3*y -5); % ascend
funval(i) = compute_fval(x,y);
iterNum(i) = i;
i = i + 1;
end
plot(iterNum,funval,'-r');
end


main函数


% x0,y0都是可行解
param.x0 = 1;
param.y0 = 1;
param.lambda = 1;
param.maxIter = 30;
param.beta = 1.1; % a constant
param.rho = 0.5;

[Hx,Fx] = getHession_F('f1');
[Hy,Fy] = getHession_F('f2');

param.Hx = Hx;
param.Fx = Fx;
param.Hy = Hy;
param.Fy = Fy;

% solve problem using admm algrithm
[x,y] = solve_admm(param);

% disp minimum
disp(['[x,y]:' num2str(x) ',' num2str(y)]);


求解结果如下图所示:

ADMM优化算法(附MATLAB代码)_matlab代码_11


更多程序可以继续浏览:

​https://web.stanford.edu/~boyd/papers/admm/​


各位小伙伴可在留言板留言,未来我们讲解的具体内容由你做主。如果可以的话,可以把希望讲解的文献也在留言板上写出来。


END


ADMM优化算法(附MATLAB代码)_多目标_12

长按识别二维码关注我们