Yalmip工具箱使用教程(2)-决策变量进阶

news2024/11/23 4:54:50

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

1.决策变量的定义

1.1 sdpvar

上文简单介绍了sdpvar函数的用法,接下来将对其进行详细介绍。复习一下,sdpvar函数的基本语法如下:

x = sdpvar(n)

x = sdpvar(n,m)

x = sdpvar(n,m,'type')

x = sdpvar(n,m,'type','field')

x = sdpvar(dim1,dim2,dim3,...,dimn,'type','field')

sdpvar x

1.1.1)x = sdpvar(n)

        该命令用于定义一个n阶的对称变量方阵,当n=1时,也就相当于定义一个标量;

1.1.2)x = sdpvar(n,m)

        该命令用于定义一个n行m列的变量矩阵,当n=m时,默认该变量矩阵具有对称性,也就是说,如果使用sdpvar定义了方阵x,则x(i,j) = x(j,i),例如,定义一个3行3列决策变量P的语法如下:

P = sdpvar(3,3);

        这时候变量P默认为一个对称矩阵,也就是P(1,2) = P(2,1),P(1,3) = P(3,1),P(2,3) = P(3,2)。

1.1.3)x = sdpvar(n,m,'type')

        sdpvar函数的第三个参数用于初始化变量的性质,例如需要定义一个不对称的变量P,则需要将第三个参数设置为'full',语法如下:

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

在定义n阶变量方阵时,其他可使用的'type'参数如表1所示:

表1 sdpvar函数中常用的'type'参数

'type'参数

简化表示

含义

'full'

'f'

完整的不对称变量矩阵

'symmetric'

'sy'

对称变量矩阵

'diagonal'

/

对角阵

'toeplitz'

't'

对称托普利茨矩阵

'hankel'

/

非对称hankel矩阵

'rhankel'

/

对称hankel矩阵

'skew'

'sk'

反对称矩阵

'Hermitian'

/

hermitian矩阵

1.1.4)x = sdpvar(n,m,'type','field')

        sdpvar函数中的第四个参数'field'可用于定义复数变量矩阵。不输入任何参数时默认是实数变量矩阵,当需要定义复数矩阵时,可以添加参数'complex',形式如下:

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

        上面的语句就表示定义了一个3阶不对称的复数变量方阵。

1.1.5)sdpvar x

        该语句表示定义一个标量x(也可以理解为1行1列的变量),也可以同时定义多个标量,语句如下:

sdpvar a b c d e

        上述语句就表示定义了5个不同的标量a,b,c,d,e。

        综上,在Yalmip工具箱中一共有三种不同的方式定义标量,分别如下:

a = sdpvar(1);

a = sdpvar(1,1);

sdpvar a

        三个语句的作用完全一样,可以按照自身的使用习惯进行选择。对于二维变量,也可以通过这种方式进行定义,但根据官方文档所述,这种方式可能存在bug,建议谨慎使用:

sdpvar a(2,2);

        上述代码表示定义一个2行2列的变量a。

1.1.6)定义多维变量(三维及以上)

        对于三维以上的变量,Yalmip工具箱可以有两种不同的建模方式(当然还有简单的一种,将多维变量转为低维变量,例如2×3×4的三维变量可以转为2×12的二维变量,也可以转为1×24的一维变量,这里不再赘述),元胞数组和多维sdpvar对象,两种建模方式分别如下:

        ①定义元胞类型(cell)的sdpvar变量

        假设需要定义一个5×20×80的变量M,使用cell定义的方法为:

M = cell(1,5);

for k = 1:5

  M{k} = sdpvar(20,80);

end

也可以写成:

M = sdpvar(20*ones(5,1),80*ones(5,1));

        两种定义方式是等价的。

8ac2072775a64c9bbce70d17644dce3f.png

 

        使用cell格式定义多维变量比较方便,但缺点是无法使用一些常用的数学运算函数,例如下面的代码将会报错:

M = sdpvar(20*ones(5,1),80*ones(5,1));

N = sdpvar(20*ones(5,1),80*ones(5,1));

