GUROBI建模之非线性约束的处理

官方文档

目录

官方文档:GRBModel.AddGenConstrXxx() - Gurobi Optimization

数学规划的约束类型

基本约束(fundamental constraints):

通用约束(general constraints):

1. GUROBI求解器有针对这类约束的函数,直接调用这类函数即可

2. 自己对这类约束进行数学形式转化


官方文档

数学规划的约束类型

       数学规划的约束可以分为线性约束非线性约束两大类,对于线性约束可以很好地处理,而对于非线性约束,则需要使用一些特殊的方法来转化为线性约束才能被处理。

基本约束(fundamental constraints):

上下界约束(variable bound constraints)、线性约束(linear constraints)、二次约束(quadratic constraints)、整数约束(intergrality constraints)、SOS约束等,这些类型的约束是可以被GUROBI的底层算法直接处理的。

补充一下什么是SOS约束:SOS - Gurobi Optimization

       简言之:type1型的SOS约束就是一组变量中最多只有一个变量可以取非0值;type2型的SOS约束就是一组有序变量中最多只有两个变量可以取非0值,如果有两个非零变量的话,这两个变量必须是位置连续的。

通用约束(general constraints):

在实际建模的时候,约束类型经常不局限于以上几种基本类型,比如最大最小约束、绝对值约束、函数约束(指数函数、对数函数、幂函数等等),这种约束我们称为genaral constraints

在解决实际问题时,如果遇到了这类约束,我们可以使用以下两种方法来解决:

1. GUROBI求解器有针对这类约束的函数,直接调用这类函数即可

那么这些函数背后的底层逻辑又是如何处理genaral constraints 的呢?

其实,这类求解器也不能直接处理这类约束,只是在预处理阶段(presolve)阶段,求解器会将这类约束转化为由fundamental constraints组成的简单约束,通过直接处理fundamental constraints来间接处理genaral constarints。

那么这种转化是等价的吗?(好问题)

大多数情况下,这种转化在数学上是等价的;但有时候,无法等价转化,只能近似;这取决于general constarints的具体形式。后面再解释一下。

那么具体如何实现呢?

(1)一种是直接使用GUROBI的专有函数Model.addGenConstrXxx(),如下:

(2)一种是使用Model.addConstr或者Model.addConstrs(搭配genaral constraints辅助函数和loaded operates一起),如下:

两种方法的实现代码如下:(x和y是决策变量,其他的均为需要输入的常量)

addGenConstrMax:  y = max(x_{1}, x_{2}, ..., c)

Model.addGenConstrMax() - Gurobi Optimization

#  y = max(x1, x3, x4, 2.0)
# addGenConstrXXX
addGenConstrMax ( resvar, vars, constant=None, name="" )
model.addGenConstrMax(y, [x1, x3, x4], 2.0, "maxconstr")

# overloaded forms
model.addConstr(y == max_([x1, x3, x4], constant = 2.0), name = "maxconstr")
model.addConstr(y == max_(x1, x3, x4, constant = 2.0), name = "maxconstr")

addGenConstrMiny =min(x_{1}, x_{2},..., c)

Model.addGenConstrMin() - Gurobi Optimization

# y = min(x1, x3, x4, 2.0)
model.addGenConstrMin(y, [x1, x3, x4], 2.0, name="minconstr")

model.addConstr(y == min_([x1, x3, x4], constant = 2.0), name = "minconstr")
model.addConstr(y== min_(x1, x3, x4, constant = 2.0), name ="minconstr")

addGenConstrAbsy = \left | x \right |

Model.addGenConstrAbs() - Gurobi Optimization

# y = |x1|
model.addGenConstrAbs(y, x1, name = "absconstr")

model.addConstr(y == abs_(x1), name = "absconstr")

addGenConstrAndy = x_{1} \wedge x_{2}\wedge x_{3}\wedge...

Model.addGenConstrAnd() - Gurobi Optimization

# y = and(x1, x3, x4)
model.addGenConstrAnd(y, [x1, x3, x4], name = "addconstr")

