Yalmip使用教程(6)-将约束条件写成矩阵形式

news2025/1/12 22:49:23

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

        这篇博客将详细介绍如何借助yalmip工具箱将约束条件写成矩阵形式。

1.相关函数介绍

1.1 depends和getvariables函数

        depends和getvariables函数都可用于求出sdpvar类型变量在Yalmip工具箱内部的索引(可以简单理解为该变量是第几个使用的变量,比如索引为3,表示为第3个使用的变量),两个函数的使用语法分别为:

k = depends(x)
k = getvariables(x)

        其中,x为sdpvar类型变量,k为变量的索引。

        对于线性变量来说,两者的返回结果完全相同,例如下面的代码:

        例1:对线性变量使用depends和getvariables函数

yalmip('clear')
x = sdpvar(1);
y = sdpvar(2,3);
x_index1 = getvariables(x)
y_index1 = getvariables(y)
x_index2 = depends(x)
y_index2 = depends(y)

        运行结果为:

        两个函数的区别在于非线性的变量。对于非线性变量,depends函数只会返回其中涉及的线性变量,而getvariables函数则将直接返回非线性变量的索引。下面是一个例子:

        例2:对非线性变量使用depends和getvariables函数

yalmip('clear')
x = sdpvar(1);
z = x^2;
z_index1 = getvariables(z)
z_index2 = depends(z)

        运行结果为:

        上面的代码中涉及到1个线性变量x和一个非线性变量z,其中x的索引为1,z的索引为2。从结果中可以看到,getvariables函数将直接返回非线性变量z的索引,而depends函数只会输出非线性变量z中涉及到的线性变量x的索引。

1.2 getbase函数

        getbase函数将返回sdpvar类型变量中的full basis(我将其理解为变量的系数矩阵),使用语法如下:

B = getbase(x);

        其中x表示sdpvar类型的变量,B表示所涉及基本变量(也就是Yalmip内部中分配了索引号的1维变量)的系数矩阵。光看这个函数的文字描述也是比较难理解它的作用,我们还是结合一个实例进行讲解。

例3:

yalmip('clear')
x = sdpvar(1);
y = sdpvar(1);
z = [1;2*x;3*y;4*x+5*y + 6*x^2];
full(getbase(z))

        运行结果为:

ans =
     1     0     0     0
     0     2     0     0
     0     0     3     0
     0     4     5     6

        首先我们可以知道,变量z为4×1的矩阵形式,其中共涉及3个基本变量,x,y和x²。那么我们可以把变量z用这三个基本变量进行表达,也就是:

        对于上面的例子来说:

        也就是系数矩阵为:

从分析结果可知,getbase函数所返回的就是所涉及基本变量的系数矩阵。

1.3 getbasematrix函数

        getbasematrix函数将返回sdpvar类型变量中指定基本变量的系数矩阵,使用语法如下:

B = getbasematrix(x,index)

        其中x表示sdpvar类型的变量,index表示指定的基本变量索引,B表示所涉及基本变量(也就是Yalmip内部中分配了索引号的1维变量)的系数矩阵。

        如果理解了getbase函数的用法,那么getbasematrix函数也就不难理解,无非是将返回所有涉及的基本变量系数矩阵变成了指定基本变量的系数矩阵。下面是一个示例:

        例4:

yalmip('clear')
x = sdpvar(1);
y = sdpvar(1);
z = [1;2*x;3*y;4*x+5*y + 6*x^2];
xB = full(getbasematrix(z,1))
yB = full(getbasematrix(z,2))

        运行结果如下:

1.4 recover函数

        recover函数通过索引来创建变量,标准语法如下:

x = recover(index)

        其中index表示变量索引,x表示所创建的变量。

        从本质上来讲,recover和getvariables函数是一个逆运算,即recover函数的输入是getvariables函数的输出,recover函数的输出是getvariables函数的输入。下面的代码说明了这一点:

