Gurobi设置初始可行解

news2024/12/24 12:16:27

目录

1. 决策变量的`Start`属性直接设置变量的初始值

1.1 Start:MIP变量的起始值(初值)double类型,可更改

1.2 StartNodeLimit:限制了在完善一组输入部分变量的初始解时,MIP所探索的分支定界的节点的数量 int类型,可更改

1.3 NumStart:在MIP模型中的初始解的数量,即有几组初始解。(初始化为未定义)int类型,可更改

1.4 StartNumber:当传入多个初始解时 int类型,可更改

2. 设置决策变量的Hint属性,为求解器提供提示

2.1 VarHintVal:用户提示值,即一个变量在MIP模型的高质量解决方案中可能具有的特定值 double类型,可更改

2.2 VarHintPri:用户对于用户提示值的信心水平,该值越大表明用户把握越大 int类型,可更改

3. 使用求解器的callback方法


对于min问题,可行解是提供的UB,要么是通过分支定界探测节点(具体的说是探测松弛节点再加割)找到,要么是通过启发式算法找到。

前者表现在gurobi求解日志里是第一列的*,后者表现在gurobi求解日志里是H。

gurobi内部也嵌套了30多种启发式算法,是普适性的算法,不一定对我们的问题适用。当我们看到gurobi很久都找不到一个可行解(incumbent那一列为空),如下:

我们可以要么改写模型,写一个更紧一点的模型,本质是探测节点找到可行解。但也可以通过启发式算法传入可行解。

传入的方法有3种:

1. 决策变量的`Start`属性直接设置变量的初始值

这个方法其实简单,效果也不错,以我现在的水平用得比较多。

Start属性可以输入一个或多个可行解,Gurobi会自己将可行解中未定义的变量补全,用户也可以Push求解器努力补全更好的,Gurobi最终会使用最好的可行解进行迭代搜索。

与Start相关的属性有:`Start,StartNodeLimit,StartNumber,NumStart`。

1.1 Start:MIP变量的起始值(初值)double类型,可更改

# 将变量x_1_12的初值设置为0
x[0,12].start = 1.0

# 循环为x_ij赋值完整的一组初始解,data为存放初始解的矩阵
for i in range(len(data)):
    for j in range(len(data[i])):
        x[i,j].start = data[i][j]

1.2 StartNodeLimit:限制了在完善一组输入部分变量的初始解时,MIP所探索的分支定界的节点的数量 int类型,可更改

         StartNodeLimit参数的默认值是-1,其使用SubMIPNodes参数的值(即搜索500个分支定界树的节点后停止)。
        值为-2表示只检查完整的MIP的Start输入下的可行性,并忽略部分MIP的决策变量的Start。
        值为-3将完全关闭MIP的Start通道。
        非负的参数值表示探索节点限制个数,比如设置m.setParam(GRB.Param.StartNodeLimit, 10000.0), 表示探索的节点个数上限为10000个。

# 将搜索节点个数设置为10000个点
m.setParam(GRB.Param.StartNodeLimit, 10000.0)

1.3 NumStart:在MIP模型中的初始解的数量,即有几组初始解。(初始化为未定义)int类型,可更改

1.4 StartNumber:当传入多个初始解时 int类型,可更改

# 为模型m2设置要输入的初始解个数为2个
m2.NumStart = 2

# 将该可行解设置为第一个输入的可行解
m2.Params.StartNumber = 0

# 将该可行解设置为第二个输入的可行解
m2.Params.StartNumber = 1

# 完整版
# 读取原始模型m
    m2 = read("CVRP1.mps")
    # 设置NumStart=2,表示可以接受两个可行解作为初值
    m2.NumStart = 2
    # 提取解池中第5个解
    m.setParam(GRB.Param.SolutionNumber, 4)
    s5 = m.Xn
    # 将该可行解设置为第一个输入的初值
    m2.Params.StartNumber = 0
    index = 0
    for v in m2.getVars():
        v.Start = s5[index]
        index += 1
    # 提取解池中第6个解
    m.setParam(GRB.Param.SolutionNumber, 5)
    m2.Params.StartNumber = 1
    s6 = m.Xn
    index = 0
    for v in m2.getVars():
        v.Start = s6[index]
        index += 1
    # 输入好初值后更新模型并求解
    m2.update()
    m2.optimize()

2. 设置决策变量的Hint属性,为求解器提供提示

有的时候我们也找不到可行解,求解器就更加为难了。但是我们通过已有的一些尝试发现某些变量非常有可能的取值情况,此时就可以通过Hint属性来向求解器提示某某变量可能取某个值。注意,如果我们已知一些变量的取值,或者已知一个可行解,我们应该使用Start属性来给求解器提供初值,因为Hint会从全局影响整个迭代搜索的过程。

  • Hint属性是用户提示Gurobi某个变量可能在最优解中的取值,并且用户可以自己设置对这个想法的信心。

  • 但是与Start属性不同的是,Hint会在整个迭代过程中影响着Gurobi的迭代搜索,因此如果很确信的话,还是拿Start来构建初值比较好。start建构是100%建构,Hint是程度。

