CPLEX -切换到Gurobi

从CPLEX™迁移包括:

  1. 建筑模型
  2. 设置求解参数手机万博登录
  3. 解的计算与提取

此外,您还可以在我们的页面上看到跨越各种编程语言的代码示例列表代码示例页面。

建筑模型

任何使用优化的程序都必须首先建立一个优化模型。虽然模型如何构建的确切细节取决于编程语言,但在我们所支持的所有语言中,一般概念是相似的。我们将关注概念,并在适当时提供细节。在CPLEX和Gurobi中,描述优化问题的前两个步骤是创建一个环境和一个模型.这些是我们的面向对象接口中的对象,分别使用GRBEnv和GRBModel构造函数创建。它们是C接口中的指针,由GRBloadenv()和GRBnewmodel()例程返回。下一步通常是列出决策变量。这是通过C语言中的grbadvar()例程和面向对象接口中的addVar()方法完成的。您可以一次添加一个变量,也可以添加多个变量(使用grbadvars()或addVars())。我们通常发现一次添加一个变量更方便,而且这样做不会造成性能损失,但是如果CPLEX程序已经这样做了,您可能想要添加多个变量。

Gurobi和CPLEX的一个区别是我们使用“懒更新”的方法。在对模型进行更改之后,您需要调用grbupdatmodel /GRBModel。更新以使这些更改可见。更具体地说,你需要打电话“更新”在向模型中添加变量之后,为了在约束中使用这些变量。我们的延迟更新方法使构建或修改模型变得更容易、更有效,因为您可以完全控制实际更改何时发生。然而,我们的接口和CPLEX接口之间的区别是您需要记住的。决策变量有许多属性,包括变量类型(连续、二进制等)、下界、上界等。你有两个选择来指定这些。第一个是在创建变量时输入所需的属性值(例如,作为addVar()的参数)。第二种方法是在将变量添加到模型之后,使用各种Gurobi之一修改属性例程(例如,C中的GRBsetintattr(), c++中的GRBVar.set())。属性是Gurobi接口中的一个重要概念。与在CPLEX中为访问和修改模型的各种属性提供几十个不同的例程不同,我们通过一个接口来处理它们。下面是一个例子,在一系列语言中显示的命令,您可以使用它来更改变量的上限x1.0:

语言 命令
C grbsetdbltreelement (model, GRB_DBL_ATTR_UB, x_index, 1.0);
c++ x.set (GRB_DoubleAttr_UB, 1.0);
c# x.Set (GRB.DoubleAttr。乌兰巴托,1.0);
Java x.set (GRB.DoubleAttr。乌兰巴托,1.0);
Python x.ub = 1.0

类似地,要改变下界:

语言 命令
C grbsetdbltrelement (model, GRB_DBL_ATTR_LB, x_index, 1.0);
c++ x.set (GRB_DoubleAttr_LB, 1.0);
c# x.Set (GRB.DoubleAttr。磅,1.0);
Java x.set (GRB.DoubleAttr。磅,1.0);
Python x.lb = 1.0

这个属性接口用于统一和简化各种Gurobi接口。通常,如果您正在搜索一个与CPLEX get/set例程匹配的例程,那么您很可能会在我们的属性接口中找到该功能。

构建优化模型的下一步通常是描述决策变量的线性约束。根据您使用的界面,您可以使用单个约束矩阵来描述这些约束,可以添加约束组,也可以一次添加一个约束。同样,我们发现一次添加一个约束更方便,但我们理解,如果模拟现有的CPLEX方法,可能会简化迁移。如果您使用Gurobi C接口,那么您通常只会使用一个约束矩阵来指定约束。您可以使用GRBloadmodel()例程来实现这一点。这个例程的参数与CPLEX的参数非常相似CPXcopylp ()例行公事。注意,您还可以使用grbadconstr()在C接口中单独添加约束。在我们的面向对象接口中,您可以使用addConstr()方法添加单个线性约束。细节取决于你使用的语言。我们的c++, .NET和Python接口允许操作符重载,所以你可以添加一个线性约束,如下所示:

语言 命令
C Int ind[] = {1, 3, 4};Double val[] = {1.0, 2.0, 1.0};错误= GRBaddconstr(model, 3, ind, val, GRB_EQUAL, 1.0, "New");
c++ 模型。addConstr(x + y + 2*z <= 2);
c# 模型。AddConstr(x + y + 2*z <= 2);
Python 模型。addConstr(x + y + 2*z <= 2)

您还可以构建线性表达式(GRBExpr)对象,向这些表达式添加线性项(expr.addTerm()),然后使用这些表达式添加约束。在Java中:

GRBLinExpr expr = new GRBLinExpr();

expr.addTerm (1.0 x);expr.addTerm (1.0, y);expr.addTerm (2.0, z);

模型。addConstr (expr伽马线暴。LESS_EQUAL, 2.0);

您的模型可能包含其他约束类型,包括特殊有序集(SOS)约束或二次约束。Gurobi接口包含的例程与CPLEX接口中的例程非常相似。我们鼓励您浏览我们的示例以获得详细信息。

设置求解参数手机万博登录

在将优化模型从CPLEX迁移到Gurobi时,您可能需要设置某些Gurobi参数,以匹配您在CPLEX中修改过的参数。我们想要强调的一个重要一点是,您不应该假设需要为您更改的每个CPLEX参数找到一个匹配的Gurobi参数。Gurobi和CPLEX使用不同的策略和算法。Gurobi策略调优可能与您所做的CPLEX调优有所不同,而且通常可能根本就没有必要进行调优。我们建议您从默认设置开始,并且只在您观察到想要修改的特定行为时更改参数。下表给出了最常用CPLEX参数的高级映射:

CPLEX参数(C API) Gurobi参数
CPX_PARAM_BARALG BarHomogeneous
CPX_PARAM_BARCROSSALG 交叉
CPX_PARAM_BAREPCOMP BarConvTol
CPX_PARAM_BARQCPEPCOMP BarQCPConvTol
CPX_PARAM_BRDIR BranchDir
CPX_PARAM_CLIQUES CliqueCuts
CPX_PARAM_COVERS CoverCuts
CPX_PARAM_CUTPASS CutPasses
CPX_PARAM_EPGAP MIPGap
CPX_PARAM_EPAGAP MIPGapAbs
CPX_PARAM_EPINT IntFeasTol
CPX_PARAM_EPOPT OptimalityTol
CPX_PARAM_FLOWCOVERS FlowCoverCuts
CPX_PARAM_FPHEUR PumpPasses
CPX_PARAM_FRACPASS GomoryPasses
CPX_PARAM_GUBCOVERS GUBCoverCuts
CPX_PARAM_HEURFREQ 启发式
CPX_PARAM_INTSOLLIM SolutionLimit
CPX_PARAM_LPMETHOD 方法
CPX_PARAM_MIPEMPHASIS MIPFocus
CPX_PARAM_MIRCUTS MIRCuts
CPX_PARAM_NODEFILEIND NodeFileStart
CPX_PARAM_POLISHAFTEREPGAP ImproveStartGap *
CPX_PARAM_POLISHAFTERTIME ImproveStartTime *
CPX_PARAM_PREDUAL 预对偶
CPX_PARAM_PREIND Presolve
CPX_PARAM_RINSHEUR rin
CPX_PARAM_STARTALG 方法
CPX_PARAM_SUBALG NodeMethod
CPX_PARAM_THREADS 线程
CPX_PARAM_TIMELIMIT 期限
CPX_PARAM_VARSEL VarBranch
CPX_PARAM_ZEROHALFCUTS ZeroHalfCuts

* Gurobi使用了不同的算法,但得到了相似的结果。同样,这只是您在CPLEX中可能使用的参数的部分列表。如果您正在修改不在此列表中的参数,我们鼓励您浏览参考手册中的Gurobi参数列表

查看手册

