c++ API概述

这部分文档Gurobi c++接口。本手册始于一个快速概述类暴露的接口和最重要的方法在这些类。然后继续全面介绍所有可用的类和方法

如果你是新Gurobi优化器,我们建议你先快速入门指南或者是例子之旅。这些文件提供了具体的例子如何使用这里描述的类和方法。

环境

第一步使用Gurobi c++接口对象是创建一个环境。环境是代表使用GRBEnv类。一个环境充当容器与一组相关联的所有数据优化运行。通常只需要一个环境对象在程序中。

对于更高级的用例,您可以使用一个空环境创建一个未初始化的环境,然后通过编程,设置所有必需的选项为您的特定需求。详情查看环境部分。

模型

您可以创建一个或多个优化模型在一个环境。每个模型都被表示为一个类的对象GRBModel。模型由一组决策变量(对象类GRBVar),一个线性或二次目标函数(指定使用这些变量GRBModel: setObjective),一组约束这些变量(类的对象GRBConstr,GRBQConstr,GRBSOS,或GRBGenConstr)。每个变量都有一个关联的下限,上限和类型(连续、二进制等)。每个线性或二次约束都有一个关联的意义(小于或等于、大于或等于或相等),和右边的值。指本节为更多信息变量、约束和目标。

线性约束是通过建立线性表达式(指定的对象类GRBLinExpr),然后指定这些表达式之间的关系(例如,要求一个表达式等于另一个)。二次约束是建立在类似的方式,但使用二次表达式(类的对象GRBQuadExpr)。

一个优化模型可以被指定,从文件加载模型(使用适当的GRBModel构造函数),或者逐步建立,首先构造一个空对象的类GRBModel然后随后调用GRBModel: addVarGRBModel: addVars添加额外的变量GRBModel: addConstr,GRBModel: addQConstr,GRBModel: addSOS,或任何的GRBModel: addGenConstrXxx方法添加约束。模型是动态的实体;你可以随时添加或删除变量或约束。

我们经常指的是优化模型。一个模型与一个线性目标函数,线性约束,是一个连续变量线性规划(LP)。如果目标是二次,是一个模型二次规划(QP)。如果二次的任何约束,模型是一个Quadratically-Constrained计划(QCP)。我们有时会引用一些特殊情况的QCP: QCPs凸约束,QCPs与非凸约束,双线性程序,二次二阶锥规划。如果模型包含任何整数变量,半连续变量,semi-integer变量,特殊的有序集(SOS)的约束,或一般约束,模型是一个混合整数规划(MIP)。有时我们也会讨论MIP的特殊情况,包括混合整数线性规划(MILP),(MIQP)混合整数二次规划问题,混合整数Quadratically-Constrained程序(MIQCP),混合整数二阶锥规划(MISOCP)。Gurobi优化器处理所有这些模型类。

解决一个模型

一旦你建立了一个模型,您可以调用GRBModel:优化计算一个解决方案。默认情况下,优化将使用并发优化器解决LP模型、障碍解决QP算法模型与凸凸目标和QCP模型约束,否则branch-and-cut算法。解决方案是存储在一个组属性的模型。这些属性可以查询使用一组属性查询的方法GRBModel,GRBVar,GRBConstr,GRBQConstr,GRBSOS,GRBGenConstr类。

Gurobi算法保持小心跟踪模型的状态,所以调用GRBModel:优化只会执行进一步优化如果相关数据改变了自从去年优化模型。如果你想抛弃以前从头计算解决方案信息并重新启动优化而不改变模型中,您可以调用GRBModel:重置

MIP模型已经得到解决之后,您可以调用GRBModel: fixedModel计算相关的固定模型。这个模型是相同的原始,除了它们的值的整数变量是固定的MIP的解决方案。如果你的模型包含SOS约束,一些连续变量出现在这些约束可能是固定的。在某些应用程序中,它可能是有用的信息来计算这种固定模式(例如,双变量,敏感信息,等等),虽然你应该小心在你如何理解这些信息。

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

默认情况下,优化器Gurobi假设你的目标是找到一个证明单个模型的最优解与一个单一的目标函数。Gurobi提供了以下功能,让你放松这些假设:

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

不可行模型

你有几个选项如果找到一个模型是不可行的。你可以尝试诊断不可行性的原因,试图修复不可行性,或两者兼而有之。获取信息,可以用于诊断的原因不可能实行,电话GRBModel: computeIIS计算一个不可约子系统(IIS)不一致。该方法可用于连续和MIP模型,但是你应该意识到MIP版本将是相当昂贵的。这种方法填充IIS的一组属性。