model.addConstr(y == and_([x1, x3, x4]), name ="addconstr")
model.addConstr(y == and_(x1, x3, x4), name = "addconstr")

addGenConstrOry = x_{1}\vee x_{2} \vee x_{3} \vee...

Model.addGenConstrOr() - Gurobi Optimization

 # y = or(x1, x3, x4)
model.addGenConstrOr(y, [x1, x3, x4], name = "orconstr")

model.addConstr(y == or_([x1, x3, x4]), name = "orconstr")
model.addConstr(y == or_(x1, x3, x4), name = "orconstr")

addGenConstrNormy = norm(x_{1}, x_{2}, x_{3},...)

Model.addGenConstrNorm() - Gurobi Optimization

# y = 2-norm(x1, x3, x4)
model.addGenConstrNorm(y, [x1, x3, x4], 2, "normconstr") # 0\1\2范数

addGenConstrIndicatory = 1 \rightarrow a{}'x<=b

Model.addGenConstrIndicator() - Gurobi Optimization

# y = 1 ——》 x1 + 2x3 + x4 =1
model.addGenConstrIndicator(y, True, x1 + 2*x3 + x4, GRB.EQUAL, 1.0)
# 或者
model.addGenConstrIndicator(y, True, x1 + 2*x3 + x4 == 1.0)


model.Constr((x == 1) >> (x1 + 2*x3 + x4 == 1.0))

addGenConstrPwly = pwl(x)

分段线性函数线性化

Model.addGenConstrPWL() - Gurobi Optimization

model.addGenConstrPWL(x, y, [0, 1, 2], [1.5, 0, 3])
# 分段点:(0,1.5)、(1,0)、(2,3)

addGenConstrPolyy = p_{0}x^{d} + p_{1}x^{d-1} + p_{2}x^{d-2} + p_{d-1}x + p_{d}

Model.addGenConstrPoly() - Gurobi Optimization

# y = 2 x^3 + 1.5 x^2 + 1
model.addGenConstrPoly(x, y, [2, 1.5, 0, 1])

addGenConstrExpy = e^{x}

Model.addGenConstrExp() - Gurobi Optimization

# y = exp(x)
nodel.addGenConstrExp(x, y)

addGenConstrExpAy = a^{x}

Model.addGenConstrExpA() - Gurobi Optimization

 # y = 3^x
model.addGenConstrExpA(x, y, 3.0)

addGenConstrLogy = lnx

Model.addGenConstrLog() - Gurobi Optimization

# y = ln(x)
model.addGenConstrLog(x, y)

addGenConstrLogAy = log_{a}x

Model.addGenConstrLogA() - Gurobi Optimization

 # y = log2(x)
 model.addGenConstrLogA(x, y, 2)

addGenConstrLogisticy = \frac{1}{1+e^{-x}}

Model.addGenConstrLogistic() - Gurobi Optimization

model.addGenConstrLogistic(x, y)

addGenConstrPowy = x^{a}

Model.addGenConstrPow() - Gurobi Optimization

# y = x^3.5
model.addGenConstrPow(x, y, 3.5)

addGenConstrSiny = sin(x)

model.addGenConstrSin(x, y)

addGenConstrCosy = cos(x)

Model.addGenConstrSin() - Gurobi Optimization

addGenConstrTany = tan(x)

从上面我们可以发现: general constraints可以分为两类

simple constraints: max、min、abs 、and 、or、norm、indicatior、precewise-linear,ect

这类简单约束可以通过引入隐式辅助变量、线性约束、SOS约束来处理(线性化),例如:

function constraintsy = f(x)

这类约束更加复杂,无法像simple constraints那样来处理,目前最有效的方式是通过线性分段函数来近似逼近这些非线性函数,而这种近似线性化又有静态处理和动态处理两种方式,可以用户自行设置:

当然啦,这些处理都是求解器自己在背后处理的!

还有一个问题,既然是近似,那么就有可能存在偏差,GUROBI提供了一系列参数供用户设置根据自己的模型来尽可能的控制这个偏差;并且,这种近似所造成的violation依然是在feasiblity tolerance内的,也就是说这种近似依然可以保证满足原始约束的。

