Operations Research课程之非线性规划(梯度下降|牛顿法|Gurobi+Python)

目录

1.非线性规划介绍

2.梯度下降法(Gradient descent)

2.1 梯度和Hessians矩阵

2.2 梯度下降算法

2.3 算法举例

3. 牛顿法(Newton’s method)

3.1 适合单变量的牛顿法

3.2 适合多变量的牛顿法

3. 实例(Gurobi+Python)

3.1 Agricultural Pricing问题描述

3.2 Gurobi+Python代码


来源:Coursera课程Operations Research (2): Optimization Algorithms Week4

课程前言:

怎么求解一个有数千个变量和约束的问题?为什么求解整数规划比线性规划需要更多时间?为什么线性化很重要,为什么不直接把问题建模成非线性规划模型?

(1)精确解

  • 线性规划:单纯形法
  • 整数规划:分枝定界
  • 非线性规划✅:梯度下降和牛顿法

(2)启发式解

很多场景下建立数学模型再调用求解器是不够的,现实问题非常复杂,我们还需要为特定的问题设计特定的算法,许多情况下会使用启发式算法,能在合理的时间内找到近似最优

1.非线性规划介绍

很多现实的工程问题都是非线性的,需要依赖数值算法获得一个数值解,非线性规划(NLP)算法通常有以下步骤:

  • 迭代(Iterative):算法会在某次迭代中移动到一个点,然后从这个点开始下一次迭代
  • 重复(Repetitive):每次迭代会重复一些步骤
  • 贪婪(Greedy):每次迭代会寻找当前迭代轮次中最好的那个
  • 近似(Approximation):依赖原始问题的一阶或二阶近似

NLP算法有一些难点:

  • NLP算法可能无法收敛: 如果更多的迭代不能改进修正当前解,算法会收敛至这个解,有些情况下算法也会根本无法收敛
  • NLP算法可能陷入局部最优:迭代开始点非常重要,算法会采取一些方法得到多个局部解
  • NLP算法需要域是连续且连通的:非线性整数规划比较难求解

下面介绍两种简单的NLP算法:梯度下降和牛顿法,主要求解无约束非线性优化问题,对于带约束的优化问题,需要结合使用其它方法,如拉格朗日乘子,罚函数,序列二次规划,内点法等。

2.梯度下降法(Gradient descent)

2.1 梯度和Hessians矩阵

举例说明计算过程:

 梯度是一个N维向量,可以通过朝着这个方向移动来改善当前解,梯度是最快的上升方向

2.2 梯度下降算法

由于梯度是上升方向,对于最小化问题需要沿着其反方向移动,给定一个当前解x,在每次迭代更新公式为x-a\triangledown f(x),其中a>0,称为步长(step size),和深度学习里的学习率概念类似,当前解的梯度为0时停止迭代。怎么选择合适的步长?一个不合适的步长可能会导致算法不收敛,以下面的为例

为了找到最合适的步长,需要在每次梯度更新前引入一个子问题:最大程度的改进(largest improvement),即沿着当前方向能到达的最优的点

梯度下降的每次迭代没有局限在可行域,可能会跳出可行域然后移动回来,搜索速度会更快

2.3 算法举例

以包含两个变量的函数为例,下面是迭代两次的过程,在求解步长时,由于自变量已知,因此子问题只有步长一个变量,便于求解。

3. 牛顿法(Newton’s method)

梯度下降法是一种一阶方法,比较直观,但是有时会比较慢,牛顿法依赖二阶梯度(Hessians矩阵)来求解,速度更快。

3.1 适合单变量的牛顿法

 以EOQ库存控制模型为例说明过程

3.2 适合多变量的牛顿法

与单变量牛顿法一样,只是梯度从单变量梯度变成了Hessians矩阵,每次迭代更新向量如下:

 对于牛顿法:

  • 牛顿法没有梯度下降法中的步长
  • 对于二次函数,能在一次迭代中就找到最优解
  • 在某些情况下比梯度下降法更快
  • 对于某些函数也会难以收敛,比如非凸函数
  • 梯度下降的单次迭代一定是更好的方法,而牛顿法取决于函数性质

还有一些更通性的问题:

  • 收敛保证
  • 收敛速度
  • 不可导函数
  • 约束优化

3. 实例(Gurobi+Python)