2.1 VarHintVal:用户提示值,即一个变量在MIP模型的高质量解决方案中可能具有的特定值 double类型,可更改

2.2 VarHintPri:用户对于用户提示值的信心水平,该值越大表明用户把握越大 int类型,可更改

#设置x[0,18]可能=1,信心为50
x[0,18].VarHintVal = 1.0
x[0,18].VarHintPri = 50

#设置x[0,13]可能=1,信心为25
x[0, 13].VarHintVal = 1.0
x[0, 13].VarHintPri = 25

#设置x[0,6]可能=1,信心为25
x[0, 6].VarHintVal = 1.0
x[0, 6].VarHintPri = 25

3. 使用求解器的callback方法

Callback(回调)是求解器的一种高级功能,可以用于监视求解进程、获取求解进程信息,甚至干预求解算法等。Callback不同于上文介绍的设置变量的Start属性和Hint属性的方法。

Callback是一个比较神奇的技术,它需要在求解过程中靠我们插手“半自动的”进行迭代搜索,我们设置的callback会在迭代中影响着Gurobi的求解,往往和一些cut算法结合。

gurobi中callback函数的使用整理_gurobi callback-CSDN博客

其中与初值有关的操作有,设置导入一个启发式解决方案的值为初值或部分初值。涉及的方法为cbSetSolutioncbSetSolution ( vars, solution )方法中有两个待输入参数,其中一个vars为需要指定初值的变量,可以为一个,也可以为一个列表的变量;另一个solution则是新解决方案中那些被指定初值的变量的所需值,即vars需要的值。例子代码如下:

# Example usage:
def mycallback(model, where):
    if where == GRB.Callback.MIPNODE:
        model.cbSetSolution(vars, newsolution)
        objval = model.cbUseSolution()
        model.optimize(mycallback)
 
# 如:
if abs(subX[i + j -1].x) < 0.001:  # 松弛解中该变量的取值在0附近
   model.cbSetSolution(model._X[(i,j)], 0.0)  # 将该变量的取值上界设为0
elif abs(subX[i + j-1].x - 1) < 0.001:  # 在1附近
   model.cbSetSolution(model._X[(i,j)], 1.0)

可以继续使用 cbUseSolution()方法来使用被指定初值的vars们立即使用启发式方法计算出一个可行解。

参考文献:

优化求解器 | 求解器加速的高级技能包:MIP模型初始解设置相关操作的超详细解读

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

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

相关文章

SAAS软件营销——利用人工智能帮助企业了解客户

软件营销部队(Salesforce)是全球领先的客户关系管理(CRM)解决方案供应商之一&#xff0c;其产品和服务旨在帮助企业成长&#xff0c;并追踪与客户的关系。 在1999 年成立时&#xff0c;它就率先提出了通过互联网(现在通常称为“云”)实现“软件即服务”(SaaS)的概念。 SaaS提…

周期性触发的自定义触发器

背景 本文我们实现一个周期性触发的自定义触发器&#xff0c;顺便看下实现自定义触发器的一些要点 周期性触发器实现 实现一个每分钟触发一次的自定义事件时间触发器&#xff0c;实现代码和注意事项如下所示 package wikiedits.trigger;import org.apache.flink.api.common…

线程通信初始

简单认识一下线程通信 目录 简单认识一下线程通信线程通信定义线程通信模型之一释疑示例案例案例要求案例简单实现 拓展等待和唤醒API 参考视频 注&#xff1a;线程通信 前提是 线程安全 线程通信定义 当多个线程共同操作共享的资源时&#xff0c;线程间通过某种方式互相告知自…

【算法训练-二分查找 三】【特殊二分】寻找峰值

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是【数组的二分查找】&#xff0c;使用【数组】这个基本的数据结构来实现&#xff0c;这个高频题的站点是&#xff1a;CodeTop&#xff0c;筛选条件为…

Vue3+TS+ECharts5实现中国地图数据信息显示

1.引言 最近在做一个管理系统&#xff0c;主要技术栈使用的是Vue3TSViteElementPlus&#xff0c;主要参考项目是yudao-ui-admin-vue3&#xff0c;其中用到ECharts5做数字大屏&#xff0c;展示中国地图相关信息&#xff0c;以此基础做一个分享&#xff0c;写下这篇文章。 &quo…

解决ASP.NET Core的中间件无法读取Response.Body的问题

概要 本文主要介绍如何在ASP.NET Core的中间件中&#xff0c;读取Response.Body的方法&#xff0c;以便于我们实现更多的定制化开发。本文介绍的方法适用于.Net 3.1 和 .Net 6。 代码和实现 现象解释 首先我们尝试在自定义中间件中直接读取Response.Body&#xff0c;代码如…

Appleid苹果账号自动解锁改密(自动解锁二验改密码)

目前该项目能实现以下功能&#xff1a; 多用户使用&#xff0c;权限控制多账号管理账号分享页&#xff0c;支持设置密码、有效期、自定义HTML内容自动解锁与关闭二步验证自动/定时修改密码自动删除Apple ID中的设备代理池与Selenium集群&#xff0c;提高解锁成功率允许手动触发…