yalmip('clear')
x = sdpvar(1);
assign(x,2);
x_index = getvariables(x);
x1 = recover(x_index);
x_value = value(x)
x1_value = value(x1)

        运行结果如下:

        从结果上来看,我们首先使用getvariables函数获取了变量x的索引,再利用recover函数,通过索引得到变量x1。由于我们提前使用了assign函数给变量x赋值为2,因此变量x的取值为2。但我们并没有给变量x1赋初值,但结果显示变量x1的取值也为2,说明变量x和变量x1本质上是同一个变量。也就是说通过recover函数和变量的索引号得到的新变量,和原变量是完全等价的。

1.5 see函数

        see函数在命令行返回sdpvar类型变量中所涉及基本变量的索引、常数矩阵和基本变量的系数矩阵,语法如下:

see(x)

        下面是一个例子:

        例5:

yalmip('clear')
x = sdpvar(1);
y = sdpvar(1);
z = [1;2*x;3*y;4*x+5*y + 6*x^2];
see(z)

        运行结果如下:

该结果和getvariables、getbase等函数返回结果的含义相同,此处不再赘述。

2.将优化问题改写为矩阵形式

        我们知道,在线性规划中一个变量对应优化问题中的一列,一个约束条件对应优化问题中的一行。对于有N个变量和M条约束的线性规划问题,那约束矩阵就有M行N列。我们可以将每一条约束都改写成≤0或≥0的形式,并使用一个中间变量表示这条约束,再通过上述函数确定中间变量所涉及的基本变量索引与系数矩阵,就可以间接表示出约束矩阵,进一步将优化问题改写为矩阵形式。

        下面通过1个实际例子进行说明。

        例6:

        假设我们想把上面的优化问题写成紧凑的矩阵形式:

        求矩阵A、b、c,然后使用矩阵形式求解优化问题的代码如下:

clc
clear
close all
warning off
yalmip('clear')
 
%% 决策变量
sdpvar x1 x2
 
%% 求系数矩阵
obj0 = x1 + 2*x2;
 
z = [-2*x1 + 3*x2 - 12 ;
    x1 + x2 - 14;
    -3*x1 + x2 + 3;
    3*x1 + x2 - 30];
 
M1 = full(getbase(z));
M2 = full(getbase(obj0));
index = depends([x1 x2]);
A = M1(:,index + 1);
b = -M1(:,1);
c = M2(index + 1)';
 
%% 矩阵形式的目标函数
x = [x1;x2];
obj = c'*x;
C = [A*x <= b , x >= 0];
 
%% 求解优化问题
ops = sdpsettings('verbose', 3, 'solver', 'gurobi');
sol = optimize(C , -obj ,ops);
 
%% 判断求解是否成功
if sol.problem == 0
    disp('求解成功!!!');
    x = value(x)
else
    disp(['求解失败,原因为',sol.info]);
end

        运行结果如下:

        上面的例子是一个简单的线性规划问题,直接写出约束矩阵也很容易,采用Yalmip函数反而多此一举。但是实际问题通常涉及0-1变量,多重下标,需要用循环语句表达约束等等,手动写系数矩阵非常麻烦且容易出错,借助Yalmip的相关函数将会简单很多。

3.测试题

3.1测试1

        将下列优化问题建模为混合整数线性规划问题,并利用Yalmip函数改写为矩阵形式:

3.2测试2

        其中数据为:

        请将上述优化问题改写为下面的矩阵形式,并使用矩阵形式进行求解:

3.3测试3

        将旅行商问题(TravelingSalesmanProblem,TSP)的0-1规划模型改写成矩阵形式并进行求解:

3.4测试题参考答案

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

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

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

相关文章

C# Winform 简单排期实现(DevExpress TreeList)

排期的需求在很多任务安排的系统中都有相应的需求&#xff0c;原生的Winform控件并未提供相应的控件&#xff0c;一般都是利用DataGridViewTreeView组合完成相应的需求&#xff0c;实现起来比较麻烦。用过DevExpress控件集的开发者应该知道&#xff0c;DevExpress WinForm提供了…

