Python API概述


Python API概述

本节记录了Gurobi Python接口。首先概述全局函数,可以在不引用任何Python对象的情况下调用全局函数。然后讨论接口中可用的不同类型的对象,以及这些对象上最重要的方法。最后,给出一个全面介绍所有可用的类和方法

如果您是Gurobi Optimizer的新手,我们建议您从快速入门指南或者是例子之旅.这些文档提供了如何使用这里描述的类和方法的具体示例。

AIX用户的重要注意事项:由于AIX上的Python支持有限,我们的AIX端口不包括Python接口。

全局函数

Gurobi shell包含一组全局函数可以在不引用任何Gurobi对象的情况下调用。这些函数中最重要的可能是阅读函数,该函数允许您从文件中读取模型。其他有用的全局函数包括系统,它允许您从Gurobi shell中发出shell命令,模型,它提供当前加载的模型的列表disposeDefaultEnv,它处理默认环境。其他全局函数允许读取、修改或写入Gurobi参数(readParamssetParamwriteParams)。

模型

Gurobi Python接口中的大多数操作都是通过调用Gurobi对象上的方法来执行的。最常用的对象是模型.模型由一组决策变量(类的对象)组成Var兆乏),对这些变量的线性或二次目标函数(用Model.setObjective),以及对这些变量(类的对象)的一组约束施工MConstrQConstr紧急求救信号,或GenConstr)。每个变量都有一个相关的下界、上界和类型(连续的、二进制的等等)。每个线性或二次约束都有一个相关的含义(小于或等于、大于或等于或等于)和右边值。指本节有关变量、约束和目标的更多信息。

通过从文件加载模型(使用前面提到的方法),可以一次性指定优化模型阅读函数),也可以通过首先构造类的空对象来递增地构建模型然后调用Model.addVarModel.addVars,或Model.addMVar添加其他变量,和Model.addConstrModel.addConstrsModel.addLConstrModel.addQConstrModel.addSOS,或任何Model.addGenConstrXxx方法来添加额外的约束。

线性约束通过构建线性表达式(类的对象)来指定LinExprMLinExpr),然后指定这些表达式之间的关系(例如,要求一个表达式与另一个表达式相等)。二次约束以类似的方式构建,但使用二次表达式(类的对象)QuadExprMQuadExpr)。一般约束是使用一组专门的方法,或一组一般约束辅助函数加上重载运算符。

模型是动态实体;始终可以添加或删除变量或约束。

我们经常提到优化模型的设计。具有线性目标函数、线性约束和连续变量的模型是线性规划(LP)。如果目标为二次型,则模型为a二次规划(QP).如果任何约束条件是二次的,则模型是aQuadratically-Constrained计划(QCP). 我们有时会提到QCP的一些特殊情况:具有凸约束的QCP,具有非凸约束的QCP,双线性程序二阶锥程序(SOCP).如果模型包含任何整数变量、半连续变量、半整数变量、特殊有序集(SOS)约束或一般约束,则该模型是一个混合整数程序(MIP).我们有时也会讨论MIP的特殊情况,包括混合整数线性规划(MILP)混合整数二次规划(MIQP)混合整数二次约束规划(MIQCP)混合整数二阶锥规划(MISOCP).Gurobi Optimizer处理所有这些模型类。

环境

与我们的其他语言api相比,环境在Gurobi Python接口中扮演的角色要小得多,这主要是因为Python接口有一个默认环境。除非您显式地将您自己的环境传递给需要环境的例程,否则将使用默认环境。

您可能希望创建自己的环境的主要情况是,您希望精确控制与环境(特别是许可令牌或Compute Server)关联的资源何时释放。狗万app足彩如果您使用自己的环境来创建模型(使用阅读或者是模型构造函数),那么只要您的程序不再引用您的环境或狗万app足彩使用该环境创建的任何模型,与该环境相关联的资源就会被释放。

注意,您可以手动删除对默认环境的引用,从而通过调用disposeDefaultEnv. 调用此函数后,在默认环境中构建的所有模型都被垃圾收集后,默认环境也将被垃圾收集。如果调用需要的例程,将自动创建新的默认环境。

对于更高级的用例,您可以使用空环境来创建未初始化的环境,然后以编程方式为您的特定需求设置所有必需的选项。有关更多详细信息,请参阅环境部分

解决一个模型

一旦你建立了一个模型,你可以调用Model.optimize计算一个解。默认情况下,优化将使用并发优化器对于LP模型的求解,采用barrier算法求解具有凸目标的QP模型和具有凸约束的QCP模型,另外采用分支切割算法。该解决方案存储在一组属性模型的,可以随后进行查询(稍后我们将回到这个主题)。

