YALMIP学习(二)准备开始!

下面的代码基本上介绍了你需要学习的所有内容。它使用 sdpvar、约束、目标、选项(包括通过 sdpsettings 的求解器选项)定义变量,使用优化解决问题,检查结果并提取解决方案(请注意,代码将求解器指定为 QUADPROG。如果未安装 QUADPROG,只需在选项定义中删除该求解器选择即可。YALMIP将选择它发现已安装的其他求解器)

% It's good practice to start by clearing YALMIPs internal database 
% Every time you call sdpvar etc, an internal database grows larger
yalmip('clear')

% Define variables
x = sdpvar(10,1);

% Define constraints 
Constraints = [sum(x) <= 10, x(1) == 0, 0.5 <= x(2) <= 1.5];
for i = 1 : 7
  Constraints = [Constraints, x(i) + x(i+1) <= x(i+2) + x(i+3)];
end

% Define an objective
Objective = x'*x+norm(x,1);

% Set some options for YALMIP and solver
options = sdpsettings('verbose',1,'solver','quadprog','quadprog.maxiter',100);

% Solve the problem
sol = optimize(Constraints,Objective,options);

% Analyze error flags
if sol.problem == 0
 % Extract and display value
 solution = value(x)
else
 display('Hmm, something went wrong!');
 sol.info
 yalmiperror(sol.problem)
end

看到这一点,让我们从头开始。

YALMIPs符号变量

YALMIP中最重要的命令是sdpvar。此命令用于定义决策变量。为了定义一个有 n 行和 m 列的矩阵(或标量)P,我们写

P = sdpvar(n,m);

请注意,方阵默认是对称的!为了获得完全参数化(即不一定对称)的方阵,需要第三个参数。

P = sdpvar(3,3,'full');

提示:如果省略 ;或者简单地写下名称,将显示表达式,您可以检查其属性

P
Linear matrix variable 3x3 (full, real, 9 variables)

第三个参数可用于获得许多预定义类型的变量,例如托普利茨、汉克尔、对角矩阵、对称矩阵和斜对称矩阵。有关详细信息,请参阅 sdpvar 上的帮助文本。或者,可以将标准 MATLAB 命令应用于矢量。

x = sdpvar(n,1);
D = diag(x) ;    % Diagonal matrix
H = hankel(x);   % Hankel matrix
T = toeplitz(x); % Hankel matrix

可以用三种不同的方式定义标量。

x = sdpvar(1,1); y = sdpvar(1,1);
x = sdpvar(1);   y = sdpvar(1);
sdpvar x y

sdpvar 对象在 MATLAB 中像任何其他变量一样作,大多数函数都是重载的。因此,以下命令有效

P = sdpvar(3,3) + diag(sdpvar(3,1));
X = [P P;P eye(length(P))] + 2*trace(P);
Y = X + sum(sum(P*rand(length(P)))) + P(end,end)+hankel(X(:,1));

在开发代码并且您不是 YALMIP 专业人士时,请养成查看表达式和变量的习惯,看看它们实际上具有您期望它们具有的属性。例如,在这里,X应该是一个6x6的实数和对称矩阵,除非我们犯了一些错误,事实上它是由定义对称9x3矩阵的3个变量构造的。

>> X
Linear matrix variable 6x6 (symmetric, real, 9 variables)

在某些情况下,使用多维变量简化了编码。这在YALMIP中支持两种不同的构造,单元数组和多维sdpvar对象。

单元格数组格式只不过是以下代码的抽象

for i = 1:5
  X{i} = sdpvar(2,3);
end

通过在 sdpvar 中使用矢量维度,可以按如下方式设置相同的单元数组

X = sdpvar([2 2 2 2 2],[3 3 3 3 3]);

单元数组现在可以像往常一样在 MATLAB 中使用。

上述方法的缺点是变量 X 不能直接用作标准 sdpvar 对象(加号等操作不会在 MATLAB 中的单元格上重载)。作为替代方案,可以使用完全通用的多维 sdpvar。我们可以用这个调用创建一个本质上等效的对象。