数学建模--K-means聚类的Python实现

目录 1.算法流程简介 2.1.K-mean算法核心代码 2.2.K-mean算法效果展示 3.1.肘部法算法核心代码 3.2.肘部法算法效果展示 1.算法流程简介 #k-means聚类方法 """ k-means聚类算法流程: 1.K-mean均值聚类的方法就是先随机选择k个对象作为初始聚类中心. 2.这…

http实现文件分片下载

文章目录 检测是否支持HTTP Range 语法Range请求cURL示例单一范围多重范围条件式分片请求 Range分片请求的响应文件整体下载文件分片下载文本下载图片下载封装下载方法 HTTP分片异步下载是一种下载文件的技术&#xff0c;它允许将一个大文件分成多个小块&#xff08;分片&#…

一个新工具 nolyfill

名字的意思&#xff0c; 我自己的理解 no(po)lyfill 正如它的名字, 不要再用补丁了, 当然这里说的是过时的补丁。 polyfill 是补丁的意思 为什么要用这个插件 文档原文: 当您通过安装最新的 Node.js LTS 来接受最新的功能和安全修复时&#xff0c;像eslint-plugin-import、…

架构师如何做好需求分析

架构师如何做好需求分析 目录概述需求&#xff1a; 设计思路实现思路分析1.主要步骤 2.主要步骤2操作步骤 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result,…

Android笔记(二十八):在雷电模拟器安卓7.0+上使用Charles抓包详细教程

背景 由于手头没有合适的真机,所有经常使用雷神模拟器来跑项目,模拟器也需要能够抓包看看接口返回的数据,以便自测调试。本文记录了如何在雷电模拟器安卓7.0+上使用Charles抓包,其他模拟器没试过。 最终效果 浏览器打开百度网页,能抓到百度页面数据 具体步骤 模拟器…

xinput1_3.dll丢失的解决方法,快速修复xinput1_3.dll文件

在使用电脑时&#xff0c;我们可能会遇到各种各样的问题&#xff0c;其中之一就是xinput1_3.dll文件丢失的情况。这个文件是DirectX的一部分&#xff0c;它对于许多游戏和其他应用程序的正常运行至关重要。当xinput1_3.dll文件丢失时&#xff0c;我们无法启动或运行依赖该文件的…

LeetCode刷题笔记【28】:贪心算法专题-6(单调递增的数字、监控二叉树)

文章目录 前置知识738.单调递增的数字题目描述解题思路代码 968.监控二叉树题目描述解题思路代码 总结 前置知识 参考前文 参考文章&#xff1a; LeetCode刷题笔记【23】&#xff1a;贪心算法专题-1&#xff08;分发饼干、摆动序列、最大子序和&#xff09; LeetCode刷题笔记【…

VMware虚拟机+Centos7 配置静态,动态IP

本章目录 一、查看网关&#xff1a; 编辑–>虚拟网络编辑器二、点击NAT设置三、记住网关IP待会要用四、配置静态ip地址1、进入存放修改IP地址的目录2、修改ip地址的文件3、编辑文件4、文件&#xff08;编辑好后退出&#xff09; 五、重启网络六、测试1、linux上查看IP地址的…

使用pyenv安装python缓慢或无法安装

使用pyenv安装python缓慢或无法安装 这一定程度上和网络情况有关&#xff0c;下面提供几个常见方法&#xff1a; 关闭 VPN 后重新安装使用管理员权限打开命令窗口后安装如下 手动安装 pyenv 在执行 pyenv install --- 命令的时候&#xff0c;会连接远程库&#xff0c;将要安…

格式工厂多个图片合并成一个PDF的报错

使用图片合并PDF功能时 当图片数量超过50会报错 找到imgconv.py文件&#xff0c;将50改为500&#xff0c;保存 现在可以支持100张图合并成一个PDF文件了&#xff01; 但是超过150张程序会直接闪退&#xff0c;正在解决中。。

