coneprog
二阶锥规划求解器
语法
说明
coneprog 函数是一个二阶锥规划求解器,用于求由下式指定的问题的最小值
需满足以下约束
f、x、b、beq、lb 和 ub 是向量,A 和 Aeq 是矩阵。对于每个 i,矩阵 Asoc(i)、向量 dsoc(i) 和 bsoc(i) 以及标量 γ(i) 处于使用 secondordercone 创建的二阶锥约束中。
有关锥约束的详细信息,请参阅二阶锥约束。
求解二阶锥规划问题,x = coneprog(f,socConstraints)socConstraints 中的约束编码为
Asoc(i) =
socConstraints(i).Absoc(i) =
socConstraints(i).bdsoc(i) =
socConstraints(i).dγ(i) =
socConstraints(i).gamma
示例
要使用二阶锥约束设立问题,请创建一个二阶锥约束对象。
Asoc = diag([1,1/2,0]); bsoc = zeros(3,1); dsoc = [0;0;1]; gamma = 0; socConstraints = secondordercone(Asoc,bsoc,dsoc,gamma);
创建一个目标函数向量。
f = [-1,-2,0];
该问题没有线性约束。为这些约束创建空矩阵。
Aineq = []; bineq = []; Aeq = []; beq = [];
对 x(3) 设置上界和下界。
lb = [-Inf,-Inf,0]; ub = [Inf,Inf,2];
使用 coneprog 函数求解该问题。
[x,fval] = coneprog(f,socConstraints,Aineq,bineq,Aeq,beq,lb,ub)
Optimal solution found.
x = 3×1
0.4851
3.8806
2.0000
fval = -8.2462
解的分量 x(3) 位于其上界。锥约束在解处处于活动状态:
norm(Asoc*x-bsoc) - dsoc'*x % Near 0 when the constraint is activeans = -2.5677e-08
要设立一个具有多个二阶锥约束的问题,请创建一个约束对象数组。为了节省时间和内存,请先创建最高阶指数约束。
Asoc = diag([1,2,0]); bsoc = zeros(3,1); dsoc = [0;0;1]; gamma = -1; socConstraints(3) = secondordercone(Asoc,bsoc,dsoc,gamma); Asoc = diag([3,0,1]); dsoc = [0;1;0]; socConstraints(2) = secondordercone(Asoc,bsoc,dsoc,gamma); Asoc = diag([0;1/2;1/2]); dsoc = [1;0;0]; socConstraints(1) = secondordercone(Asoc,bsoc,dsoc,gamma);
创建线性目标函数向量。
f = [-1;-2;-4];
使用 coneprog 函数求解该问题。
[x,fval] = coneprog(f,socConstraints)
Optimal solution found.
x = 3×1
0.4238
1.6477
2.3225
fval = -13.0089
指定一个目标函数向量和单个二阶锥约束。
f = [-4;-9;-2]; Asoc = diag([1,4,0]); bsoc = [0;0;0]; dsoc = [0;0;1]; gamma = 0; socConstraints = secondordercone(Asoc,bsoc,dsoc,gamma);
指定一个线性不等式约束。
A = [1/4,1/9,1]; bsoc = 5;
求解。
[x,fval] = coneprog(f,socConstraints,A,bsoc)
Optimal solution found.
x = 3×1
3.2304
0.6398
4.1213
fval = -26.9225
要观测 coneprog 求解器的迭代,请将 Display 选项设置为 "iter"。
options = optimoptions("coneprog",Display="iter");
创建一个二阶锥规划问题,并使用 options 对其进行求解。
Asoc = diag([1,1/2,0]); bsoc = zeros(3,1); dsoc = [0;0;1]; gamma = 0; socConstraints = secondordercone(Asoc,bsoc,dsoc,gamma); f = [-1,-2,0]; Aineq = []; bineq = []; Aeq = []; beq = []; lb = [-Inf,-Inf,0]; ub = [Inf,Inf,2]; [x,fval] = coneprog(f,socConstraints,Aineq,bineq,Aeq,beq,lb,ub,options)
Iter Fval Primal Infeas Dual Infeas Duality Gap Time 0 0.000000e+00 0.000000e+00 5.714286e-01 2.000000e-01 0.02 1 -7.558066e+00 0.000000e+00 7.151114e-02 2.502890e-02 0.02 2 -7.366973e+00 0.000000e+00 1.075440e-02 3.764040e-03 0.02 3 -8.243432e+00 0.000000e+00 5.191882e-05 1.817159e-05 0.02 4 -8.246067e+00 0.000000e+00 2.430813e-06 8.507845e-07 0.03 5 -8.246211e+00 0.000000e+00 6.154504e-09 2.154077e-09 0.03 Optimal solution found.
x = 3×1
0.4851
3.8806
2.0000
fval = -8.2462
创建一个二阶锥规划问题的元素。为了节省时间和内存,请先创建最高阶指数约束。
Asoc = diag([1,2,0]); bsoc = zeros(3,1); dsoc = [0;0;1]; gamma = -1; socConstraints(3) = secondordercone(Asoc,bsoc,dsoc,gamma); Asoc = diag([3,0,1]); dsoc = [0;1;0]; socConstraints(2) = secondordercone(Asoc,bsoc,dsoc,gamma); Asoc = diag([0;1/2;1/2]); dsoc = [1;0;0]; socConstraints(1) = secondordercone(Asoc,bsoc,dsoc,gamma); f = [-1;-2;-4]; options = optimoptions("coneprog",Display="iter");
按照problem中所述,创建一个包含必需字段的问题结构体。
problem = struct("f",f,... "socConstraints",socConstraints,... "Aineq",[],"bineq",[],... "Aeq",[],"beq",[],... "lb",[],"ub",[],... "solver","coneprog",... "options",options);
通过调用 coneprog 求解问题。
[x,fval] = coneprog(problem)
Iter Fval Primal Infeas Dual Infeas Duality Gap Time 0 0.000000e+00 0.000000e+00 5.333333e-01 9.090909e-02 0.04 1 -9.696012e+00 5.551115e-17 7.631901e-02 1.300892e-02 0.04 2 -1.178942e+01 0.000000e+00 1.261803e-02 2.150800e-03 0.04 3 -1.294426e+01 9.251859e-18 1.683078e-03 2.868883e-04 0.04 4 -1.295217e+01 9.251859e-18 8.994595e-04 1.533170e-04 0.04 5 -1.295331e+01 0.000000e+00 4.748841e-04 8.094615e-05 0.04 6 -1.300753e+01 0.000000e+00 2.799942e-05 4.772628e-06 0.04 7 -1.300671e+01 9.251859e-18 2.366136e-05 4.033187e-06 0.05 8 -1.300850e+01 9.251859e-18 8.251573e-06 1.406518e-06 0.05 9 -1.300842e+01 4.625929e-18 7.332583e-06 1.249872e-06 0.05 10 -1.300866e+01 9.251859e-18 2.616719e-06 4.460317e-07 0.05 11 -1.300892e+01 1.850372e-17 2.215835e-08 3.776991e-09 0.05 Optimal solution found.
x = 3×1
0.4238
1.6477
2.3225
fval = -13.0089
创建一个二阶锥规划问题。为了节省时间和内存,请先创建最高阶指数约束。
Asoc = diag([1,2,0]); bsoc = zeros(3,1); dsoc = [0;0;1]; gamma = -1; socConstraints(3) = secondordercone(Asoc,bsoc,dsoc,gamma); Asoc = diag([3,0,1]); dsoc = [0;1;0]; socConstraints(2) = secondordercone(Asoc,bsoc,dsoc,gamma); Asoc = diag([0;1/2;1/2]); dsoc = [1;0;0]; socConstraints(1) = secondordercone(Asoc,bsoc,dsoc,gamma); f = [-1;-2;-4]; options = optimoptions("coneprog",Display="iter"); Aineq = []; bineq = []; Aeq = []; beq = []; lb = []; ub = [];
求解该问题,请求有关求解过程的信息。
[x,fval,exitflag,output] = coneprog(f,socConstraints,Aineq,bineq,Aeq,beq,lb,ub,options)
Iter Fval Primal Infeas Dual Infeas Duality Gap Time 0 0.000000e+00 0.000000e+00 5.333333e-01 9.090909e-02 0.05 1 -9.696012e+00 5.551115e-17 7.631901e-02 1.300892e-02 0.06 2 -1.178942e+01 0.000000e+00 1.261803e-02 2.150800e-03 0.06 3 -1.294426e+01 9.251859e-18 1.683078e-03 2.868883e-04 0.06 4 -1.295217e+01 9.251859e-18 8.994595e-04 1.533170e-04 0.06 5 -1.295331e+01 0.000000e+00 4.748841e-04 8.094615e-05 0.06 6 -1.300753e+01 0.000000e+00 2.799942e-05 4.772628e-06 0.06 7 -1.300671e+01 9.251859e-18 2.366136e-05 4.033187e-06 0.06 8 -1.300850e+01 9.251859e-18 8.251573e-06 1.406518e-06 0.07 9 -1.300842e+01 4.625929e-18 7.332583e-06 1.249872e-06 0.07 10 -1.300866e+01 9.251859e-18 2.616719e-06 4.460317e-07 0.07 11 -1.300892e+01 1.850372e-17 2.215835e-08 3.776991e-09 0.07 Optimal solution found.
x = 3×1
0.4238
1.6477
2.3225
fval = -13.0089
exitflag = 1
output = struct with fields:
iterations: 11
primalfeasibility: 1.8504e-17
dualfeasibility: 2.2158e-08
dualitygap: 3.7770e-09
algorithm: 'interior-point'
linearsolver: 'augmented'
message: 'Optimal solution found.'
迭代显示和输出结构都表明,
coneprog经过 11 次迭代才得出解。退出标志值
1和output.message值'Optimal solution found.'表明该解是可靠的。output结构体表明,不可行性在求解过程中越来越低,对偶间隙也越来越小。您可以通过乘以
f'*x来重现fval输出。
f'*x
ans = -13.0089
创建一个二阶锥规划问题。为了节省时间和内存,请先创建最高阶指数约束。
Asoc = diag([1,2,0]); bsoc = zeros(3,1); dsoc = [0;0;1]; gamma = -1; socConstraints(3) = secondordercone(Asoc,bsoc,dsoc,gamma); Asoc = diag([3,0,1]); dsoc = [0;1;0]; socConstraints(2) = secondordercone(Asoc,bsoc,dsoc,gamma); Asoc = diag([0;1/2;1/2]); dsoc = [1;0;0]; socConstraints(1) = secondordercone(Asoc,bsoc,dsoc,gamma); f = [-1;-2;-4];
求解问题,请求在解处的对偶变量以及所有其他 coneprog 输出。
[x,fval,exitflag,output,lambda] = coneprog(f,socConstraints);
Optimal solution found.
检查返回的 lambda 结构体。由于唯一的问题约束是锥约束,因此只检查 lambda 结构体中的 soc 字段。
disp(lambda.soc)
5.9426
4.6039
2.4624
约束具有非零的对偶值,指示约束在解处为活动约束。
输入参数
系数向量,指定为实数向量或实数数组。系数向量表示目标函数 f'*x。该表示法假设 f 是列向量,但您也可以使用行向量或数组。coneprog 在内部将 f 转换为列向量 f(:)。
示例: f = [1,3,5,-6]
数据类型: double
二阶锥约束,指定为 SecondOrderConeConstraint 对象的向量或元胞数组。使用 secondordercone 函数创建这些对象。
socConstraints 对约束进行编码
其中,数组和方程之间的映射如下:
Asoc(i) =
socConstraints.A(i)bsoc(i) =
socConstraints.b(i)dsoc(i) =
socConstraints.d(i)γ(i) =
socConstraints.gamma(i)
示例: Asoc = diag([1 1/2 0]); bsoc = zeros(3,1); dsoc = [0;0;1]; gamma = -1; socConstraints = secondordercone(Asoc,bsoc,dsoc,gamma);
线性不等式约束,指定为实矩阵。A 是 M×N 矩阵,其中 M 是不等式的数目,而 N 是变量的数目(f 的长度)。对于大型问题,将 A 作为稀疏矩阵传递。
A 以如下形式编写 M 个线性不等式
A*x <= b,
其中,x 是由 N 个变量组成的列向量 x(:),b 是具有 M 个元素的列向量。
例如,假设有以下不等式:
x1 + 2x2 ≤ 10
3x1 + 4x2 ≤ 20
5x1 + 6x2 ≤ 30。
通过输入以下约束来指定不等式。
A = [1,2;3,4;5,6]; b = [10;20;30];
示例: 要指定 x 的各个分量加起来等于或小于 1,请指定 A = ones(1,N) 和 b = 1。
数据类型: double
线性不等式约束,指定为实数向量。b 是与 A 矩阵相关的包含 M 个元素的向量。如果将 b 作为行向量传递,求解器会在内部将 b 转换为列向量 b(:)。
b 以如下形式编写 M 个线性不等式
A*x <= b,
其中,x 是由 N 个变量组成的列向量 x(:),A 是大小为 M×N 的矩阵。
例如,假设有以下不等式:
x1 + 2x2 ≤ 10
3x1 + 4x2 ≤ 20
5x1 + 6x2 ≤ 30。
通过输入以下约束来指定不等式。
A = [1,2;3,4;5,6]; b = [10;20;30];
示例: 要指定 x 分量总和等于或小于 1,请使用 A = ones(1,N) 和 b = 1。
数据类型: single | double
线性等式约束,指定为实矩阵。Aeq 是 Me×N 矩阵,其中 Me 是等式的数目,而 N 是变量的数目(f 的长度)。对于大型问题,将 Aeq 作为稀疏矩阵传递。
Aeq 以如下形式编写 Me 个线性等式
Aeq*x = beq,
其中,x 是由 N 个变量组成的列向量 x(:),beq 是具有 Me 个元素的列向量。
例如,请参考以下等式:
x1 + 2x2 + 3x3 = 10
2x1 + 4x2 + x3 = 20。
通过输入以下约束来指定等式。
Aeq = [1,2,3;2,4,1]; beq = [10;20];
示例: 要指定 x 分量之和为 1,请指定 Aeq = ones(1,N) 和 beq = 1。
数据类型: double
线性等式约束,指定为实数向量。beq 是与 Aeq 矩阵相关的包含 Me 个元素的向量。如果将 beq 作为行向量传递,求解器会在内部将 beq 转换为列向量 beq(:)。
beq 以如下形式编写 Me 个线性等式
Aeq*x = beq,
其中,x 是由 N 个变量组成的列向量 x(:),Aeq 是大小为 Me×N 的矩阵。
例如,请参考以下等式:
x1 + 2x2 + 3x3 = 10
2x1 + 4x2 + x3 = 20。
通过输入以下约束来指定等式。
Aeq = [1,2,3;2,4,1]; beq = [10;20];
示例: 要指定 x 分量总和为 1,请使用 Aeq = ones(1,N) 和 beq = 1。
数据类型: single | double
下界,指定为实数向量或实数数组。如果 f 的长度等于 lb 的长度,则 lb 指定
x(i) >= lb(i)(对于全部 i)。
如果 numel(lb) < numel(f),则 lb 指定
x(i) >= lb(i) (1 <= i <= numel(lb))。
在这种情况下,求解器会发出警告。
示例: 要指定所有 x 分量都为正,请指定 lb = zeros(size(f))。
数据类型: double
上界,指定为实数向量或实数数组。如果 f 的长度等于 ub 的长度,则 ub 指定
x(i) <= ub(i)(对于全部 i)。
如果 numel(ub) < numel(f),则 ub 指定
x(i) <= ub(i) (1 <= i <= numel(ub))。
在这种情况下,求解器会发出警告。
示例: 要指定所有 x 分量都小于 1,请使用 ub = ones(size(f))。
数据类型: double
优化选项,指定为 optimoptions 的输出。
| MATLAB 选项 | |
|---|---|
| 选项 | 描述 |
ConstraintTolerance | 约束的可行性容差,非负标量。 |
| 显示级别(请参阅迭代输出):
|
LinearSolver | 迭代中求解单步的算法: 如果
有关稀疏示例,请参阅比较 coneprog 算法的速度。 |
| 允许的最大迭代次数,非负整数。默认值为 |
MaxTime | 算法运行的最长时间(以秒为单位),非负数或 |
| 相对对偶间隙的终止容差,非负标量。有关定义,请参阅公式 5。默认值为 |
| 代码生成 | |
ConstraintTolerance | 约束的可行性容差,非负标量。 |
| 显示级别(请参阅迭代输出):
迭代显示不会在生成的代码中显示时间列。 |
LinearSolver | 迭代中求解单步的算法: 对于代码生成, |
| 允许的最大迭代次数,非负整数。默认值为 |
| 对偶可行性的终止容差,非负标量。默认值为 |
代码生成不支持 MaxTime 选项。
示例: optimoptions("coneprog",Display="iter",MaxIterations=100)
问题结构体,指定为含有以下字段的结构体。
| 字段名称 | 条目 |
|---|---|
| 线性目标函数向量 f |
| 二阶锥约束的结构数组,或 cons = {soc1 soc2 soc3};
problem.socConstraints = {cons}; |
| 线性不等式约束矩阵 |
| 线性不等式约束向量 |
| 线性等式约束矩阵 |
| 线性等式约束向量 |
lb | 由下界组成的向量 |
ub | 由上界组成的向量 |
| 'coneprog' |
| 用 optimoptions 创建的选项 |
数据类型: struct
输出参量
解处的目标函数值,以实数形式返回。通常,fval = f'*x。当 exitflag 值为 –fval、–NaN 或 –2 时,3 输出为空(对于代码生成为 10)。
coneprog 停止的原因,以整数形式返回。
| 值 | 描述 |
|---|---|
| 函数收敛于解 |
| 迭代次数超过了 |
| 找不到可行点。 |
| 此问题无界。 |
| 搜索方向的模变得太小。无法取得进一步进展。 |
| 步骤未定义,算法因奇异系统而无法继续。仅使用稀疏数据生成代码。切换到完整数据而非稀疏数据可帮助求解器顺利完成求解。 |
| 此问题在数值上不稳定。 |
提示
如果出现退出标志 0、-7 或 -10,请尝试对 LinearSolver 选项使用不同值。
有关优化过程的信息,以包含下列字段的结构体形式返回。
| 字段 | 描述 |
|---|---|
algorithm |
|
dualfeasibility | 对偶约束违反值的最大值 |
dualitygap | 对偶间隙 |
iterations | 迭代次数 |
message | 退出消 - 在代码生成中不可用 |
primalfeasibility | 约束违反值的最大值 |
linearsolver | 使用的内部步长求解器算法 |
当 exitflag 值为 –2、-3 或 –10 时,output 字段 algorithm、dualfeasibility、dualitygap、linearsolver 和 primalfeasibility 为空(对于代码生成,数值为 NaN)。
对于代码生成,iterations 字段具有 int32 类型,而不是 double 类型。
详细信息
为什么约束
称为二阶锥约束?假设三维空间中有一个锥体在 x-y 平面中具有椭圆形横截面,并且直径与 z 坐标成正比。y 坐标的刻度为 ½,而 x 坐标的刻度为 1。定义点在 [0,0,0] 的锥体内部的不等式为
在 coneprog 语法中,此锥体具有以下参量。
A = diag([1 1/2 0]); b = [0;0;0]; d = [0;0;1]; gamma = 0;
绘制锥体的边界。
[X,Y] = meshgrid(-2:0.1:2); Z = sqrt(X.^2 + Y.^2/4); surf(X,Y,Z) view(8,2) xlabel 'x' ylabel 'y' zlabel 'z'