M + N

096ce21502c141de9aa63806026de818.png

 

        更高维度的变量也可以采用相同的方式进行定义,例如下面的代码就是定义了一个5×5×10×20的变量L:

L = sdpvar(5,5,10,20);

        需要主义的是,因为变量L前两个维度是相同的,按照之前的说明,前两个维度始终是对称的,为了定义一个不对称的变量L,也需要添加参数'full':

L = sdpvar(5,5,10,20,'full');

        这样就可以保证L的前两个维度不是对称的。

1.2 binvar

        binvar和sdpvar的语法完全一样,唯一不同的就是使用binvar定义的变量是0-1变量,也就是取值要么为0,要么为1。在实际的优化问题中很多变量都可以建模为0-1变量,例如仓库选址、配电网的支路状态等。同时,对于约束条件中的逻辑“或”的关系,也可以通过0-1变量进行建模(这实际上是线性规划的知识,我在这里只做简单介绍)。下面举两个例子:

例1:

变量x,y满足:4x + 3y ≤ 50  (1) 或x + y ≤ 20  (2)

        对于例1的约束条件,可以通过引入一个0-1变量w和一个足够大的正数M进行建模(实际上这就是常说的大M法),建模方式如下:

sdpvar x y

binvar w

M = 1e5;

Constraints = [4*x + 3*y - 50 <= w*M , x + y -20 <= (1-w)*M];

        当w=1时,约束1成立,当w=0时,约束2成立,这样就通过0-1变量完成了约束条件中逻辑“或”的表达。

例2:

变量x,y满足下面3个不等式其中2个:

4x + 3y ≤ 50,x + y ≤ 20,3x+2y <= 35

        对于例2的约束条件,可以通过引入一个3维0-1变量w和一个足够大的正数M进行建模,建模方式如下:

sdpvar x y

w = binvar(1,3);

M = 1e5;

Constraints = [

    4*x + 3*y - 50 <= w(1)*M ,...

    x + y -20 <= w(2)*M , ...

    3*x +2*y -35 <= w(3)*M , ...

    sum(w) == 2];

        当w1=1时,约束1成立,当w2=1时,约束2成立,当w3=1时,约束3成立,同时令w1+w2+w3=2,这样就通过0-1变量完成了3个约束条件中必须满足其中2个的表达。

        通过0-1变量,还可以实现分段函数、分类讨论等表达,此处不再赘述。

        另外,也可以先把变量定义为连续型,然后通过binary函数约束为0-1变量,具体用法如下:

x = sdpvar(2,3);

Constraints = [binary(x)];

1.3 intvar

        intvar和sdpvar的语法完全一样,唯一不同的就是使用intvar定义的变量是整数变量,也就是取值只能为整数。在实际的优化问题中很多变量都可以建模为整数变量,例如人数、商品件数等。

1.4 semivar

        semivar和sdpvar的语法完全一样,唯一不同的就是使用semivar定义的变量是半连续变量,也就是取值要么为0,要么为某个区间内的连续变量。但使用semivar时,可能会出现求解器不支持的情况。按上文的介绍,这种变量可以理解为逻辑“或”的关系,可以通过引入0-1变量使用大M法进行建模。为了避免求解器不支持导致模型无法求解,所以semivar很少使用,通常都会应用大M法对半连续变量进行建模。

2.决策变量相关函数

        在这一节的介绍之前,首先说明一点,sdpvar时Yamlip中的一个函数,用于定义决策变量,定义的决策变量在Matlab中为sdpvar类型。而binvar、intvar等函数定义的决策变量,本质上就是带有约束的sdpvar类型变量。所以,下面介绍的决策变量相关函数适用于所有sdpvar类型的变量,而不仅仅是通过sdpvar函数定义的变量。

2.1常见的数学运算

        Matlab中几乎所有的数学运算都可应用于sdpvar类型的变量,最常用的数学运算函数以及符号如表2所示:

表2 sdpvar类型变量常用的数学运算

数学运算

含义

用法

+

加法

x+y

-

减法

x-y

*

乘法,可用于标量和矩阵相乘以及矩阵乘法