3.1 Agricultural Pricing问题描述

来自Gurobi官方案例:Agricultural Pricing​​​​​​​

agricultural pricing problem农产品定价问题:确定一个国家乳制品的价格和需求,以便最大限度地提高这些产品销售的总收入。使用 Gurobi Python API 将此问题建模为二次优化问题,并使用 Gurobi 优化器解决它,二次规划(Quadratic Programming QP)是非线性规划问题的一个特例。Gurobi对于LP问题使用单纯刑法和内点法求解,这些算法经过扩展也能用于求解QP问题。

一个国家的政府想要决定其乳制品的价格,这些产品都是(直接或间接)由该国的原奶生产企业生产的。 原奶有两个主要成分:脂肪和干物质。 减去用于出口或农场消费的脂肪和干物质的数量后,每年的脂肪可用总量为 60 万吨,干物质可用总量为 75 万吨, 这些都可用于生产供国内消费的乳制品(牛奶、黄油和两种奶酪),4种产品组成百分比如下表所示:

下表显示了去年国内乳制品消费(需求)和价格:

弹性和交叉弹性如下表所示,弹性(elasticities)是指同一产品价格变动导致消费量变动的程度,交叉弹性(cross-elasticities)是指产品A的价格变动导致产品B的消费量变动的程度。这样基于去年国内乳制品消费(需求)和价格,能对今年决策的消费和价格进行约束限制。

价格指数不能高于去年,去年的价格指数是1.939(以千美元计),规定限制新价格必须保证去年消费的总成本不会增加,这样基于去年国内乳制品消费(需求)能对今年决策的价格进行约束限制。优化目标是确定今年的价格和消费(需求)量可以使总收入最大化。模型如下:

3.2 Gurobi+Python代码

和求解MIP问题代码类似,但是要设置模型参数,模型按照求解MIP的逻辑来求解此类非凸问题

model.params.nonConvex = 2
Continuous model is non-convex -- solving as a MIP

 模型数据:

import gurobipy as gp
from gurobipy import GRBdairy = ['milk', 'butter', 'cheese1', 'cheese2']
components = ['fat', 'dryMatter']
components, capacity = gp.multidict({('fat'):600,('dryMatter'):750})
cd, qtyper = gp.multidict({('fat','milk'): 0.04,('fat','butter'): 0.8,('fat','cheese1'): 0.35,('fat','cheese2'): 0.25,('dryMatter','milk'): 0.09,('dryMatter','butter'): 0.02,('dryMatter','cheese1'): 0.3,('dryMatter','cheese2'): 0.4})
dairy, consumption, price, elasticity = gp.multidict({('milk'): [4.82, 0.297, 0.4],('butter'): [0.32, 0.72, 2.7],('cheese1'): [0.21, 1.05, 1.1],('cheese2'): [0.07, 0.815, 0.4]})
priceIndex = 1.939
elasticity12 = 0.1
elasticity21 = 0.4

代码核心: 

model = gp.Model()
model.params.nonConvex = 2# 决策变量:价格和消费量
newp = model.addVars(dairy, name="new price")
newc = model.addVars(dairy, name="new consumption")# 目标函数:最大化收入
model.setObjective(newp.prod(newc), GRB.MAXIMIZE)# 约束条件
#(1)成分总量约束
model.addConstrs((gp.quicksum(qtyper[c,d]*newc[d] for d in dairy)) <= capacity[c] for c in components)#(2)价格指数约束
model.addConstr((gp.quicksum(consumption[d]*newp[d] for d in dairy)) <= priceIndex)#(3)弹性系数约束
model.addConstr((newc['milk']-consumption['milk'])/consumption['milk']==-elasticity['milk']*((newp['milk']-price['milk'])/price['milk']))model.addConstr((newc['butter']-consumption['butter'])/consumption['butter']==-elasticity['butter']*((newp['butter']-price['butter'])/price['butter']))model.addConstr((newc['cheese1']-consumption['cheese1'])/consumption['cheese1']==-elasticity['cheese1']*((newp['cheese1']-price['cheese1'])/price['cheese1'])+elasticity12*((newp['cheese2']-price['cheese2'])/price['cheese2']))model.addConstr((newc['cheese2']-consumption['cheese2'])/consumption['cheese2']==-elasticity['cheese2']*((newp['cheese2']-price['cheese2'])/price['cheese2'])+elasticity21*((newp['cheese1']-price['cheese1'])/price['cheese1']))model.optimize()

 运行结果