b 和 gamma 参量用于移动锥体。A 和 d 参量用于旋转锥体并更改其形状。
算法
该算法使用内点法。有关详细信息,请参阅二阶锥规划算法。
替代功能
App
优化实时编辑器任务为 coneprog 提供了一个可视化界面。
扩展功能
用法说明和限制:
coneprog支持使用codegen(MATLAB Coder) 函数或 MATLAB® Coder™ 生成代码。您必须拥有 MATLAB Coder 许可证才能生成代码。目标硬件必须支持标准双精度浮点计算。
代码生成目标与 MATLAB 求解器不使用相同的数学核心函数库。因此,代码生成解可能不同于求解器解,尤其是对于病态问题。
在生成代码时,
coneprog不支持problem参量。[x,fval] = coneprog(problem) % Not supported所有
coneprog输入矩阵,如A、Aeq、secondordercone输入、lb和ub,均可为全矩阵或稀疏矩阵。要使用稀疏输入,必须启用动态内存分配。请参阅Code Generation Limitations (MATLAB Coder)。当非零项的占比很小时,求解器在使用稀疏输入的情况下表现良好。将锥约束作为
SecondOrderConeConstraint对象的元胞数组传递,而不是作为这些对象的数组传递。如果没有锥约束,请传递一个空数组{}。参量
lb和ub的条目数必须与问题变量的数目相同,或者必须为空[]。如果您的目标硬件不支持无限边界,请使用
optim.coder.infbound。对于涉及嵌入式处理器的高级代码优化,您还需要 Embedded Coder® 许可证。
代码生成支持
optimoptions的以下选项:ConstraintToleranceDisplayLinearSolverMaxIterationsOptimalityTolerance
生成的代码只会对选项进行有限的错误检查。更新选项的推荐方法是使用点符号,而不是
optimoptions。opts = optimoptions("coneprog",ConstraintTolerance=1e-4); opts = optimoptions(opts,MaxIterations=1e4); % Not preferred opts.MaxIterations = 1e4; % Recommended
coneprog支持传递给求解器的选项,而不仅仅是在代码中创建的选项。如果您指定了不受支持的选项,在代码生成过程中通常会忽略该选项。为了获得可靠的结果,请仅指定支持的选项。
版本历史记录
在 R2020b 中推出用于生成
coneprog代码的所有输入矩阵,如A、Aeq、lb、ub,以及输入到secondordercone的矩阵,可以是全矩阵或稀疏矩阵。新的
exitflag-8仅适用于包含稀疏数据的代码生成。现在,您可以使用
optimoptions更新选项,但建议使用点表示法。opts = optimoptions("coneprog",ConstraintTolerance=1e-4); opts = optimoptions(opts,MaxIterations=1e4); % Not preferred opts.MaxIterations = 1e4; % Recommended
有关详细信息,请参阅coneprog 背景下的代码生成。
coneprog 可以生成 C/C++ 代码。有关详细信息,请参阅coneprog 背景下的代码生成和为 coneprog 生成代码。为了适应代码生成,现在可以将二阶锥约束作为 SecondOrderConeConstraint 对象的元胞数组传递,这是代码生成的必需语法。有关详细信息,请参阅语言限制 (MATLAB Coder)。
要提高求解具有稠密数据的问题的速度,请将 LinearSolver 选项设置为 'normal-dense'。有关示例,请参阅比较 coneprog 算法的速度。
coneprog lambda 输出参量字段 lambda.eq 和 lambda.ineq 已分别重命名为 lambda.eqlin 和 lambda.ineqlin。此更改导致 coneprog lambda 结构体字段与其他求解器中的对应字段具有相同的名称。
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
选择网站
选择网站以获取翻译的可用内容,以及查看当地活动和优惠。根据您的位置,我们建议您选择:。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)