x*y

.*

用于维度相同的矩阵,表示对应元素相乘

x.*y

abs

求绝对值

y = abs(x)

det

求行列式,仅用于方阵

y = det(x)

exp

指数函数

y = exp(x)

floor

向下取整

y = floor(A)

log,log2,log10

对数函数

y = log(A)

y = log2(A)

y = log10(A)

min/max

求最大值/最小值

y = min(x)

y = min(x,z)

y = min(x,[],dim)

[y,loc]= min(x,[],dim)

norm

求1范数、2范数、∞范数

y = norm(x)

y = norm(x,1)

y = norm(x,2)

y = norm(x,inf)

pnorm

求p范数

y = pnorm(x,q/r);

y = pnorm(x,p,'power')

2.2 value函数

        value函数是最常用的决策变量处理函数之一,可以在优化问题求解成功之后,提取决策变量的取值,其语法如下:

Y = value(X)

例如,下面的代码就是在求解优化问题后求出决策变量与目标函数的取值:

sdpvar x y

objective = 2*x + 3*y;

Constraints = [x + y >= 2 , 2*x - 3*y <= 9 , x>=0];

optimize(Constraints,objective)

x = value(x)

y = value(y)

objective = value(objective)

运行结果如下:

5f0fa0ef2de94368814cab778f5c3a31.png

   

        优化问题求解成功后,通过使用value函数我们可以知道该线性规划问题的目标函数2x+3y在(3,-1)处取得最小值3。

2.3 sdisplay函数

        sdisplay函数可以用来以符号的形式显示sdpvar变量,其语法如下:

s = sdisplay(p,[digits])

        其中,p为一个sdpvar变量,digits表示四舍五入的位数。例如:

x1 = sdpvar(1,1);

x2 = sdpvar(1,1);

f1 = x1^2 + 5*x2^2;

f2 = 3*x1^3 + x2;

m1 = sdisplay(f1)

m2 = sdisplay(f2)

m3 = sdisplay(f1*f2)

        运行结果为:

0deb8cf9c2f84824a7b7066d72401a1e.png

在调试代码的过程中,合理地应用sdisplay函数可以帮助我们确认目标函数或者约束条件的公式是否书写正确。

2.4 binmodel函数

        binmodel函数通过引入其他变量和约束,将涉及0-1变量和连续变量的多项式表达式转换为线性表达式,其语法如下:

[plin1,...,plinN,F] = binmodel(p1,...,pN,Domain)

其中plin1-plinN表示线性化之后的表达式,F表示相应的约束条件,p1-pN为初始表达式,Domain为连续变量的取值范围。下面是一个示例代码:

binvar a b

sdpvar x y

[plinear01,plinear02,F0] = binmodel(a^3+b,a*b);

[plinear1,plinear2,F] = binmodel(a^3*x+b*y,a*b*x, -2 <=[x,y] <=2);

        在上述代码中,plinear01对应线性化后的表达式a^3+b,plinear02对应于线性化之后的表达式a*b,F0为可行域,由于原始表达式中不包含连续变量,所以不需要指定取值范围;plinear1对应线性化后的表达式a^3*x+b*y,plinear2对应于线性化之后的表达式a*b*x,F0为可行域,连续变量的取值范围被限定在[-2,2]。

2.5 assign函数

        assign函数用来给sdpvar变量指定一个取值,其语法如下:

assign(X,value)

        例如下面的代码就是将变量x赋值为1

sdpvar x

assign(x,1)

value(x)

运行结果为:

 6fac62fec404486794072469d5a07b30.png

2.6 is函数

        is函数用于检查sdpvar变量是否为某类型的变量,其语法如下:

d = is(x,property)

        当变量x满足属性’property’时,d取值为1,否则取值为0。下面的示例代码时检查变量是否为线性:

x = sdpvar(1,1);

y1 = x*x;

y2 = 2*x;

m1 = is(y1,'linear')

m2 = is(y2,'linear')

        运行结果为:

 d65339d16837420ab8e18b1b716a3f99.png