Solution count 6: 2.06641 2.06641 2.06641 ... 2.04229Optimal solution found (tolerance 1.00e-04)
Best objective 2.066407962090e+00, best bound 2.066408976227e+00, gap 0.0000%

结果展示: 

import pandas as pd
price_demand = pd.DataFrame(columns=["Products", "Price", "Demand"])
for d in dairy:price_demand = price_demand._append({"Products": d, "Price": '${:,.2f}'.format(round(1000*newp[d].x)), "Demand": '{:,.2f}'.format(round(1e6*newc[d].x))}, ignore_index=True)  
price_demand.index=[''] * len(price_demand)
price_demand

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

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

相关文章

【论文复刻】堆叠柱状图+饼图

复刻了一下这篇论文里的fig2c&#xff1a;Impacts of COVID-19 and fiscal stimuli on global emissions and the Paris Agreement | Nature Climate Change 效果图&#xff1a; 主要步骤&#xff1a; 1. 数据准备&#xff1a;随机赋值 2. 图像绘制&#xff1a;绘制堆叠柱状…

【C++】可变参数模板简单介绍

前言 可变参数模板是C11中的新特性&#xff0c;它能够让我们创建可以接收可变参数的函数模板和类模板&#xff0c;相比C98/03&#xff0c;类模版和函数模版中只能含固定数量的模版参数&#xff0c;可变模版参数是一个巨大的改进&#xff0c;通过系统系统推演数据的类型&#xf…

Python笔记-Alchemy中改变表的模式(库schema)

现在是2024-01-10&#xff0c;发到互联网上应该是2024-05-13。查了下chatgpt&#xff0c;麻了&#xff0c;乱七八糟的。 最后还是靠stackoverflow解决的&#xff0c;目前&#xff0c;从解决问题的角度来看&#xff0c;这个还是牛逼点。 原文如下&#xff1a; python - How d…

Ansible常用变量【下】

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 前言 在上一篇文章《Ansible常用变量【上】》中&#xff0c;学习了Ansible常用变量的前半部分&#xff0c;放了个五一假&#x…

买货查窜货过程中的可能情况

控价除了要管控渠道中的低价、乱价链接外&#xff0c;还可能需要解决窜货问题&#xff0c;当窜货问题蔓延不及时解决时&#xff0c;渠道会越来越受影响&#xff0c;所以治理窜货也是控价过程中很重要的一步&#xff0c;窜货问题的治理多通过买货溯源来解决&#xff0c;买货要先…

点云分割论文阅读01--FusionVision

FusionVision: A Comprehensive Approach of 3D Object Reconstruction and Segmentation from RGB-D Cameras Using YOLO and Fast Segment Anything FusionVision&#xff1a;使用 YOLO 和 Fast Segment Anything 从 RGB-D 相机重建和分割 3D 对象的综合方法 toread&#x…

拥有一台服务器可以做哪些有趣又实用的事情?

在接触云服务器这个概念你以前&#xff0c;你是不是在想&#xff1a; 可能是&#xff0c;云服务器&#xff0c;这个产品的存在&#xff0c;它可以为你做些什么实用的事情吗&#xff1f; 或者是&#xff0c;云服务器这个看似高大上的科技产品&#xff0c;其实可以为我们的生活…

JVM 自定义类加载器

文章目录 1. 为什么要自定义类加载器1.1 隔离加载类1.2 修改类加载的方式1.3 扩展加载源1.4 防止源码泄漏 2. 自定义类加载器应用场景有哪些3. 两种实现方式 自定义类加载器是Java中的一个高级特性&#xff0c;允许您在运行时动态加载类。通过自定义类加载器&#xff0c;您可以…

论文翻译及部分笔记:LANDMARC: Indoor Location Sensing Using Active RFID

LANDMARC: Indoor Location Sensing Using Active RFID 摘要 移动计算设备和嵌入式技术的日益融合引发了“上下文感知”应用的发展和部署&#xff0c;其中位置是最重要的上下文。在本文中&#xff0c;我们介绍了一种名为LANDMARC的定位感知原型系统&#xff0c;该系统使用射频识…

