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提供的函数当然是更佳的选择。

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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:RichText)

富文本组件&#xff0c;解析并显示HTML格式文本。 说明&#xff1a; 该组件从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。该组件无法根据内容自适应设置宽高属性&#xff0c;需要开发者设置显示布局。 子组件 不包含子组…

flask库

文章目录 flask库1. 基本使用2. 路由路径和路由参数3. 请求跳转和请求参数4. 模板渲染1. 模板变量2. 过滤器3. 测试器 5. 钩子函数与响应对象 flask库 flask是python编写的轻量级框架&#xff0c;提供Werkzeug&#xff08;WSGI工具集&#xff09;和jinjia2&#xff08;渲染模板…

JMH287亲测【鸣潮】一键内测风景端V1.0.2已整理并录制视频教学

资源介绍&#xff1a; 否需要虚拟机&#xff1a;否 文件大小&#xff1a;压缩包约15G 支持系统&#xff1a;win7、win10、win11 硬件需求&#xff1a;运行内存16G 4核及以上CPU独立显卡 资源截图&#xff1a; 下载地址&#xff1a; JMH287【鸣潮】一键端 [V1.0.2]

MySql入门教程--MySQL数据库基础操作

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

精读《精通 console.log》

1 引言 本周精读的文章是 Mastering JS console.log like a Pro&#xff0c;一起来更全面的认识 console 吧&#xff01; 2 概述 & 精读 console 的功能主要在于控制台打印&#xff0c;它可以打印任何字符、对象、甚至 DOM 元素和系统信息&#xff0c;下面一一介绍。 c…

Linux 中搭建 主从dns域名解析服务器

CSDN 成就一亿技术人&#xff01; 作者主页&#xff1a;点击&#xff01; Linux专栏&#xff1a;点击&#xff01; CSDN 成就一亿技术人&#xff01; ————前言———— 主从&#xff08;Master-Slave&#xff09;DNS架构是一种用于提高DNS系统可靠性和性能的配置方式。…

以题为例浅谈文件包含

什么叫做文件包含 文件包含函数加载的参数没有经过过滤或严格定义&#xff0c;可以被用户控制&#xff0c; 包含其他恶意文件&#xff0c;导致了执行非预期代码。 文件包含漏洞&#xff08;File Inclusion Vulnerability&#xff09;是一种常见的网络安全漏洞&#xff0c;它允…

相机拍照与摄影学基础

1.相机拍照 相机可能形状和大小不同&#xff0c;但基本功能相同&#xff0c;包括快门速度、光圈和感光度&#xff0c;这些是摄影的通用概念。即使是一次性相机也是基于这三个理念工作的。不同类型相机在这三个概念上的唯一区别是你可以控制这些功能的程度。这三个参数被称为相…

动态库和静态库的新理解

旧理解(当初理解较浅&#xff0c;今再看到有新发现) 链接&#xff1a; 静态链接库和动态链接库区别_动态链接库和静态链接库的区别-CSDN博客 由于本人不是做架构方面&#xff0c;给大佬打螺丝。长时间的惯性思维就是要使用其他项目的类或者函数&#xff0c;先导出成dll。然后…

计算机设计大赛 题目:基于大数据的用户画像分析系统 数据分析 开题

文章目录 1 前言2 用户画像分析概述2.1 用户画像构建的相关技术2.2 标签体系2.3 标签优先级 3 实站 - 百货商场用户画像描述与价值分析3.1 数据格式3.2 数据预处理3.3 会员年龄构成3.4 订单占比 消费画像3.5 季度偏好画像3.6 会员用户画像与特征3.6.1 构建会员用户业务特征标签…

基于Python django的人脸识别门禁系统,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、Python技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&…

DC-DC电源管理芯片MC34063A介绍

MC34063A 为一单片 DC-DC 变换集成电路&#xff0c;内含温度补偿的参考电压源&#xff08;1.25V&#xff09;、比较器、能有效限制电流及控制工作周期的振荡器&#xff0c;驱动器及大电流输出开关管等。外配少量元件&#xff0c;就能组成升压、降压及电压反转型 DC-DC 变换器。…