上面的代码中,变量y1为非线性,因此m1=0,y2为线性,因此m2=1。其他常用的类型如表3所示:

表3 is函数常用的判断类型

属性

含义

'real'

实数

'symmetric'

对称

'hermitian'

自共轭

'scalar'

标量

'linear'

线性

'bilinear'

双线性

'quadratic'

二次型

'integer'

整数

'binary'

0-1变量

2.7 int函数

        int函数使用sdpvar形式返回多项式的积分(注意只能返回多项式的积分,无法实现其他非线性表达式的积分),其语法如下:

F = int(f,x,from,to)

        下面是一个例子:

sdpvar x1 x2 T

p = 4*x1^4 + x1*x2;

m1 = sdisplay(int(p))

m2 = sdisplay(int(p,x2))

m3 = sdisplay(int(p,[x1 x2],[0 0],[1 T]))

m4 = sdisplay(int(p,[x1 x2],[0 0],[1 x2]))

运行结果为:

9a3c9d1f64254032b132f18160440b91.png

上面的结果中,m1展示了对p中包含的所有变量求积分的结果;m2中只对变量x2求积分;m3中同时对变量x1和x2求积分,并指定了积分上下限。

2.8 jacobian函数

        jacobian函数以sdpvar变量形式返回多项式的导数,其语法如下:

J = jacobian(p)

J = jacobian(p,x)

其中,p为初始多项式,x为需要求导数的变量。下面是一个例子:

x1 = sdpvar(1,1);

x2 = sdpvar(1,1);

f = x1^2+5*x2^2;

m1 = sdisplay(jacobian(f))

m2 = sdisplay(jacobian(f,x2))

其运行结果为:

99290cfef81444798507c690b0f0b84a.png

2.9 linearize函数

linearize函数用来求出多项式p(x)在x=value(x)处的切线表达式,其语法如下:

h = linearize(p)

例子:

x = sdpvar(1,1);

f = x^2;

assign(x,1);

m1 = sdisplay(linearize(f))



assign(x,3);

m2 = sdisplay(linearize(f))

运行结果:

2fabd4262a3747089aab2bc9a3df84aa.png

2.10 replace函数

        replace函数用于将一个sdpvar类型变量替换为另一个sdpvar类型变量、表达式或者常数,其语法如下:

newexpression = replace(expression,variable,replacement)

        例如,可以用常数替换表达式中对应的变量:

sdpvar x y a b

p = 1 + x^2 + y;

m1 = replace(p,[x y],[7 8])



p1 = replace(p,[x y],[a^2 b^4]);

m2 = sdisplay(p1)

运行结果为:

 dc84a384e33b4155bda1b244ed0e7738.png

3.测试题

3.1测试1

求如下优化问题的解并将结果在命令行展示

2cb572c67b9d4a82820a7d38d382a4ef.png

3.2测试2

一汽车厂生产小、中、大三种类型的汽车,已知各类型每辆车对钢材、劳动时间的需求,利润以及每月工厂钢材、劳动时间的现有量如表4所示,试制定月生产计划,使工厂的利润最大。

表4 相关数据

 

小型

中型

大型

现有量

钢材/吨

1.5

3

5

600

劳动时间/小时

280

250

400

60000

利润/万元

2

3

4

 

 

3.3测试3

请使用Yalmip工具箱求积分ec0a2598a1d147f0a95d70459d81357c.png的取值。

3.4测试4

请使用Yalmip工具箱求函数981fddc3bea4407792537d2c20ac4088.png在点(-1,f(-1))处的切线方程。 

3.5测试题参考答案

第二章测试题的参考答案可以从下面的链接中获取:

https://download.csdn.net/download/weixin_44209907/88049325

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/752916.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

常用化合物谱图数据库查询系统-40个软件免费查!

化学图谱是用于描述化学物质结构和性质的图形化表示方法&#xff0c;在有机化学、材料科学、生物化学、药物化学等领域都被广泛的应用研究分析。不同类型的化学谱图适用于不同的化学分析和研究领域&#xff0c;为此笔者调研了常用化合物谱图数据库及各个类型的主流使用化学谱图…