Gurobi算法会仔细跟踪模型的状态,因此调用Model.optimize只在自上次优化模型以来相关数据发生更改时执行进一步优化。如果您想放弃以前计算的解决方案信息,并在不更改模型的情况下从头开始优化,您可以调用Model.reset

解出MIP模型后,可以调用Model.fixed计算相关的固定模型。除了整数变量固定在MIP解中的值之外,该模型与原始模型相同。如果您的模型包含SOS约束,那么在这些约束中出现的一些连续变量也可能是固定的。在某些应用程序中,在这个固定的模型上计算信息(例如,二元变量、敏感性信息等)是很有用的,尽管您应该谨慎地解释这些信息。

多种解决方案、目标和场景

默认情况下,Gurobi Optimizer假设您的目标是为具有单一目标函数的单一模型找到一个经验证的最佳解决方案。Gurobi提供了以下功能,允许您放松这些假设:

  • 溶液池:让你找到更多的解决方案。
  • 多个场景:允许您查找多个相关模型的解决方案。
  • 多个目标:允许您指定多个目标函数并控制它们之间的权衡。

不可行模型

如果发现一个模型不可行,您有几个选择。您可以尝试诊断不可行性的原因,尝试修复不可行性,或两者兼有。为了获得对诊断不可行性的原因有用的信息,调用Model.computeIIS计算不可约不一致子系统(IIS)。这种方法可以用于连续模型和MIP模型,但是您应该知道MIP版本可能非常昂贵。此方法填充一组IIS属性。

想要修复一个不可行的问题,请打电话Model.feasRelaxSModel.feasRelax计算模型的可行性松弛。这种松弛允许您找到一个解,使违反约束的幅度最小化。

查询和修改属性

与Gurobi模型关联的大部分信息都存储在一组属性中。有些属性与模型的变量有关,有些与模型的约束有关,还有一些与模型本身有关。举一个简单的例子,求解一个优化模型导致x要填充的变量属性。属性,如x用户不能直接修改由Gurobi优化器计算的变量,而其他变量,如变量下界属性)。

在Python接口中,可以通过两种方式访问属性。第一种是使用getAttr ()setAttr ()方法,这些方法可用于变量(Var.getAttr/Var.setAttr)、矩阵变量(MVar.getAttr/MVar.setAttr),线性约束(Constr.getAttr/Constr.setAttr),矩阵约束(MConstr.getAttr/MConstr.setAttr)、二次约束(QConstr.getAttr/QConstr.setAttr),索斯(SOS.getAttr)、一般约束(GenConstr.getAttr/GenConstr.setAttr)及模型(Model.getAttr/Model.setAttr)。属性名作为第一个参数被调用(例如,var.getAttr(“x”)若干。setAttr (rhs》0.0))。可在中找到可用属性的完整列表属性本手册的一部分。

还可以更直接地访问属性:可以在对象名称后面加上句点,后跟该对象的属性名称。注意,当引用属性时,大写/小写将被忽略。因此,b = constr.rhs相当于b = constr.getAttr (rhs)若干。rhs = 0.0相当于若干。setAttr (rhs》0.0)

附加的模型修改信息

对现有模型的大多数修改都是通过属性接口完成的(例如,对变量边界、约束右边等的更改)。主要的例外是对约束矩阵和目标函数的修改。

约束矩阵可以用几种方法修改。第一个是调用Model.chgCoeff方法。此方法可用于修改现有非零的值,将现有非零设置为零,或创建新的非零。当您从模型中移除一个变量或约束时(通过Model.remove方法)。与删除的约束或变量关联的非零值将随约束或变量本身一起删除。

模型目标函数还可以通过几种方法进行修改。最简单的方法是构建一个表达式来捕获目标函数(aLinExprMLinExprQuadExpr,或MQuadExpr对象),然后将该表达式传递给方法Model.setObjective.如果你想修改目标,你可以直接打电话setObjective再次用一个新的LinExprQuadExpr对象。

对于线性目标函数,可选择setObjective就是使用Obj变量属性修改单个线性目标系数。

如果变量具有分段线性目标,则可以使用Model.setPWLObj方法。为每个相关变量调用此方法一次。Gurobi单纯形求解器包含了对凸分段手机万博登录线性目标函数的算法支持,因此对于连续模型,您应该可以从使用该特性中看到实质性的性能优势。要清除先前指定的分段线性目标函数,只需设置Obj属性设置为0。

懒惰的更新