X = sdpvar(2,3,5);

不同之处在于,我们可以使用标准 MATLAB 代码直接对这个对象进行操作。

Y = sum(X,3)
X(:,:,2)

请注意,根据标准 YALMIP 语法,前两个切片是对称的(如果前两个维度相同)。要创建完全参数化的高维变量,请使用尾随标志,就像在标准情况下一样。

X = sdpvar(2,2,2,2,'full');

有关多维变量的插图,请查看数独示例

约束

要定义约束集合,我们只需创建并连接它们。约束的含义与上下文相关。如果左手边和右边是埃尔米特的,则约束被解释为正确定性,否则是元素方面的。因此,声明对称矩阵和正确定性约束是用

n = 3;
P = sdpvar(n,n);
C = [P>=0];

而具有正元素的对称矩阵定义为,例如,

P = sdpvar(n,n);
C = [P(:)>=0];

请注意,这定义了两次非诊断约束。一个好的 SDP 求解器可能会在预处理期间检测到这一点并简化模型,但我们当然只能使用标准 MATLAB 代码手动定义唯一元素

C = [triu(P)>=0];

C = [P(find(triu(ones(n))))>=0];

根据上述规则,可以使用 >= 运算符立即定义具有正元素的非方阵(或通常是非对称矩阵)

P = sdpvar(n,2*n);
C = [P>=0];

具有正元素的完全参数化的方阵也是如此

P = sdpvar(n,n,'full');
C = [P>=0];

通过添加或连接它们来定义多个约束的列表。

P = sdpvar(n,n);
C = [P>=0] + [P(1,1)>=2];
C = [P>=0, P(1,1)>=2];

提示:可以显示约束列表,并且可以检查是否确实定义了要定义的约束类型。正如我们养成了在开发代码时查看表达式的习惯一样,我们也应该查看约束列表,看看它们是否与意图匹配。

C
++++++++++++++++++++++++++++++++++++++
|   ID|                    Constraint|
++++++++++++++++++++++++++++++++++++++
|   #1|         Matrix inequality 3x3|
|   #2|   Element-wise inequality 1x1|
++++++++++++++++++++++++++++++++++++++

 

当然,所涉及的表达式可以是任意 sdpvar 对象,可以定义相等约束 (==),也可以使用 <= 的约束。

C = [P>=0, P(1,1)<=2, sum(sum(P))==10
++++++++++++++++++++++++++++++++++++++
|   ID|                    Constraint|
++++++++++++++++++++++++++++++++++++++
|   #1|         Matrix inequality 3x3|
|   #2|   Element-wise inequality 1x1|
|   #3|       Equality constraint 1x1|
++++++++++++++++++++++++++++++++++++++

定义多个约束的一种便捷方法是使用双面约束。

F = [0 <= P(1,1) <= 2];

不能使用严格的不等式(YALMIP 会警告您),因为它们在使用数值求解器进行优化时没有任何意义,因为这些求解器无论如何总是使用数值公差。因此,如果您需要严格上限,则必须选择保证金。请注意,此保证金的选择是一个棘手的问题。太小,不会有任何区别,因为它会淹没在求解器用于将约束定义为足够接近可行的一般公差中,而太大可能会过多地减少可行空间。

my_tolerance_for_strict = 1e-5;
F = [0 <= P(1,1) <= 2-my_tolerance_for_strict, 
     P >= eye(n)*my_tolerance_for_strict];

但请注意,很多时候严格不等式是齐次问题的一部分,应该通过添加单个约束(如 P>=eye(n) 并将所有其他约束替换为非严格约束来去同质化。

可以在 MATLAB 中像往常一样在 for 循环等中附加几个约束

F = [0 <= P(1,1) <= 2];
for i = 2:n-1
 F = [F, P(i,1) <= P(2,i) - P(i,i)];
end

定义变量和约束后,您就可以解决问题了。查看其余教程以了解有关此内容的更多信息。

我也还在学习中,各位大佬看到有什么问题求轻喷,就是公益翻译上传一下,方便自己回看,也方便别人看。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值