(RX200)R5F52315ADFP/R5F52318ADFL/R5F52316CDFL微控制器基于RXv2 32位内核,54MHz 闪存 LQFP

RX200 32位微控制器 (MCU) 在功率效率和性能之间实现了平衡。这些MCU在工作模式下的电流消耗为0.12mA/MHz&#xff0c;在待机模式下的电流消耗仅为0.8μA&#xff08;保留RAM内容&#xff09;。RX200 MCU具有54MHz的最高CPU运行速度&#xff0c;可提供4.16 CoreMark/MHz的高性能…

Home Assistant 南方电网 计算电费

目录 1.China Southern Power Grid Statistics集成2.获取当月用电情况3.计算电费然后在UI上显示3.效果 1.China Southern Power Grid Statistics集成 链接 2.获取当月用电情况 因为我的电费是固定的&#xff0c;没有阶梯电价 用电量 * 0.63906875 电费 3.计算电费然后在UI…

ESXI8.0安装教程,在VMware Workstation安装esxi

文章目录 &#x1f41f;前言&#x1f41f;安装&#x1f41f;在VMware WorkStation中创建虚拟机&#x1f41f;ESXI部署安装&#x1f41f;安装完成后配置 &#x1f41f;前言 ESXI8.0版本开始最低RAM从以前的4GB变为8GB 本文所使用到的镜像以及Key都可以到我的网站中下载 地址&…

Python——— 面向对象

&#xff08;一&#xff09;初识面向对象 Python完全采用了面向对象的思想&#xff0c;是真正面向对象的编程语言&#xff0c; 完全支持面向对象的基本功能&#xff0c;例如&#xff1a;继承、多态、封装等。 Python 支持面向过程、面向对象、函数式编程等多种编程范 式。 Pyth…

数据结构初阶--排序2

目录 前言快速排序思路hoare版本代码实现挖坑法代码实现前后指针法代码实现 快排优化三项取中法代码实现三指针代码实现 快排非递归代码实现 归并排序思路代码实现归并非递归代码实现 计数排序思路代码实现 前言 本篇文章将继续介绍快排&#xff0c;归并等排序算法以及其变式。…

2023年iOS App Store上架流程详解(上)

目录 1.注册开发者账号 2.登录并配置人员 3.申请证书和配置文件 一.证书管理​ 二.新建证书​ 三.使用appuploader服务同步证书​ 1&#xff09;申请证书 2&#xff09;添加Identifiers和配置App ID 3&#xff09;申请配置文件 1.在Xcode项目中配置签名 2.上传应用包…

数据库应用:死锁、悲观锁、乐观锁

目录 一、理论 1.死锁 2.悲观锁 3.乐观锁 二、总结 一、理论 1.死锁 &#xff08;1&#xff09;概念 死锁是指两个或两个以上的进程在执行过程中&#xff0c;因争夺资源而造成的一种互相等待的现象&#xff0c;若无外力作用&#xff0c;它们都将无法推进下去。此时称系…

INVDIA GPU参数列表:P100,V100,A100,A800,H100等性能参数

一、P100与V100 训练深层神经网络的时候&#xff0c;V100比P100快大约2倍 二、A100 三、A800 四、H100 引用 1、 世上最全NVDIA GPU参数列表&#xff1a; V100&#xff0c; A100&#xff0c; A800&#xff0c;H100&#xff0c;3090&#xff0c;4090&#xff0c; A40&#xf…

Unity使用Android Stdio接入SDK制作AAR包

最近需要在Unity2021版本中接入SDK&#xff0c;发现和直接接入SDK有些区别&#xff0c;这里把接入的流程记录一下。 Unity在最新的版本中把UnityPlayActivity.java&#xff0c;从Class.jar中移除&#xff0c;需要在Unity的工程内找到这个文件&#xff0c;并把其加入到Android …

【监控系统】Prometheus监控组件Mysql-Exporter配置实战