一旦知道想要更改哪些参数,更改它们所需的代码就很简单了。在C语言中,调用grbsettparam /GRBsetdblparam/GRBsetstringparam。在我们的面向对象接口中,您调用GRBEnv对象的set()方法。当从CPLEX迁移到Gurobi时,有时会让人们感到困惑的一点是,Gurobi为每个模型提供了自己的Gurobi环境的副本,因此允许每个模型拥有自己的参数设置。在CPLEX中,所有模型使用相同的参数值。最简单的管理方法是为模型设置如下参数:

语言 命令
C 错误= GRBsetintparam(GRBgetenv(model), GRB_INT_PAR_SOLUTIONLIMIT, 1);
c++ model.getEnv()。集(GRB_IntParam_SolutionLimit, 1);
c# model.GetEnv()这里(GRB.IntParam。SolutionLimit, 1);
Java model.getEnv()这里(GRB.IntParam。SolutionLimit, 1);
Python model.params.solutionLimit = 1

计算并提取解

一旦您制定了您的优化模型和设置求解器参数,最后一步是计算一个解。手机万博登录你可以通过在C中调用GRBoptimize()或在面向对象的接口中调用GRBModel.optimize()来实现。当您要求的终止条件之一(优化差距、时间限制、解限制等)得到满足时,优化将完成。一旦优化完成,您应该始终检查它的状态。同样,我们不是提供几十个get/set例程,而是将状态作为模型的一个属性返回。您可以使用适当的属性查询它得到例行公事。例如:

语言 命令
C error = GRBgetintattr(model, GRB_INT_ATTR_STATUS, &status); / /获取状态if (status == GRB_OPTIMAL)…
c++ if (model.get(GRB_IntAttr_Status) == GRB_OPTIMAL)…
c# if (model.Get(GRB.IntAttr.Status) == GRB.OPTIMAL)…
Java if (model.get(GRB.IntAttr.Status) == GRB.OPTIMAL)…
Python 如果模型。状态= =伽马线暴。优:…

决策变量的计算值也是属性:

语言 命令
C error = grbgetdblattreelement (model, GRB_DBL_ATTR_X, x_index, &xvalue); / /将数据复制printf("变量x的值是%g\n", xvalue);
c++ cout << "Value for variable x is: " << x.get(GRB_DoubleAttr_X) << endl;
c# 控制台。WriteLine("变量x的值是:" + x. get (grb . doubleattrx));
Java system . out。println("变量x的值是:" + x.get(grb . doubleattrn . x));
Python print('变量x的值是:',x.x)

您还可以使用属性接口检索其他解决方案信息,包括客观值、约束松弛和双变量(可用时)。让我们重申一下,如果您希望将CPLEX get/set函数映射到Gurobi,那么您可能会在我们的属性接口中找到它的等效物。当然,找到一个经过验证的最佳解决方案并不是唯一可能的结果。例如,您可能会发现您的模型是不可行的。如果您正在使用CPLEX冲突细化器来帮助诊断不可行性,Gurobi通过我们的不可约不一致子系统(IIS)例程(C语言中的GRBcomputeIIS();model.computeIIS()在面向对象接口中)。如果您正在使用CPLEX feasopt特性来寻找模型中约束的最小成本松弛,那么您可以使用Gurobi feasRelax特性(C语言中的GRBfeasrelax();模型。面向对象接口中的feasRelax)。

结论

我们鼓励您浏览Gurobi示例例子之旅以便更具体地了解Gurobi接口的结构。客户告诉我们,一旦理解了一些关键概念,迁移过程就会非常简单,通常非常快。

查看示例指南

商业许可证

新用户:Gurobi允许您试用一个免费的、全功能的、商业评估许可证,有效期为30天。在此期间,你还会得到:

  • 免费的基准测试服务
  • 免费模型调优服务
  • 获得Gurobi世界级的技术支持
  • 两小时免费一对一咨询服务

受COVID-19影响的现有客户须知:如果您在访问Gurobi Optimizer时遇到困难,请使用此表格申请临时许可。

学术使用者须知:被认可的学位授予机构的学术用户可以获得免费的学术许可证。你可以了解我们的学术项目在这里。无法查看窗体?请点击这里在新窗口中打开它。

谢谢你!信息已成功提交。