最近在做论文时,涉及到最优化问题,而最优化里面很多时候涉及的是二次约束二次规划QCQP这样的非凸问题,一般地,这样的非凸问题是得不到全局精确的最优解的,需要另辟蹊径。常用的有半定松弛SDR。将非线性松弛为线性,以致可以SDP,利用CVX这样的专有凸规划工具箱解决;但是缺点也是很明显的:就是灵活性和可靠性不高,当约束条件里面还有正定性未知的矩阵时,SDR力不从心,这时引入了QCQP下的二阶锥规格SOCP,利用YALMIP可以很好解决这样最优化问题的近似解。所以有必要说一下YALMIP的简单应用:
YALMIP总共有四个流程:
1:设置变量 ;
2::设定目标函数f;
3:设置限定条件;
4:利用工具箱求。
1:设置变量
变量设置常用的有三种:sdqvar() 设置实型,intvar()设置整形,binvar()设置二进制形。以sdqvar()为例。Yalmip中最重要的指令就是sdpvar。这个指令是用来定义决策变量。用n行和m列定义一个矩阵(或标量)P,我们写做:
P=sdqvar(n,m),这是一个默认对称的实数方阵,类似的还有简单形式sdqvar(n)以及详细形式sdqvar(n,m,'symmetric');
第三个参数可以用来获得许多预定义类型的变量,如Toeplitz, Hankel, diagonal(对角线), symmetric(对称)和skew-symmetric(反对称)矩阵,有关信息请参阅sdpvar帮助文档;
当然为了获得一个完全参数化(不一定是对称)的方阵,第三个参数是必要的:P = sdpvar(n,n,'full');
一个复数形式的完全参数化(不一定是对称)的方阵:P = sdpvar(n,n,'full','complex');
同时,也可以补上第三个和第四个参数:P = sdpvar(n,n,'sy','co')
2:sdpsettings
sdpsettings是YALMIP和solver之间通信的桥梁,一般用作最优化函数optimize, solvesos, solvemoment 和solvemp的第三个入口参数(本文以solvesdp):
options = sdpsettings('field',value,'field',value,...)
optimize(Constraints, Objective, options)
比如:ops = sdpsettings('solver','sdpa','sdpa.maxIteration',100);
可以从ops = sdpsettings;指令中看到其所有选择的默认参数:
ops = sdpsettings;
ops
solver: ''
verbose: 1
warning: 1
cachesolvers: 0
debug: 1
beeponproblem: [-5 -4 -3 -2 -1]
showprogress: 0
saveduals: 1
removeequalities: 0
savesolveroutput: 0
savesolverinput: 0
convertconvexquad: 1
radius: Inf
relax: 0
usex0: 0
savedebug: 0
sos: [1x1 struct]
moment: [1x1 struct]
bnb: [1x1 struct]
bpmpd: [1x1 struct]
bmibnb: [1x1 struct]
cutsdp: [1x1 struct]
global: [1x1 struct]
cdd: [1x1 struct]
clp: [1x1 struct]
cplex: [1x1 struct]
csdp: [1x1 struct]
dsdp: [1x1 struct]
glpk: [1x1 struct]
kypd: [1x1 struct]
lmilab: [1x1 struct]
lmirank: [1x1 struct]
lpsolve: [1x1 struct]
maxdet: [1x1 struct]
nag: [1x1 struct]
penbmi: [1x1 struct]
pennlp: [1x1 struct]
pensdp: [1x1 struct]
sdpa: [1x1 struct]
sdplr: [1x1 struct]
sdpt3: [1x1 struct]
sedumi: [1x1 struct]
qsopt: [1x1 struct]
xpress: [1x1 struct]
quadprog: [1x1 struct]
linprog: [1x1 struct]
bintprog: [1x1 struct]
fmincon: [1x1 struct]
fminsearch: [1x1 struct]
ops.sedumi
ans =
alg: 2
beta: 0.5000
theta: 0.2500
free: 1
sdp: 0
stepdif: 0
w: [1 1]
mu: 1
eps: 1.0000e-09
bigeps: 1.0000e-03
maxiter: 150
vplot: 0
stopat: -1
denq: 0.7500
denf: 10
numtol: 5.0000e-07
bignumtol: 0.9000
numlvlv: 0
chol: [1x1 struct]
cg: [1x1 struct]
maxradius: Inf
optimize是解决最优化问题的常见函数,本文里solvesdp就是其中一种。格式:diagnostics = optimize(Constraints,Objective,options)
举个简单例子:我们面对一个线性规划LP:{min cTx subject to Ax<= b},用本文方法的话:
x = sdpvar(length(c),1);
F = [A*x<=b];
h = c'*x;
optimize(F,h);
solution = value(x);
如果我们仅仅考虑灵活性那么可以忽略目标函数h,得到:
diagnostics =
optimize
(
F
)
;返回的diag可以用在检验灵活性:
if diagnostics.problem == 0
disp('Feasible')
elseif diagnostics.problem == 1
disp('Infeasible')
else
disp('Something else happened')
end
通过上面函数获得最优化结果后,需要显示,这时就需要value(X),double是其中一种,即从决策向量里抽取数值。
整体效果可以再以一个例子说明:
已知非线性整数规划为:
Max z=x1^2+x2^2+3*x3^2+4*x4^2+2*x5^2-8*x1-2*x2-3*x3-x4-2*x5
s.t.
0<=xi<=99(i=1,2,...,5)
x1+x2+x3+x4+x5<=400
x1+2*x2+2*x3+x4+6*x5<=800
2*x1+x2+6*x3<=800
x3+x4+5*x5<=200
在matlab中输入 x=intvar(1,5);
f=[1 1 3 4 2]*(x'.^2)-[8 2 3 1 2]*x';F=set(0<=x<=99);
F=F+set([1 1 1 1 1]*x'<=400)+set([1 2 2 1 6]*x'<=800)+set(2*x(1)+x(2)+6*x(3)<=800);
F=F+set(x(3)+x(4)+5*x(5)<=200);solvesdp(F,-f)
double(f) 80199
double(x) 53 99 99 99 0
intvar(m,n):生成整数型变量;
sdpvar(m,n):生产变量;
solvesdp(F,f):求解最优解(最小值),其中F为约束条件(用set连接),f为目标函数
double:显示求解的答案