Mysql-Exporter主要监控Mysql数据库的稳定性、吞吐量、连接情况、缓冲池使用情况、查询性能等各项指标&#xff0c;是我们压测时常常需要监控的一些指标。 目前&#xff0c;Exporter 支持高于5.6版本的 MySQL 和高于10.1版本的 MariaDB。在 MySQL/MariaDB 低于5.6版本时&#…

MobPush 最佳实践:消息重弹

功能概述 消息重弹功能&#xff0c;可在安卓在线通道送达的消息被其他消息挤下去时&#xff0c;重新置顶&#xff0c;增加消息的曝光度和点击率。 适用场景 仅支持Mob通过自有TCP通道下发的通知消息&#xff0c;不支持自定义推送消息支持开发者后台和推送API配置使用 功能使…

安天逆向教程——常用汇编语句

一.汇编基础 二.条件分支 反汇编时更多关注这些条件分支。如果看懂这些条件分支&#xff0c;会对程序的大体逻辑有一个整体的了解。 至于程序里面的细节&#xff0c;有时会省略掉。往往关键的跳转理解了甚至进行一点点的改动&#xff0c;就会使得程序发生翻天覆地的变化。 三…

读书笔记怎么写?《金字塔原理》读书笔记

​生活工作中有很多需要表达的场景&#xff0c;表达最重要的是逻辑清晰&#xff0c;表达出来的想法才能被理解&#xff0c;进而解决生活或工作中的困境。 《金字塔原理》详细地介绍了思维表达的方法&#xff0c;金字塔原理除了能够帮助人们以书面形式组织和表达思想以外&#x…

Vue3 组件之间父子通信

文章目录 Vue3 组件之间父子通信概述选项式API父传子子传父 组合式API父传子子传父 Vue3 组件之间父子通信 概述 所有的 props 都遵循着单向绑定原则&#xff0c;props 因父组件的更新而变化&#xff0c;自然地将新的状态向下流往子组件&#xff0c;而不会逆向传递。 选项式…

虚拟现实:将数字融入现实

随着科技的不断进步&#xff0c;虚拟现实正逐渐走进我们的现实生活&#xff0c;为我们带来了许多新的体验和可能性。虚拟现实技术将数字世界与真实世界融合在一起&#xff0c;为我们创造了令人惊叹的沉浸式体验。让我们一起探索虚拟现实正在走进现实的意义和影响。 虚拟现实为我…

C语言进阶之通讯录的实现(静态版和动态版)以及动态内存管理

通讯录的实现及动态内存管理 1.通讯录实现要求2.静态版通讯录实现2.1 contact.h文件实现2.2 contact.c文件实现2.3 main.c文件实现2.4 静态版通讯录全部文件代码 3.动态内存管理3.1 为什么存在动态内存分配3.2 动态内存函数的介绍3.3 常见的动态内存错误3.4 C/C程序的内存开辟3…

海盗搜身-2022年全国青少年信息素养大赛Python国赛第9题

[导读]&#xff1a;超平老师计划推出《全国青少年信息素养大赛Python编程真题解析》50讲&#xff0c;这是超平老师解读Python编程挑战赛真题系列的第11讲。 全国青少年信息素养大赛&#xff08;原全国青少年电子信息智能创新大赛&#xff09;是“世界机器人大会青少年机器人设…

vue3+ts+element-plus管理系统实际开发业务之增删改查

文章目录 功能一&#xff1a; 实现一个表格增、删、改、查功能✏️ 1. 表格、添加按钮、删除按钮、搜索框和搜索按钮、编辑按钮添加&#x1f4d2; 运行后页面效果&#xff1a;如下 ✏️ 2. 使用添加按钮添加一条新纪录&#xff0c;逻辑点击按钮弹出带有表单的弹窗进行输入添加。…

Elasticsearch--查询(nested、join)

nested 嵌套类型 数据的某个值是json、object对象&#xff1b;不再是简单的数据类型&#xff0c;或者简单数据类型的数组&#xff1b;那么还用之前的查询方式就有问题了。因为ES在存储复杂类型的时候会把对象的复杂层次结果扁平化为一个键值对列表 。此时&#xff0c;需要用n…