关于Gurobi优化器中的模型修改,需要注意的一个重要事项是,它是在懒惰的时尚,这意味着修改不会立即影响模型。相反,它们会在以后排队应用。如果您的程序只是创建一个模型并求解它,您可能永远不会注意到这种行为。但是,如果您在应用修改之前询问有关模型的信息,则延迟更新的详细信息会ch可能与您有关。

正如我们刚才提到的,模型修改(绑定更改、右侧更改、目标更改等)被放置在一个队列中。这些排队修改可以通过三种不同的方式应用于模型。第一种是通过显式调用Model.update.第二种是通过召唤来的Model.optimize.第三个是通过电话Model.write写出模型。第一种情况使您可以细粒度控制何时应用修改。第二种和第三种假设您希望在优化模型或将模型写入磁盘之前应用所有挂起的修改。

为什么Gurobi接口会以这种方式工作?有几个原因。首先,这种方法使对模型执行多次修改变得更加容易,因为模型在修改之间保持不变。第二,处理模型修改的成本可能很高,特别是在计算服务器环境中,修改需要机器之间的通信。因此,准确了解何时应用这些修改非常有用。通常,如果您的程序需要对模型进行多次修改,则应分阶段进行修改,即先进行一组修改,然后进行更新,再进行更多修改,然后再次更新,等等。每次修改后进行更新可能会非常昂贵。

如果您忘记调用update,您的程序不会崩溃。您的查询将简单地返回来自上次更新点的请求数据的值。如果您尝试查询的对象不存在,那么您将得到NOT_IN_MODEL而是例外。

自早期Gurobi版本以来,惰性更新的语义已经发生了变化。虽然绝大多数程序不受此更改的影响,但您可以使用UpdateMode参数,以便在遇到问题时恢复到以前的行为。

管理参数

Gurobi优化器提供了一组参数,允许您控制优化过程的许多细节。在开始优化之前,可以通过修改Gurobi参数来控制可行性和最优性容差、算法选择、探索MIP搜索树的策略等因素。参数使用method设置Model.setParam. 当前值也可以使用Model.getParamInfo.也可以更直接地通过模型参数类。设置MIPGap参数为0.0的模型,例如,您可以执行以下任一操作m.setParam (MIPGap, 0)m.Params.MIPGap = 0

使用。从文件中读取一组参数设置Model.read,或使用Model.write

我们还包括一个自动参数调整工具,该工具探索许多不同的参数更改集,以找到一组提高性能的参数Model.tune调用模型上的调优工具。指的是参数调优工具第节了解更多信息。

我们应该注意的一点是,更改一个模型的参数不会影响其他模型的参数值setParam方法为所有加载的模型设置参数。

Gurobi参数的完整列表可以在参数部分

监控进度-日志记录和回调

优化的进度可以通过Gurobi日志进行监控。默认情况下,Gurobi将向屏幕发送输出。有几个简单的控件可用于修改默认日志记录行为。您可以设置日志文件参数,如果您希望将Gurobi日志也指向一个文件。日志输出的频率可以用DisplayInterval参数,可以完全关闭日志记录OutputFlag参数。

日志输出也被发送到名为gurobipy在水平信息.你可以使用Python日志记录模块连接到此日志。

更详细的进度监控可以通过回调函数来完成。如果你传递一个带两个参数的函数,模型在哪里,Model.optimize,你的函数将被周期性地从优化内部调用。然后你的回调可以调用Model.cbGet检索有关优化状态的附加信息。你可以参考回调类以获取更多信息。

修改解算器行为-回调手机万博登录

回调还可以用于修改Gurobi优化器的行为。最简单的控制回调是Model.terminate,它要求优化器在最早方便的时间点终止Model.cbSetSolution允许您在解决MIP模型的过程中注入可行的解决方案(或部分解决方案)。方法Model.cbCutModel.cbLazy允许您添加减少飞机懒惰的约束分别在MIP优化期间。方法Model.cbStopOneMultiObj允许您中断多目标MIP问题中某个优化步骤的优化过程,而无需停止分层优化过程。

批处理优化

Gurobi Compute Server使程序能够将优化计算卸载到专用服务器上。Gurobi集群管理器在这一基础上添加了许多附加功能。一个重要的,,批处理优化,允许您使用客户端程序构建优化模型,将其提交到Compute Server集群(通过集群管理器),然后检查模型的状态并检索其解决方案。你可以用批处理对象以便更容易处理批量。有关批次的详情,请参阅批处理优化部分

错误处理

Gurobi Python库中的所有方法都可以抛出类型为的异常GurobiError.发生异常时,可以通过检索errno消息的成员GurobiError对象。的可能值的列表errno字段可以在错误代码部分