从0到1学习Yalmip工具箱(2)-决策变量进阶

news2024/11/24 14:09:43

博客中所有内容均来源于自己学习过程中积累的经验以及对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));

        两种定义方式是等价的。

 

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

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

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

M + N

 

        更高维度的变量也可以采用相同的方式进行定义,例如下面的代码就是定义了一个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)

运行结果如下:

   

        优化问题求解成功后,通过使用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)

        运行结果为:

在调试代码的过程中,合理地应用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)

运行结果为:

 

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')

        运行结果为:

 

上面的代码中,变量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]))

运行结果为:

上面的结果中,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))

其运行结果为:

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))

运行结果:

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)

运行结果为:

 

3.测试题

3.1测试1

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

3.2测试2

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

表4 相关数据

小型

中型

大型

现有量

钢材/吨

1.5

3

5

600

劳动时间/小时

280

250

400

60000

利润/万元

2

3

4

3.3测试3

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

3.4测试4

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

3.5测试题参考答案

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

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

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

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

相关文章

模板方法模式:简化代码,提高复用性

在软件开发中&#xff0c;我们经常会遇到一些算法或业务流程&#xff0c;其中的步骤或顺序是固定的&#xff0c;但某些步骤的具体实现方式可能会有所不同。这时&#xff0c;模板方法模式就能派上用场。模板方法模式是一种行为设计模式&#xff0c;它定义了一个算法的骨架&#…

环肽科研试剂:161552-03-0,Cyclo(-Arg-Gly-Asp-D-Phe-Lys),IC50为0.94nM

资料编辑|陕西新研博美生物科技有限公司小编MISSwu 五元环肽Cyclo(-Arg-Gly-Asp-D-Phe-Lys) &#xff08;CAS号&#xff1a;161552-03-0&#xff09;&#xff0c;是αvβ3整联蛋白的有效和选择性抑制剂&#xff0c;IC50为0.94nM。可以高放射化学纯度&#xff08;>97&#xf…

高数笔记2(第一章函数 极限 连续-无穷小量与无穷大量)

目录 二、无穷小量与无穷大量概念 &#xff08;1&#xff09;无穷小的概念&#xff08;2&#xff09;无穷小的性质无穷个无穷小的和不是无穷小-证明无穷个无穷小量的乘积不是无穷小-证明&#xff08;没看懂&#xff09;无穷小量与有界量的乘积仍是无穷小-证明 &#xff08;3&am…

IIS部署vue项目刷新404问题

在dist目录下新建web.config文件 <?xml version"1.0" encoding"UTF-8"?> <configuration><system.webServer><rewrite><rules><rule name"Handle History Mode and custom 404/500" stopProcessing"t…

前端(六)——TypeScript在前端中的重要性与应用

&#x1f60a;博主&#xff1a;小猫娃来啦 &#x1f60a;文章核心&#xff1a;TypeScript在前端中的重要性与应用 文章目录 什么是TypeScript&#xff1f;TypeScript与JavaScript的关系如何使用TypeScriptTypeScript在前端开发中的应用场景提升开发效率减少错误和调试时间优化…

剑指offer04:在有序二维数组中查找某个数字

文章目录 一、题目描述二、解题思路与代码实现1.解题思路2.代码实现 一、题目描述 二、解题思路与代码实现 1.解题思路 方法一&#xff1a; 暴力遍历&#xff0c;可以做剪枝操作&#xff0c;如果遍历的数字大于target&#xff0c;就直接break。 方法二&#xff1a; 二分查找…

javaweb使用Thymeleaf 最凝练的CRUD项目-下

javaweb使用Thymeleaf 最凝练的CRUD项目-下 10、执行保存 ①目标 提交表单后&#xff0c;将表单数据封装为Soldier对象&#xff0c;然后将Soldier对象保存到数据库。 ②思路 ③代码 [1]Servlet方法 protected void saveSoldier(HttpServletRequest request, HttpServletR…

第三方api对接怎么做?淘宝1688api接口怎么对接?

在今天的互联网上&#xff0c;第三方API对接是必不可少的。这种技术将不同的应用程序/服务连接在一起&#xff0c;创造了无限的可能性。 第三方api对接怎么做&#xff1f; 1、与支付公司签约 首先&#xff0c;通过正规的渠道&#xff0c;如支付公司官网或正规服务商&#xf…

spring boot学习第二篇:spring boot2.6.4版本启动接口服务

