Yalmip入门教程(5)-约束条件操作的相关函数

博客中所有内容均来源于自己学习过程中积累的经验以及对yalmip官方文档的翻译:https://yalmip.github.io/tutorials/

这篇博客将详细介绍yalmip工具箱中约束条件操作相关函数的用法。

1 .约束条件操作的相关函数

1.1 boundingbox函数

boundingbox函数用于求出一组约束条件中所包含变量的上下限,即提取约束条件中变量的显式边界,使用语法如下:

[B,L,U] = boundingbox(Constraint,options,x)

其中,Constraint 表示约束条件(必要输入),options 表示Yalmip设置(可选输入),x 表示需要提取边界的变量(可选输入),B 为变量x的上下限约束,为lmi变量形式,LU分别表示变量的上下限,均为矩阵形式(可选输出),下面是一个简单的示例:

**例1:**使用boundingbox求出约束x²+y²<=4中变量的上下界,并画图展示

复制代码
sdpvar x y
Ball = x^2+y^2 <= 4;
[Box,L,U] = boundingbox(Ball);
plot(Box,[x y]);
hold on
plot(Ball,[x y],'y')

运行结果:

图1 boundingbox函数效果展示

L =

-2.0000

-2.0000

U =

2.0000

2.0000

光看上面的例子,可能很难体会到这个函数的作用,但其实这个函数在求解优化问题时是非常有用的。我们知道在求解优化问题的过程中,经常会有非线性项,需要用到大M法将其转为线性项,这时候如果可以确定变量的边界,将会非常有效地提高优化问题求解效率,下面进行举例说明:

**例2:**有1个0-1变量x和1个大于0的连续变量y相乘,使用大M法将其线性化。

引入大于0的连续辅助变量z=xy,可以使用变量z和3个辅助约束条件代替这个非线性项:

z≤Mx,z≤y,z≥y-M(1-x)

其中M是变量y的一个上界,下面分析一下两者是否等效:

1)当x=0时,由z=xy可得z=0,由z≤Mx和z≥0同样可得z=0,两者等效;

2)当x=1时,由z=xy可得z=y,由z≤Mx,z≤y,z≥y-M(1-x)可得z≤y且z≥y,即z=y,两者仍然等效。

但在实际使用时,M的取值不能太大也不能太小,如果M取值太大,可能会因为浮点数精度的问题造成约束的偏差,也扩大了约束的范围,降低求解效率;如果M取值太小,甚至小于变量y的上界,那可能会改变变量y的取值范围,甚至导致模型不可解(例如,变量y∈[0,100],M取了50,那么约束z≤Mx会将y的范围限制在[0,50]之间,改变了y的取值范围)。

因此,M最合适的取值就是y的上限,使用boundingbox函数可以方便的求出变量的上界,这就是其作用所在:求出变量的上界之后,如果Yalmip建模时用到了大M法,将会自动使用变量的上界进行等效转换。

1.2 chebyball函数

chebyball函数用于求解一组约束条件所限定的边界中最大的内切圆(如果有3个或以上的变量,就是内切球以及内切超球体),其基本语法如下:

[xc,r] = chebyball(Constraint,options)

其中,Constraint 表示约束条件,options 表示Yalmip选项,xcr分别表示内切圆的圆心坐标和半径。举例说明如下:

**例3:**已知变量x和y满足约束0≤x≤1,0≤y≤1,画出该范围内最大的圆。

代码和运行结果如下:

复制代码
sdpvar x y
Box = -1 <= [x y] <= 1;
[xc,r] = chebyball(Box);
plot(Box);
hold on
plot((x-xc(1))^2 + (y-xc(2))^2 <= r^2,[],'y')

运行结果:

图2 chebyball函数效果展示

例3和例1正好正好是一个逆向过程。

1.3 check函数

check函数用在约束问题求解之后,用于检查约束条件的满足情况,其基本语法如下:

[pres,dres] = check(F)

其中,F表示约束条件,presdres分别表示原始约束和对偶约束的残差,残差即为约束实际取值和约束条件边界的偏差值,当约束条件满足时,残差为正数,当约束条件不满足时,残差为负数(具体理论不做介绍,可以使用help check或者自行查找相关理论),举例说明如下:

例4:

复制代码
sdpvar x
F0 = [x == 1];
F1 = [x == 1.25];
F2 = [0.9 <= x <= 1.2];
F3 = [x >= 2];
optimize(F0);
[pres1,dres1] = check(F1);
[pres2,dres2] = check(F2);
[pres3,dres3] = check(F3);
pres1
pres2
pres3

运行结果:

pres1 =

-0.250

pres2 =

0.1000

pres3 =

-1

x实际取值为1,约束条件F1不满足,所以残差为负数,取值为-0.25,约束条件F2满足,所以残差为正数,取值为0.1,约束条件F3不满足,所以残差为负数,取值为-1。在调试代码时check函数可以发挥很大作用。

1.4 dual函数

dual函数用于求出与约束条件相应的对偶变量,其语法如下:

Z = dual(F)

其中,F 表示约束条件,Z表示其对偶变量的取值。由于该方法是直接获取对偶变量的取值,所以一般都需要优化问题求解成功后才可以使用。首先来看官方文档给出的例子,学习一下dual函数的用法。