尝试修复的不可行性,电话GRBModel: feasRelax计算的可行性松弛模型。这个放松可以让你找到一个解决方案,最大限度地减少的大小约束违反。

查询和修改属性

大多数与Gurobi模型相关的信息存储在一组属性。一些属性与模型的变量相关联,一些模型的约束,和一些与模型本身。给一个简单的例子,使求解优化模型X填充变量属性。属性,如X所计算的Gurobi优化器直接由用户不能修改,而其他的,如变量下界(属性)。

属性查询使用GRBVar::,GRBConstr::,GRBQConstr::,GRBSOS::,GRBGenConstr::,或GRBModel::,修改后使用GRBVar:集,GRBConstr:集,GRBQConstr:集,GRBGenConstr:集,或GRBModel:集。属性分为一组的枚举类型(GRB_CharAttr,GRB_DoubleAttr,GRB_IntAttr,GRB_StringAttr)。的get ()设置()方法重载,所以属性的类型决定了返回值的类型。因此,constr.get (GRB.DoubleAttr.RHS)返回一个双,constr.get (GRB.CharAttr.Sense)返回一个字符。

如果你想检索一组变量或属性值的限制,通常是更加高效的使用数组方式有关GRBModel对象。方法GRBModel::包括签名允许您查询或修改属性值数组的变量或约束。

属性的完整列表可以在找到属性部分。

额外的模型修改信息

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

约束矩阵在一些方面可以修改。第一个是调用chgCoeffs方法GRBModel对象改变单个矩阵系数。这种方法可以用来修改一个现有的非零的值,现有的非零设置为0,或者创建一个新的非零。约束矩阵也修改,当你删除一个变量或约束的模型(通过GRBModel:删除方法)。相关联的非零值删除删除约束或变量与约束或变量本身。

模型的目标函数在一些方面也可以修改。最简单的是构建一个表达式捕获目标函数(一个GRBLinExprGRBQuadExpr对象),然后通过表达方法GRBModel: setObjective。如果你想修改目标,您可以简单地调用setObjective又一个新的GRBLinExprGRBQuadExpr对象。

线性目标函数的另一种选择setObjective是使用Obj变量属性修改个人线性目标系数。

如果你的变量的分段线性目标,您可以指定使用GRBModel: setPWLObj方法。调用这个方法一次每个相关变量。Gurobi单纯形解算器包括算法支持凸手机万博登录分段线性目标函数,所以连续模型你应该看到一个巨大的性能受益于使用这个特性。清除先前指定的分段线性目标函数,简单的设置Obj属性对应的变量为0。

懒惰的更新

一个需要注意的重要项目的模型修改Gurobi优化器中执行懒惰的时尚,这意味着立即修改不会影响模型。相反,他们正在排队和应用。如果您的程序简单地创建了一个模型,解决了它,你将不会注意到这种行为。但是,如果你要求在你修改的信息模型已经应用,懒惰的更新方法可能相关的细节给你。

正如我们提到的,模型修改(绑定更改,右边的变化,客观变化,等等)被放置在一个队列。这些排队的修改可以被应用到模型在三种不同的方式。第一个是由一个显式的调用GRBModel:更新。第二个是通过调用GRBModel:优化。第三是通过调用GRBModel:写写出模型。第一个案例给你当修改应用细粒度的控制。第二个和第三个假设你想要所有未决的修改应用优化模型或写之前到磁盘。

为什么Gurobi接口以这种方式?有几个原因。首先,这种方法使得它更容易执行多个修改模型,由于模型之间保持不变的修改。第二,处理模型的修改很贵,尤其是在计算服务器环境中,修改需要机器之间的通信。因此,它是有用的可视性应用这些修改的确切时间。一般来说,如果你的程序需要多个修改模型,你应该让他们在阶段,进行一系列修改,然后更新,然后进行更多的修改,然后再更新,等等。每个修改后更新可能会非常昂贵。

如果你忘了打电话更新,程序不会崩溃。您的查询将返回所请求的值的数据点最后的更新。如果您想查询的对象不存在,你会得到一个NOT_IN_MODEL例外。

懒惰的语义Gurobi早些时候以来已经改变了版本更新。虽然绝大多数的程序不受此更改影响,您可以使用UpdateMode参数恢复早期的行为,如果你遇到一个问题。

