ADMM(交替方向乘子法)求解-实例

本文详细介绍了使用ADMM(交替方向乘子法)求解二次规划问题的MATLAB实现,包括构建目标函数的增广拉格朗日函数,编写主函数和子函数,以及使用quadprog函数进行求解,最终给出了运行结果和小结。
摘要由CSDN通过智能技术生成

注:本内容参考:ADMM优化算法(附MATLAB代码)

文章目录

    • ADMM原理
    • ADMM求解-算法实例
    • 算法Matlab代码及注释
    • 小结

ADMM原理

ADMM求解-算法实例

下面给出一个二次规划凸优化问题,采用ADMM算法求解的示例。问题的优化模型如下:

$\begin{array}{cl}\min _{x, y} & (x-1)^2+(y-2)^2 \\ \text { s.t. } & 0 \leq x \leq 3 \\ & 1 \leq y \leq 4 \\ & 2 x+3 y=5\end{array}$

1、首先,构造目标函数的增广拉格朗日函数(ALM):

$L(x, y, \lambda)=f(x)+g(y)+\lambda^T(2 x+3 y-5)+\frac{\rho}{2}\|2 x+3 y-5\|$

2、基于ALM我们可以构造交替优化的求解形式:

算法Matlab代码及注释

1、主函数:main.m

%% 定义参数
% 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)]);

2、针对本问题(二次规划),构造交替求解对应表达式,为了用于solve_admm.m的二次规划求解器函数quadprog求解。即需要得到ALM的Hessian矩阵及变量的一次项系数

关于quadprog函数,请参见matlab官方指南:quadprog-二次规划

构造子函数getHession_F.m:

function [H,F] = getHession_F(fn)
% 目的:服务于solve_admm.m的二次规划求解器函数quadprog求解
% fn : function name
% H  : hessian matrix
% F  : 一次项系数
syms x y lambda rho; 
if strcmp(fn,'f1')           % 判断输入函数是 f1 的话
    f = (x-1)^2 + lambda*(2*x + 3*y -5) + rho/2*(2*x + 3*y -5)^2;
    H = hessian(f,x);        % 计算函数的 Hessian 矩阵  (2阶导数)
    F = (2*lambda + (rho*(12*y - 20))/2 - 2);  % x 一次项的系数:其实是由collect(f,{'x'})的x一次项系数得到
    fcol = collect(f,{'x'}); % 固定y,默认x为符号变量,输出关于x的表达式 (Collect(s,v)命令用于将符号矩阵S中所有同类项合并,并以v为符号变量输出;)
    disp(fcol);              % 输出
elseif strcmp(fn,'f2')       % 判断输入函数是 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); % y 的系数
    fcol = collect(f,{'y'}); % 固定x,默认y为符号变量
    disp(fcol);
end
end

3、ADMM子函数,用于交替优化求解x、y,子函数为solve_admm.m:

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;      % the lower bound of x
xub     = 3;      % the upper bound of x
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); % eval:可以把字符串当作命令来执行
    Fxx = eval(Fx);
    x   = quadprog(Hxx,Fxx,[],[],[],[],xlb,xub,[]);   % Quadratic programming function
    % 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

4、原问题的目标函数,compute_fval.m:

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

5、运行结果:

命令行输出:

[x,y]:0.53846,1.3077

小结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值