先输入列,再输入行

想要的表格行数和列数是 5 行 5 列&#xff0c;以下是相应的代码实现&#xff1a; # 定义表格行数和列数 rows 5 cols 5# 创建一个二维列表作为表格 table [[ for j in range(cols)] for i in range(rows)]print("请输入表格数据&#xff1a;")while True:# 获取…

Python无废话-办公自动化Excel读取操作

openpyxl模块介绍 openpyxl是一个用于处理Excel文件的Python库,用于读取/写入Excel2010 xlsx/xlsm/xltx/xltm文件(不支持xls格式)。通过使用openpyxl库&#xff0c;可 以轻松地在Python程序中实现对Excel文件的操作。 openpyxl 安装 方式1&#xff1a;使用pip 命令安装&…

操作系统学习笔记1

文章目录 1、OS的一个宏观比喻2、OS的目的和功能3、OS的发展4、OS的运行机制5、OS的特征6、OS的体系结构 参考视频&#xff1a;操作系统 1、OS的一个宏观比喻 2、OS的目的和功能 3、OS的发展 4、OS的运行机制 中断、系统调用、异常。 5、OS的特征 6、OS的体系结构

【逐步剖C++】-第二章-C++类和对象(下)

前言&#xff1a;本文是对类和对象知识点的最后一篇总结&#xff0c;前两篇的链接如下&#xff1a; 【逐步剖C】-第二章-C类和对象&#xff08;上&#xff09; 【逐步剖C】-第二章-C类和对象&#xff08;中&#xff09; 这三篇加起来就是笔者学习在类和对象中的所有总结了&…

计算机网络网络层、应用层、数据链路层协议详解

目录 一、计算机网络 二、网络层 三、应用层 四、数据链路层 一、计算机网络 计算机网络是将多台计算机和其他网络设备通过通信链路连接起来&#xff0c;以实现数据交换和资源共享的系统。它是现代信息社会的基础设施之一&#xff0c;为人们提供了快速、可靠、安全的数据传…

学校项目培训之Carla仿真平台之Carla学习内容

一、Blender Blender入门&#xff1a;https://www.bilibili.com/video/BV1fb4y1e7PD/ Blender导入骨骼&#xff1a;https://www.bilibili.com/video/BV1hc41157nL 做一个车&#xff1a;https://www.bilibili.com/video/BV1hY411q7w2 二、Roadrunner RoadRunner Scenario…

Flink状态管理与检查点机制

1.状态分类 相对于其他流计算框架,Flink 一个比较重要的特性就是其支持有状态计算。即你可以将中间的计算结果进行保存,并提供给后续的计算使用: 具体而言,Flink 又将状态 (State) 分为 Keyed State 与 Operator State: 1.1 算子状态 算子状态 (Operator State):顾名思义…

计组—— I/O系统

&#x1f4d5;&#xff1a;参考王道课件 目录 一、I/O系统的基本概念 1.什么是“I/O”&#xff1f; ​编辑2.主机如何和I/O设备进行交互&#xff1f; 3.I/O控制方式 &#xff08;1&#xff09;程序查询方式 &#xff08;2&#xff09;程序中断方式 &#xff08;3&#x…

【MATLAB源码-第41期】基于压缩感知算法的OFDM系统信道估计和LS算法对比仿真。

操作环境&#xff1a; MATLAB 2013b 1、算法描述 压缩感知&#xff08;Compressed Sensing, CS&#xff09;是一种从稀疏或可压缩信号中重构完整信号的数学理论和技术。下面详细介绍压缩感知和它在OFDM信道估计中的应用。 1. 压缩感知基本概念 在传统采样理论中&#xff0…

数字电路逻辑与设计 之循环码和 移存码

有发现错误的能力&#xff0c;不能纠正 只能检查单次的错误&#xff0c;不能完全抗干扰 可以按照上面的方法来循环构造 移存码可以通过前推后推来实现

pytorch_神经网络构建1

文章目录 pytorch简介神经网络基础分类问题分析:逻辑回归模型逻辑回归实现多层神经网络多层网络搭建保存模型 pytorch简介 为什么神经网络要自定义数据类型torch.tensor? tensor可以放在gpu上训练,支持自动求导,方便快速训练,同时支持numpy的运算,是加强版,numpy不支持这些 为…

C++项目:【高并发内存池】

文章目录 一、项目介绍 二、什么是内存池 1.池化技术 2.内存池 3.内存池主要解决的问题 4.malloc 三、定长的内存池 四、高并发内存池整体框架设计 1.高并发内存池--thread cache 1.1申请内存&#xff1a; 1.2释放内存&#xff1a; 1.3用TLS实现thread cache无锁访…

GD32F10 串口通信

1. 什么是通信 通信&#xff0c;指人与人或人与自然之间通过某种行为或媒介进行的信息交流与传递&#xff0c;从广义上指需要信息的双方或多方在不违背各自意愿的情况下采用任意方法&#xff0c;任意媒质&#xff0c;将信息从某方准确安全地传送到另方。通信双方如果想正确传输…