Matlab CPLEX:在 cplexmiqcp 中添加多个 SOCP 约束
Matlab CPLEX: add multiple SOCP constraints in cplexmiqcp
我已经在 MATLAB 中编写了我的问题,使用 CPLEX 作为求解器。由于我无法控制的问题(这是可行的),CPLEX class API 在解决我的问题时搞砸了。因此,基于在互联网上其他地方找到的 post,我尝试使用工具箱 API 来解决。
为了解决我的问题,我需要使用 cplexmiqcp,它有以下输入:
cplexmiqcp(H,f,Aineq,bineq,Aeq,beq,l,Q,r,sostype,sosind,soswt,varLB,varUB,vartype,x0,options);
我有多个 SOCP 约束,并且使用 class API,我能够使用一个结构来定义它们中的每一个,例如:
for n=1:numQCs
cplex.Model.qc(n).a=QC.a{n};
cplex.Model.qc(n).Q=QC.Q{n,1};
cplex.Model.qc(n).sense=QC.sense{n};
cplex.Model.qc(n).rhs=QC.rhs{n};
cplex.Model.qc(n).lhs=QC.lhs{n};
end
但是如何为 cplexmiqcp 输入定义多个二次约束?这些是 l,Q,r
。当我尝试像以前一样创建结构时,我得到 "Error: incorrect l,Q,r."
cplexmiqcp 工具箱函数的文档是 here。引用文档,对于 l
、Q
和 r
,我们有:
l: Double column vector or matrix for linear part of quadratic constraints
Q: Symmetric double matrix or row cell array of symmetric double matrices for quadratic constraints
r: Double or double row vector for rhs of quadratic inequality constraints
所以,当我们想要创建一个二次约束时,我们可以给出一个双列向量,一个对称双精度矩阵,以及一个用于 l
、Q
和 r
, 分别。当我们要创建多个二次约束时,我们需要提供一个矩阵,一个对称双矩阵的行元胞数组,以及一个行向量 for l
, Q
和 r
。
考虑以下简单模型:
Minimize
obj: x1 + x2 + x3 + x4 + x5 + x6
Subject To
c1: x1 + x2 + x5 = 8
c2: x3 + x5 + x6 = 10
q1: [ - x1 ^2 + x2 ^2 + x3 ^2 ] <= 0
q2: [ - x4 ^2 + x5 ^2 ] <= 0
Bounds
x2 Free
x3 Free
x5 Free
End
MATLAB 代码如下所示:
H = [];
f = [1 1 1 1 1 1]';
Aineq = []
bineq = []
Aeq = [1 1 0 0 1 0;
0 0 1 0 1 1];
beq = [8 10]';
l = [0 0;
0 0;
0 0;
0 0;
0 0;
0 0;];
Q = {[-1 0 0 0 0 0;
0 1 0 0 0 0;
0 0 1 0 0 0;
0 0 0 0 0 0;
0 0 0 0 0 0;
0 0 0 0 0 0], ...
[0 0 0 0 0 0;
0 0 0 0 0 0;
0 0 0 0 0 0;
0 0 0 -1 0 0;
0 0 0 0 1 0;
0 0 0 0 0 0]};
r = [0 0];
sostype = [];
sosind = [];
soswt = [];
lb = [ 0; -inf; -inf; 0; -inf; 0];
ub = []; % implies all inf
ctype = []; % implies all continuous
options = cplexoptimset;
options.Display = 'on';
options.ExportModel = 'test.lp';
[x, fval, exitflag, output] = cplexmiqcp (H, f, Aineq, bineq, Aeq, beq,...
l, Q, r, sostype, sosind, soswt, lb, ub, ctype, [], options);
fprintf ('\nSolution status = %s \n', output.cplexstatusstring);
fprintf ('Solution value = %f \n', fval);
disp ('Values =');
disp (x');
我已经在 MATLAB 中编写了我的问题,使用 CPLEX 作为求解器。由于我无法控制的问题(这是可行的),CPLEX class API 在解决我的问题时搞砸了。因此,基于在互联网上其他地方找到的 post,我尝试使用工具箱 API 来解决。
为了解决我的问题,我需要使用 cplexmiqcp,它有以下输入:
cplexmiqcp(H,f,Aineq,bineq,Aeq,beq,l,Q,r,sostype,sosind,soswt,varLB,varUB,vartype,x0,options);
我有多个 SOCP 约束,并且使用 class API,我能够使用一个结构来定义它们中的每一个,例如:
for n=1:numQCs
cplex.Model.qc(n).a=QC.a{n};
cplex.Model.qc(n).Q=QC.Q{n,1};
cplex.Model.qc(n).sense=QC.sense{n};
cplex.Model.qc(n).rhs=QC.rhs{n};
cplex.Model.qc(n).lhs=QC.lhs{n};
end
但是如何为 cplexmiqcp 输入定义多个二次约束?这些是 l,Q,r
。当我尝试像以前一样创建结构时,我得到 "Error: incorrect l,Q,r."
cplexmiqcp 工具箱函数的文档是 here。引用文档,对于 l
、Q
和 r
,我们有:
l: Double column vector or matrix for linear part of quadratic constraints
Q: Symmetric double matrix or row cell array of symmetric double matrices for quadratic constraints
r: Double or double row vector for rhs of quadratic inequality constraints
所以,当我们想要创建一个二次约束时,我们可以给出一个双列向量,一个对称双精度矩阵,以及一个用于 l
、Q
和 r
, 分别。当我们要创建多个二次约束时,我们需要提供一个矩阵,一个对称双矩阵的行元胞数组,以及一个行向量 for l
, Q
和 r
。
考虑以下简单模型:
Minimize
obj: x1 + x2 + x3 + x4 + x5 + x6
Subject To
c1: x1 + x2 + x5 = 8
c2: x3 + x5 + x6 = 10
q1: [ - x1 ^2 + x2 ^2 + x3 ^2 ] <= 0
q2: [ - x4 ^2 + x5 ^2 ] <= 0
Bounds
x2 Free
x3 Free
x5 Free
End
MATLAB 代码如下所示:
H = [];
f = [1 1 1 1 1 1]';
Aineq = []
bineq = []
Aeq = [1 1 0 0 1 0;
0 0 1 0 1 1];
beq = [8 10]';
l = [0 0;
0 0;
0 0;
0 0;
0 0;
0 0;];
Q = {[-1 0 0 0 0 0;
0 1 0 0 0 0;
0 0 1 0 0 0;
0 0 0 0 0 0;
0 0 0 0 0 0;
0 0 0 0 0 0], ...
[0 0 0 0 0 0;
0 0 0 0 0 0;
0 0 0 0 0 0;
0 0 0 -1 0 0;
0 0 0 0 1 0;
0 0 0 0 0 0]};
r = [0 0];
sostype = [];
sosind = [];
soswt = [];
lb = [ 0; -inf; -inf; 0; -inf; 0];
ub = []; % implies all inf
ctype = []; % implies all continuous
options = cplexoptimset;
options.Display = 'on';
options.ExportModel = 'test.lp';
[x, fval, exitflag, output] = cplexmiqcp (H, f, Aineq, bineq, Aeq, beq,...
l, Q, r, sostype, sosind, soswt, lb, ub, ctype, [], options);
fprintf ('\nSolution status = %s \n', output.cplexstatusstring);
fprintf ('Solution value = %f \n', fval);
disp ('Values =');
disp (x');