1、先启动好 参考我的spring boot学习第一篇文档&#xff1a;spring boot 1.5.x版本启动接口服务_veminhe的博客-CSDN博客 需要改动2个地方 pom.xml里面 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-par…

第八章 SSD 电源管理

从 SATA 链路、PCIe 链路、NVMe 协议以及 SSD 内部主控管理等方面介绍 SSD 上的电源管理技术。 8.1 SATA 省电模式 Partial 和 Slumber PHY&#xff1a;物理层。 1. SATA 提供了两种低功耗模式&#xff0c;Partial 和 Slumber&#xff1a; &#xff08;1&#xff09; Part…

复习Javascript数组

JavaScript 数组 JS 数字属性JS 数组方法 JavaScript 数组用于在单一变量中存储多个值。 var cars ["Saab", "Volvo", "BMW"]; 什么是数组&#xff1f; 数组是一种特殊的变量&#xff0c;它能够一次存放一个以上的值。 如果您有一个项目清…

[GFCTF 2021]Baby_Web(CVE-2021-41773) 从一道题入门PHP代码审计 (保姆级)

[GFCTF 2021]Baby_Web(CVE-2021-41773) 题目标签&#xff1a;WEB、PHP、CVE-2021-41773、变量覆盖 做后考点总结&#xff1a;CVEPHP中量代码审计 CVE-2021-41773是一个Apache Httpd Server 路径穿越漏洞 详情见&#xff1a;CVE-2021-41773_Jay 17的博客-CSDN博客 在源码中…

Docker安全开放远程访问连接权限

1、Docker完全开放远程访问 Docker服务完全开放对外访问权限操作如下&#xff1a; # 开启端口命令 &#xff08;--permanent永久生效&#xff0c;没有此参数重启后失效&#xff09; firewall-cmd --zonepublic --add-port2375/tcp --permanent # 重新载入 firewall-cmd --re…

模型与计算平台

说明&#xff1a;部分内容摘自参考文献&#xff0c;如有侵权&#xff0c;联系删除 模型概念 计算量 FLOPs FLOPs&#xff1a;floating point operations 指的是浮点运算次数&#xff0c;理解为计算量&#xff0c;可以用来衡量算法/模型时间的复杂度, 单位是 FLOPs。FLOPS&…

【Arduino小车实践】陀螺仪的使用

一、MPU6050简介 MPU6050是一款陀螺仪模块&#xff0c;可以测量X、Y、Z三轴的角速度和加速度&#xff0c;还带有温度传感器和数字运动处理器(DMP)。 二、学习步骤 1. I2C协议 MPU6050是通过I2C协议进行驱动的&#xff0c;配置寄存器和获取数据都需要通过I2C协议去实现开发板与…

OpenMMLab MMTracking目标跟踪环境搭建(一)

1、环境搭建 创建conda虚拟环境并激活。 conda create -n mmtrack python3.8 -y conda activate mmtrack 按照官方说明安装 PyTorch 和 torchvision 可以通过指定版本号切换到其他版本。 #如果网不好&#xff0c;可以这样安装 pip3 install torch1.8.2cu102 torchvision0.9…

基于SpringBoot+vue的校园闲置物品租售系统设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

postman:模拟发送一个需要 cookie 认证的请求

目录 前言&#xff1a; 1、chrome 已安装插件 intercept。 2、chrome 浏览器要设置打开&#xff0c;在运行期间浏览器要一直打开。 3、本人是用 fiddler 对 app 的请求进行抓包&#xff0c;也可以使用其他工具。查看 headers 里的 cookie&#xff0c;并复制。 4、将复制的…

Ubuntu安装zsh主题

安装zsh sudo apt install zsh安装git&#xff08;如果有跳过&#xff09; sudo apt install git(1条消息) 关于Git这一篇就够了_17岁boy想当攻城狮的博客-CSDN博客 安装oh my zsh git clone https://github.com/robbyrussell/oh-my-zsh切换目录到oh-my-zsh文件夹下的tools…

0基础学习VR全景平台篇 第62篇:通用功能-通用设置

公开&#xff1a;公开表示该作品对所有人可见&#xff0c;并且会在蛙色VR平台和个人主页显示。点击公开会切换成私人模式&#xff0c;私人则表示只有作者本人可以访问&#xff0c;他人即使获取了链接也无法打开。 预览&#xff1a;点击“预览”可以查看VR视频的效果&#xff0…