2. 自己对这类约束进行数学形式转化

     对于min、max、abs 、and 、or、indicator等,通过引入辅助变量和大M等,在数学形式都是可以将其转化为线性表达式的(无论是在目标函数中还是在约束条件中),所以可以自己在建模时直接将这类约束建模为线性约束(可以看成是做了求解器在背后做的事情),当然这种方法需要掌握一定的建模技巧,后面有需要会专门来总结一下。但是,如果只是为了解决实际问题,直接使用GUROBI提供的函数当然是更佳的选择。

留坑再次,下次总结一下线性化建模的技巧!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python-GIS分析之地理数据空间聚类

地理空间数据聚类是空间分析和地理信息系统(GIS)领域的一项关键技术。这种方法对于理解地理数据固有的空间模式和结构、促进城市规划、环境管理、交通和公共卫生等各个领域的决策过程至关重要。本文探讨了地理空间数据聚类的概念、方法、应用、挑战和未来方向。 当模式出现…

音频切割如何操作?剪辑音乐入门教程

随着数字音乐时代的来临&#xff0c;音频编辑和音乐剪辑成为了越来越多人的必备技能。无论是想要制作个人音乐作品&#xff0c;还是想要为视频添加背景音乐&#xff0c;了解如何切割和剪辑音频都是非常重要的。本文将为你提供一份音频切割和音乐剪辑的入门教程&#xff0c;帮助…

13-操作符(初识)

课前小技巧&#xff1a;VS中&#xff0c;想要复制哪一行&#xff0c;直接把鼠标放在哪一行&#xff0c;CtrlC即可&#xff0c;CtrlV直接自动复制到下一行 C语言非常灵活&#xff1a;C语言提供了非常丰富的操作符&#xff0c;使用起来比较灵活 13-1 算术操作符 - * / % 这…

WXML 模板语法

数据绑定 1. 数据绑定的基本原则 ① 在 data 中定义数据 在页面对应的 .js 文件中&#xff0c;把数据定义到 data 对象中即可 ② 在 WXML 中使用数据 2. Mustache 语法的格式 把 data 中的数据绑定到页面中渲染&#xff0c;使用 Mustache 语法&#xff08;双大括号&#x…

快速了解JavaScript

1.1 javaScript 历史 创始人 布兰登 艾奇 生于1961年 在1995设计LiveScript后改名为JavaScript 1.2 javaScript 是什么类型的语言 JavaScript是一种在客户端运行的脚本语言&#xff08;不需要编译&#xff0c;由js引擎逐行解释执行&#xff09; 1.3 JavaScript可以做什么 …

ts版本微信小程序在wxml保存文件不刷新页面的解决办法

将project.config.json中的skylineRenderEnable改为false "skylineRenderEnable": false

【理解机器学习算法】之岭回归Ridge - L2 Rgularization

Ridge 回归&#xff08;Ridge Regression&#xff09;也称作岭回归或脊回归&#xff0c;是一种专用于共线性数据分析的有偏估计回归方法。在多元线性回归中&#xff0c;如果数据集中的特征&#xff08;自变量&#xff09;高度相关&#xff0c;也就是说存在共线性(Multicollinea…

Kotlin 中List,Set,Map的创建与使用

目录 1. List 的使用 1.1 不可变 List 1.2 可变 List 2. Set 的使用 2.1 不可变 Set 2.2 可变 Set 3. Map 的使用 3.1 不可变Map 3.2 可变Map 本篇主要为已经有Java基础的同学展示Kotlin语言中的List&#xff0c;Set&#xff0c;Map的创建和使用&#xff0c;所以Java代…

STM32CubeMX与HAL库开发教程八(串口应用/轮询/中断/DMA/不定长数据收发)

目录 前言 初识串口-轮询模式 串口中断模式收发 串口DMA模式 蓝牙模块与数据包解析 前言 前面我们简单介绍过串口的原理和初步的使用方式&#xff0c;例如怎么配置和简单的收发&#xff0c;同时我们对串口有了一个初步的了解&#xff0c;这里我们来深入的来使用一下串口 …

