题目:MOSEK优化包的安装、使用及注册:以Matlab中的二次规划为例

        MOSEK优化包(MOSEK optimization package)是一个高效的优化问题求解工具包, MOSEK官方网站(https://www.mosek.com/):

1、软件下载

        在Download页面(https://www.mosek.com/downloads/)根据自己需要下载对应的版本:

例如,windows(64 bit x86)下载后得到moseksetupwin64x86.msi,而Linux(64 bit x86)下载后得到mosektoolslinux64x86.tar.bz2。

2、软件安装

        安装过程也很简单,在Windows中直接双击moseksetupwin64x86.msi安装即可,一般默认安装在了C:\Program Files目录下,在此目录会有一个mosek文件夹;在Linux中直接解压mosektoolslinux64x86.tar.bz2即可,会解压出来一个mosek文件夹。

3、Matlab中使用

        由于本人安装MOSEK的起因是想求解二次规划问题,接下来就主要以在Matlab中使用MOSEK求解二次规划问题为例来说明(MOSEK需要注册,稍后再说)。

        在Matlab中使用MOSEK求解线性规划和二次规划问题非常方便。大家都知道Matlab中包含线性规划求解函数linprog和二次规划求解函数quadprog,使用方法简介可参见:

        线性规划问题和MATLAB函数linprog的使用(https://blog.csdn.net/jbb0523/article/details/50596555)

        二次规划问题和MATLAB函数quadprog的使用(https://blog.csdn.net/jbb0523/article/details/50598641)

而MOSEK为了方便Matlab用户,将线性规划和二次规划函数名字也分别取为了linprog和quadprog,调用的语法也基本一致,可以说很方便了。

        那么这时就会有一个问题,你在Matlab调用的quadprog到底是Matlab自带的quadprog还是MOSEK呢?这个也很简单,问一下Matlab就好了。输入命令“which('quadprog')”就可以返回当前quadprog函数的路径,例如默认会输出如下路径(本人Matlab安装在了E:\Program Files目录下,版本为R2014a):

                E:\Program Files\MATLAB\R2014a\toolbox\optim\optim\quadprog.m

若想使用MOSEK的quadprog函数,则需要将MOSEK的quadprog.m文件的路径填加进来,例如本人Windows中MOSEK工具箱的路径为C:\Program Files\Mosek\8\toolbox\r2014a,只需要执行命令:

addpath('C:\Program Files\Mosek\8\toolbox\r2014a');

这时如果再运行命令“which('quadprog')”,则会输出如下路径:

                C:\Program Files\Mosek\8\toolbox\r2014a\quadprog.m

        接下来给出一段代码,可用来对比MOSEK和Matlab中的quadprog函数(mosek_example1.m):

clear;close all;clc;
%optimazation problem
H = [1 -1; -1 2];
f = [-2; -6];
A = [1 1; -1 2; 2 1];
b = [2; 2; 3];
lb = [0; 0];
%% Matlab built-in quadprog
disp('Matlab Initialize...')
temp_str = which('quadprog');
disp(temp_str);
opts = optimoptions('quadprog','Display','off');
tic;
[x,fval,exitflag,output,lambda] = quadprog(H,f,A,b,[],[],lb,[],[],opts);
toc;

%% MOSEK quadprog
addpath('C:\Program Files\Mosek\8\toolbox\r2014a\');
disp('Matlab after adding mosek...')
temp_str = which('quadprog');
disp(temp_str);
tic;
[x,fval,exitflag,output,lambda] = quadprog(H,f,A,b,[],[],lb);
toc;

        Matlab的Command Window中输出如下结果(由于优化问题规模很小,所以无法体现二者的差异性;当优化问题规模很大时,MOSEK的高效性就会非常非常明显了):

注意,以上输出信息中提示“quadprog : License cannot be located. The default search parth is ‘:C:\Users\Dell\mosek\mosek.lic’”,这是因为目前MOSEK还未注册,那么接下来就说一下MOSEK的注册问题。

4、软件注册

        对于在校师生而言,可以申请MOSEK提供的Academic Licenses,具体申请流程如下:

        (1)打开申请页面https://www.mosek.com/products/academic-licenses/

        (2)单击Request Personal Academic License,进入如下界面:

        (3)选择Personal Academic License,单击Proceed,进入如下界面:

        (4)按要求填写Name, E-mail Address(必填),Organization等信息,尤其是E-mail要使用.edu的学校邮箱(不知道其它邮箱是否可行),填好后单击Request License,稍后MOSEK会将License发送到你的邮箱(时长不等,少则十几分钟,多则一两天):

注意,邮件中MOSEK会告诉你应该将附件的mosek.lic放在哪个路径,但实际上看这个通用提示不如看Matlab给出的提示。在前面未注册之前,调用MOSEK的quadprog时会有如下提示:

即应该将mosek.lic放在目录C:\Users\Dell\mosek下(不同的电脑提示信息会不一样的)。当然了,目录C:\Users\Dell下是没有mosek文件夹的,你自己新建一个mosek文件夹,然后将mosek.lic放进去就是了。以上方法在Linux中同样可以使用,只是前面的测试程序中将addpath('C:\Program Files\Mosek\8\toolbox\r2014a\');包含的目录改为Linux中quadprog.m的所在目录即可。

        当然,有些人会选择直接在Matlab软件的默认路径中将MOSEK文件的路径填加进来(Matlab R2014a的路径添加方法参见《贝叶斯网络结构学习之K2算法(基于FullBNT-1.0.4的MATLAB实现)》(https://blog.csdn.net/jbb0523/article/details/78804963)的附录2,只需要将例子中的路径改为MOSEK的quadprog.m所在路径即可),但这样会覆盖掉Matlab的默认函数,所以个人还是推荐用的时候临时使用addpath命令填加路径即可。

5、其它注意事项

        虽然MOSEK的quadprog在求解大型二次规划问题时,求解速度比Matlab自带的quadprog会高出几个数量级,但个人在使用过程中发现,它不如Matlab自带的quadprog鲁棒,偶尔会出现返回值为空的情况(但又不会一直返回值为空),而这就会导致后面的程序出错(假如你的程序迭代运行很久了,前面调用MOSEK的quadprog一直正常,突然程序快结束时出问题了,岂不是会欲哭无泪?)。为了应对这种偶然情况,在实际使用时可使用try…catch…语句在MOSEK和Matlab的quadprog之间进行切换,使用方法举例如下(mosek_example2.m):

clear;close all;clc;
%optimazation problem
H = [1 -1; -1 2];
f = [-2; -6];
A = [1 1; -1 2; 2 1];
b = [2; 2; 3];
lb = [0; 0];
mosek_path = 'C:\Program Files\Mosek\8\toolbox\r2014a\';
addpath(mosek_path);
try
    [x,fval,exitflag,output,lambda] = quadprog(H,f,A,b,[],[],lb);
catch ME
    disp( 'Error with mosek toolbox, use built-in quadprog instead. ');
    rmpath(mosek_path);
    opts = optimoptions('quadprog','Display','off');
    [x,fval,exitflag,output,lambda] = quadprog(H,f,A,b,[],[],lb,[],[],opts);
    addpath(mosek_path);
end

即先使用MOSEK的quadprog函数求解,如果出错了,就使用Matlab自带的quadprog函数求解,这样会保证有求解结果输出。

        后来发现MOSEK的quadprog出错似乎主要是由于二次项的矩阵(即上例中的H)对角线元素为0所致,在实际使用时,得到H之后最好再加一个很小的对角阵,例如将上例中H的赋值语句换为如下语句(eye(2)表示生成一个2*2的单位矩阵):

H = [1 -1; -1 2]+(1e-8)*eye(2);

        归根到底,其实是由于MOSEK求解二次规划时,实际是将二次规划问题转换了其它等价问题去求解的。因此,有时MOSEK求解出来的结果与Matlab自带的quadprog求解出的结果会略有不同(可能是非唯一解的原因吧,仅是猜测而已,勿轻信,实际使用时自己验证一下)。

 

        另外,顺便说一句与此文无关的话:由于Matlab R2014a软件有BUG,导致帮助文件无法复制,其实使用ctrl+insert替代ctrl+c即可复制。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