**例5:**求解优化问题后,使用dual函数提取约束条件对应的对偶变量。

复制代码
A = [-1 2;-3 -4];
P = sdpvar(2,2);
F = [P >= 0, A'*P+P*A <= 0, trace(P) == 1];
optimize(F);
Z2 = dual(F(2));

运行结果:

Z2 =

1.0e-09 *

0.8605 -0.1947

-0.1947 0.0440

求解优化问题后,使用dual函数就可以求出某个约束条件对应的对偶变量取值。由线性规划的理论可知,如果原问题具有最优解,那么当原问题取得最优解时,其对偶问题也取得最优解,且两个问题的最优目标函数相同,我们用一个例子来验证:

**例6:**已知一个线性规划的原问题和对偶问题,使用dual函数验证强对偶定理(即原问题的最优解和对偶问题的最优解相同)

原问题为:

对偶问题为:

matlab代码和运行结果:

复制代码
sdpvar x1 x2
z = 50*x1 + 100*x2;
F = [ x1 + x2 <= 300 , ...
     2*x1 + x2 <= 400 , ...
     x2 <= 500 , x1 >= 0 , x2 >= 0];
optimize(F , -z)
y = dual(F(1:3))
z = value(z)
w = [300 400 250]*y

运行结果:

y =

100

0

0

z =

30000

w =

30000

由结果可知,原问题和对偶问题的最优解相等,满足强对偶定理。

1.5 hull函数

hull函数用于求出一组约束条件的凸包(convex hull,此处不再做理论介绍,只介绍用法),标准语法如下:

F = hull(F1,F2,...)

其中F1,F2...表示原始的约束条件,F表示这组约束条件的凸包,官方文档中用图形直观地展示了这个函数的作用:

例7:

复制代码
sdpvar x y
F1 = [-1 <= x <= 1, -1 <= y <= 1];
F2 = [-1.5 <= x-y <= 1.5, -1.5 <= x+y <= 1.5];
H = hull(F1,F2);
plot(H);hold on
plot(F2);
plot(F1);

运行结果:

图3 约束条件和相应的convex hull

1.6 vertex函数

(该函数仅最新版yalmip才有,如果没有去官网下载最新版即可)vertex函数用于求出一组约束的顶点,其标准语法如下:

V = vertex(Constraint,[x])

其中,Constraint 表示约束条件,x 表示决策变量,V表示顶点坐标,举例说明如下:

例8:

二维空间:

复制代码
x = sdpvar(2,1);
B = [-1 <= x <= 1, sum(x) <= 3/2];
clf
plot(B,[],[],[],sdpsettings('plot.shade',0.1));
hold on;grid on
v = vertex(B,x);
m = plot(v(1,:),v(2,:),'bo');
set(m,'Markersize',10);
set(m,'Markerface','yellow');

三维空间:

复制代码
x = sdpvar(3,1);
P = [-1 <= x <= 1, sum(abs(x)) <= 1,sum(x)>=.5]
clf
plot(P,x,[],[],sdpsettings('plot.shade',0.1));
hold on;grid on
v = vertex(P,x);
m = plot3(v(1,:),v(2,:),v(3,:),'bo');
set(m,'Markersize',10);
set(m,'Markerface','yellow');

运行结果为:

图4 二维约束的顶点

图5 三维约束的顶点

2.调试小技巧,给约束命名

当所求优化问题比较复杂时,有的时候很难记住每个约束在对应的约束变量中是第几个位置,调试代码时很不方便,这时候可以使用一个:加上一个字符串,就可以给约束命名,用于在约束变量中打上标记。例如:

复制代码
sdpvar x
Constraints = [(x >= 0):'Positivity',(x <= 1):'Bounded']

运行结果:

当需要用到某个约束时,还可以用对应的'Tag'来索引,例如:

复制代码
sdpvar x
Constraints = [(x >= 0):'Positivity',(x <= 1):'Bounded'];
Constraints('Bounded')

运行结果:

相关推荐
机器学习之心HML7 小时前
MATLAB豆渣发酵工艺优化 - 基于响应面法结合遗传算法
matlab
aini_lovee1 天前
MATLAB基于小波技术的图像融合实现
开发语言·人工智能·matlab
3GPP仿真实验室1 天前
【Matlab源码】6G候选波形:OFDM-IM 增强仿真平台 DM、CI
开发语言·matlab·ci/cd
rit84324991 天前
MATLAB中Teager能量算子提取与解调信号的实现
开发语言·matlab
我找到地球的支点啦1 天前
通信扩展——扩频技术(超级详细,附带Matlab代码)
开发语言·matlab
Dev7z2 天前
基于 MATLAB 的铣削切削力建模与仿真
开发语言·matlab
fengfuyao9852 天前
基于MATLAB的表面织构油润滑轴承故障频率提取(改进VMD算法)
人工智能·算法·matlab
机器学习之心2 天前
基于随机森林模型的轴承剩余寿命预测MATLAB实现!
算法·随机森林·matlab
rit84324992 天前
基于MATLAB的环境障碍模型构建与蚁群算法路径规划实现
开发语言·算法·matlab
hoiii1872 天前
MATLAB SGM(半全局匹配)算法实现
前端·算法·matlab