基于任务队列的机器学习服务实现

将机器模型部署到生产环境的方法有很多。 常见的方法之一是将其实现为 Web 服务。 最流行的类型是 REST API。 它的作用是全天候&#xff08;24/7&#xff09;部署和运行&#xff0c;等待接收来自客户端的 JSON 请求&#xff0c;提取输入&#xff0c;并将其发送到 ML 模型以预测…

3D异常检测论文笔记 | Shape-Guided Dual-Memory Learning for 3D Anomaly Detection

文章目录 摘要一、介绍三、方法3.1. 形状引导专家学习3.2. Shape-Guided推理 摘要 我们提出了一个形状引导的专家学习框架来解决无监督的三维异常检测问题。我们的方法是建立在两个专门的专家模型的有效性和他们的协同从颜色和形状模态定位异常区域。第一个专家利用几何信息通…

涛然自得周刊(第 5 期):蝲蛄吟唱的地方

作者&#xff1a;何一涛 日期&#xff1a;2023 年 8 月 20 日 涛然自得周刊主要精选作者阅读过的书影音内容&#xff0c;不定期发。历史周刊内容可以看这里。 电影 《沼泽深处的女孩》 改编自小说《蝲蛄吟唱的地方》&#xff0c;主角是一位在沼泽地独自生活并长大的女孩&…

[VSCode] 替换掉/去掉空行

VSCode中使用快捷键CtrlH&#xff0c;出现替换功能&#xff0c;在上面的“查找”框中输入正则表达式&#xff1a; ^\s*(?\r?$)\n然后选择右侧的“使用正则表达式”&#xff1b;“替换”框内为空&#xff0c;点击右侧的“全部替换”&#xff0c;即可去除所有空行。 参考 [VS…

Apipost forEach控制器怎么用

最近&#xff0c;Apipost对自动化测试进行了优化&#xff0c;新增foreach控制器。这个新功能的引入为自动化测试带来了更高的效率和灵活性。本文将介绍Apipost的foreach控制器&#xff0c;解释其用途和优势&#xff0c;帮助您更好地利用这一功能提升自己的测试工作。 什么是fo…

Andorid项目源码(167套)

一、项目介绍 (精华)新浪微博图片缓冲技术_hyg.rar ActivityGroup GridView ViewFlipper 实现选项卡.zip Adroid UI 界面绘制原理分析.rar AnderWeb-android_packages_apps_Launcher-4458ee4.zip andorid 源码北京公交线路查询&#xff08;离线&#xff09;.zip android Gal…

【Java 基础篇】Java Date 类详解:日期和时间操作的利器

在 Java 编程中&#xff0c;处理日期和时间是一项常见但复杂的任务。Java 提供了许多用于日期和时间操作的类&#xff0c;其中 java.util.Date 类是最早的日期和时间类之一。然而&#xff0c;它存在一些问题&#xff0c;因此 Java 8 引入了 java.time 包&#xff0c;其中包含了…

宇凡微发布2.4G合封芯片YE08,融合高性能MCU与射频收发功能

宇凡微在2023年推出了全新的2.4G合封芯片YE08&#xff0c;该芯片结合了32位高性能MCU和强大的2.4GHz无线通信功能&#xff0c;为各种远程遥控应用提供卓越性能和广泛应用潜力。 深入了解YE08内部构造 YE08芯片内部融合了两颗强大的芯片&#xff1a;PY32F002B MCU和G350 2.4G通…

基于神经网络结合紫外差分光谱的二氧化硫浓度定量预测

基于神经网络结合紫外差分光谱的二氧化硫浓度定量预测 前言一、代码运行1. 解压数据2. 导包3. 读取数据4. 构建网络5. 设置优化器6. 模型训练7. 可视化loss8. 模型验证 二、结果展示三、总结作者简介 前言 二氧化硫&#xff08;SO2&#xff09;是一种常见的环境污染物&#xff…