管理参数

Gurobi优化器提供了一组参数允许您控制的许多细节的优化过程。可行性和最优公差等因素,选择算法,探索MIP策略搜索树,等等,可以通过修改控制之前Gurobi参数优化。参数的类型int,,或字符串

最简单的方法是通过设置参数GRBModel:集方法在模型对象。同样,可以查询参数值GRBModel::

对Gurobi环境参数也可以设置对象,使用GRBEnv:集。注意,每个模型都有自己的拷贝时环境的创建,所以原始环境参数变化不会影响现有的模型。

你可以阅读从一个文件使用一组参数设置GRBEnv: readParams使用,或写一组改变参数GRBEnv: writeParams

我们还包括一个自动参数调优工具,探索许多不同的参数变化为了找到一组提高了性能。你可以叫GRBModel:调整调用模型调优工具。指的是参数调优工具节以获取更多信息。

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

内存管理

内存管理必须考虑在c++程序。特别是Gurobi图书馆和用户程序共享相同的c++堆,所以用户必须注意的某些方面Gurobi图书馆如何使用这堆。管理内存时使用的基本规则Gurobi优化器如下:

  • 与其他动态分配的c++对象,GRBEnvGRBModel使用相关的析构函数对象应该被释放。换句话说,给定一个GRBModel对象,你应该打电话删除我当你不再使用
  • 与模型相关的对象(例如,GRBConstr,GRBQConstr,GRBSOS,GRBGenConstr,GRBVar管理对象)的模型。特别是,删除一个模型将删除所有相关的对象。同样,删除一个对象模型(使用GRBModel:删除)也将删除对象。
  • 一些Gurobi方法返回一个对象数组或值。例如,GRBModel: addVars返回一个数组的GRBVar对象。这是用户的责任自由返回的数组(使用删除[])。参考手册指出当一个方法返回一个基于堆的结果。

这些规则的结果之一是,您必须小心不要使用对象一旦被释放。这无疑是相当清楚的环境和模式,你显式地调用析构函数,但可能不太清楚约束和变量,这是隐式删除时删除相关的模型。

监测进展——日志记录和回调

进步的优化可以通过Gurobi监控日志记录。默认情况下,Gurobi将发送输出到屏幕上。几个简单的控件可用于修改默认日志记录的行为。如果你想直接输出到一个文件中以及在屏幕上指定的日志文件的名字GRBEnv构造函数。您可以修改日志文件参数如果您希望将日志重定向到不同的文件在创建环境对象。的频率可以控制日志输出DisplayInterval参数,可以完全关闭的和日志记录OutputFlag参数。的详细描述Gurobi日志文件中可以找到日志记录部分。

更详细的进度监控可以通过完成GRBCallback类。的GRBModel: setCallback方法允许你接受定期从Gurobi优化器回调。这可以通过生成子类GRBCallback抽象类,编写自己的回调()在这个类的方法。你可以叫GRBCallback: getDoubleInfo,GRBCallback: getIntInfo,GRBCallback: getStringInfo,或GRBCallback: getSolution从内部获取额外的回调信息优化的状态。

修改解决行为——回调手机万博登录

回调也可以用来修改Gurobi优化器的行为。最简单的控制回调GRBCallback:中止,要求优化器终止最早方便点。方法GRBCallback: setSolution允许您将一个可行的解决方案(或部分解决方案)在MIP模型的解决方案。方法GRBCallback: addCutGRBCallback: addLazy允许你添加减少飞机懒惰的约束分别在MIP优化。方法GRBCallback: stopOneMultiObj允许你中断的优化过程多目标优化步骤之一MIP问题不停地分层优化过程。

批处理优化

Gurobi计算服务器允许程序卸载优化计算到专用服务器。Gurobi集群管理器上添加一些额外的功能。一个重要的一个,批处理优化,允许你和你的客户建立一个优化模型程序,提交计算服务器集群(通过集群管理器),后来检查的状态模型和检索其解决方案。您可以使用一个批处理对象使它容易使用批次。上批次的详细信息,请参阅批处理优化部分。

错误处理

所有的方法在Gurobi c++库可以抛出异常的类型GRBException。当发生异常时,可以获得额外的错误信息检索错误代码(使用方法GRBException: getErrorCode),或者通过检索异常消息(使用方法GRBException: getMessage)。可能会返回错误代码的列表中可以找到错误代码部分。