在云计算与人工智能中,7ECloud扮演着什么样的角色

数据驱动的时代&#xff0c;云计算和人工智能已成为推动现代科技进步的两大引擎。作为一家专注于云计算的公司&#xff0c;7ECloud正是在这个领域发挥自己的力量&#xff0c;力图为企业提供一站式解决方案&#xff0c;并拥有来自厂家的源头支持&#xff0c;用极其低的价格助力企…

QT day5 作业

服务器头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> //服务器类 #include <QTcpSocket> //客户端类 #include <QList> //链表类 #include <QMessageBox> //消息对话框类 #include <QDebu…

vscode无法连接 , .vscode-server版本问题

vscode无法连接 &#xff0c; .vscode-server版本问题 解决办法 &#xff1a; 查看自己的版本号 2. 两边vscode版本号需要一致 找一台vscode可以远程连接的&#xff0c; 将它的.vscode-server/bin/b06ae3b2d2dbfe28bca3134cc6be65935cdfea6a 传到 远程服务器上 或者 本地的…

VTK 数据类型:vtkUnstructuredGrid

VTK 数据类型&#xff1a;vtkUnstructuredGrid VTK 数据类型&#xff1a;vtkUnstructuredGridVTK 中数据类型的继承关系常用的几何类型实例&#xff1a;vtkHexahedron 和 vtkTetra VTK 数据类型&#xff1a;vtkUnstructuredGrid 非结构化点是在空间中离散随意分布的点&#xf…

【数据可视化01】matplotlib实例介绍2

目录 一、引言二、实例介绍1.箱线图2.热力图3.3D图 一、引言 接着上一文章【数据可视化01】matplotlib实例介绍1继续介绍matplotlib的实例。 二、实例介绍 在matplotlib中&#xff0c;常用的图形类型包括&#xff1a; 箱线图&#xff08;Box plot&#xff09;&#xff1a;用…

算法day05

第一题 1004. 最大连续1的个数 III 题目如下所示&#xff1a; 如上题所示&#xff1a; 题目本意是在一个数组中只有1和0&#xff0c;给定一个k值&#xff0c;将小于k个0翻转成1&#xff0c;然后返回最终得到最长的1的个数&#xff1b; 我们将这到题的意思转化为另外一种意思&…

单元测试之TestNG知识点总结及代码示例

TestNG 是一个测试框架&#xff0c;用于自动化测试 Java 和 Scala 应用程序&#xff0c;它是 JUnit 和 NUnit 的一个强大替代品。TestNG 支持数据驱动测试、参数化测试、测试套件、依赖管理、多线程测试等特性。TestNG官网&#xff1a;TestNG Documentation 目录 1.TestNG 基…

PCB笔记(二十六):PCB检查

前言 首先检查元器件是否100&#xff05; 放置 文章目录 1、打开DRC2、database check3、检查DRC4、检查多余的线5、其他需要注意的点a.检查差分线、等长线是否已调好b.注意检查晶振、电感等元件上/下方是否其他线经过&#xff08;一般不允许线经过&#xff09;c.打开place_bo…

【管理咨询宝藏101】普华永道并购尽调内部培训

【管理咨询宝藏101】普华永道并购尽调内部培训 【格式】PDF版本 【关键词】普华永道、兼并收购、尽职调查 【核心观点】 - 尽职调查的目的&#xff0c;发现潜在的致命缺陷&#xff0c;判断是否继续交易进程&#xff1b;发现潜在的问题&#xff0c;制定交易前后相应的应对措施。…

C语言 | Leetcode C语言题解之第88题合并两个有序数组

题目&#xff1a; 题解&#xff1a; void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {int p1 m - 1, p2 n - 1;int tail m n - 1;int cur;while (p1 > 0 || p2 > 0) {if (p1 -1) {cur nums2[p2--];} else if (p2 -1) {cur nu…

Kali Linux菜单中各工具功能大全

网络安全学习路线 &#xff08;2024最新整理&#xff09; 如图片过大被平台压缩导致看不清的话&#xff0c;评论区点赞和评论区留言扣1或者关注我我后台会主动发给你&#xff01; 第一阶段&#xff1a;安全基础 网络安全行业与法规 Linux操作系统 计算机网络 HTML PHP Mysql P…