基于高德地图JS API实现Vue地图选点组件

基于高德地图JS API2.0实现一个搜索选择地点后返回给父组件位置信息的功能&#xff0c;同时可以进行回显 目录 1 创建key和秘钥1.1 登录高德地图开放平台1.2 创建应用1.3 绑定服务创建秘钥 2 使用组件前准备2.1 导入loader2.2 在对应的组件设置秘钥2.3 引入css样式 3 功能实现…

记录dockers中Ubuntu安装python3.11

参考&#xff1a; docker-ubuntu 安装python3.8,pip3_dockerfile ubuntu22 python3.8-CSDN博客

揭示数据在内存中存储的秘密!

** ** 悟已往之不谏&#xff0c;知来者犹可追 ** ** 创作不易&#xff0c;宝子们&#xff01;如果这篇文章对你们有帮助的话&#xff0c;别忘了给个免费的赞哟~ 整数在内存中的存储 整数的表达方式有三种&#xff1a;原码、反码、补码。 三种表示方法均有符号位和数值位两部分…

Oracle数据库:使用 bash脚本 + 定时任务 自动备份数据

Oracle数据库&#xff1a;使用 bash脚本 定时任务 自动备份数据 1、前言2、为什么需要自动化备份&#xff1f;3、编写备份脚本4、备份脚本授权5、添加定时任务6、重启 crond / 检查 crond 服务状态7、备份文件检查 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收…

matlab 平面桁架有限元受力分析计算

1、内容简介 略 62-可以交流、咨询、答疑 平面桁架有限元受力分析计算 2、内容说明 略 3、仿真分析 略 4、参考论文 略

宿主环境

1. 什么是宿主环境 宿主环境&#xff08; host environment &#xff09;指的是程序运行所必须的依赖环境。例如&#xff1a; Android 系统和 iOS 系统是两个不同的宿主环境。安卓版的微信 App 是不能在 iOS 环境下运行的&#xff0c;所以&#xff0c; Android 是安卓软件的宿…

“import ... =“ 只能在 TypeScript 文件中使用

当你遇到这个问题很苦恼。 可以按照以下解决办法 使用ctrlshiftP 修改"javascript.validate.enable": false

php中 0 == ‘’(0等于任意字符串) 判断是否成立 返回true

php中不同类型变量之间比较大小 一、背景二、探究0是为什么&#xff1f;三、探究 0all是为什么&#xff1f;四、程序中如何判断0是否等于指定字符串 一、背景 最近在项目实际开发中&#xff0c;我需要判断前端传来的参数值是否等于一个字符串&#xff1b;然后发现当参数值是0时…

MATLAB学习笔记(二)PDE求解偏微分方程组

一、利用PDE求解偏微分方程组 初值为&#xff1a; 针对上述方程组&#xff0c;利用matlab自带工具箱和函数PDE进行求解。 以下是matlab中对工具箱中pdepe函数的解释。 二、matlab编程 在matlab中编程&#xff0c;利用PDE函数求解以上偏微分方程。 clc; clear; syms y global …

【蓝桥杯单片机】十三届省赛“重难点”解析(附源码)

【蓝桥杯单片机】十三届省赛“重难点”解析 一、题目难点解析二、易出错点提示三、完整代码链接 笔记包括&#xff1a;①题目难点解析、②易出错点提示、③完整代码链接 注&#xff1a;本文提供的所有代码都是使用第十四届竞赛包完成 ⭐----------系列文章链接----------⭐ 【蓝…

Java初阶数据结构二叉树实现+练习完整(工程文件后序会进行上传)

i1.二叉树的概念 1.二叉树的定义 &#xff08;1&#xff09;二叉树可以是一个节点的有限集合 &#xff08;2&#xff09;可以为空 &#xff08;3&#xff09;或者是由一个根节点加上两棵分别称为左子树和右子树的二叉树组成的 &#xff08;4&#xff09;二叉树的每一个节点…