假设我创建了一个JuMP模型,将其传递给求解器并检索了一个解决方案。现在,我要确定由Gurobi(即在预求解之后)求解的模型是否是混合整数程序(MIP)。我需要此信息,因为我想打印解决方案的MIP差距(如果存在)。显然,不一定要事先知道JuMP模型是否实际上是MIP,或者是否所有整数变量都可以通过presolve除去。
此代码示例创建一个简单模型(不包含任何整数变量)并解决该问题:
import JuMP
import Gurobi
model = JuMP.Model(Gurobi.Optimizer)
JuMP.@variable(model, x)
JuMP.@constraint(model, x>=0)
JuMP.@objective(model, Min, x)
JuMP.optimize!(model)
如果问题是(甚至在预先解决之后)MIP,我也可以使用
mip_gap = JuMP.relative_gap(model)
以获取MIP差距。但是在上述情况下(即不是MIP),它会触发
错误:Gurobi.GurobiError(10005,“无法检索属性'MIPGap'”)
也不起作用的是
mip_gap = JuMP.get_optimizer_attribute(model, "MIPGap")
因为这将返回用作终止标准的MIP间隙(即不是实际解决方案的MIP间隙)。
在JuMP和MathOptInterface的源代码中没有找到直接返回MIP差距的函数。但是,Gurobi有一个名为IsMIP的模型属性,应该可以访问。但是
is_mip = JuMP.get_optimizer_attribute(model, "IsMIP")
原因
错误:LoadError:无法识别的参数名称:IsMIP。
我还尝试在Gurobi.jl中找到解决方案,并发现实现了here的Gurobi参数“ IsMIP”。还有一个名为is_mip的函数确实可以实现我想要的功能。问题是,我不能使用它,因为参数必须是Gurobi Model,而不是JuMP模型。
我该怎么办?
答案 0 :(得分:2)
不幸的是,有很多事情结合在一起导致了您的问题。
1)JuMP的“优化器属性”对应于Gurobi的“参数”。因此,您只能使用get/set_optimizer_attribute
来查询公差等内容。这就是为什么您可以查询MIPGap
(一个Gurobi参数)但不能查询IsMIP
(一个Gurobi模型属性)的原因。
2)不用担心,因为您应该能够按以下方式访问Gurobi模型属性(和变量/约束属性):
MOI.get(model, Gurobi.ModelAttribute("IsMIP"))
3)但是,似乎在堆栈中的某个地方存在一个错误,这意味着我们在尝试从JuMP转到Gurobi时,错误地重定向了该调用。作为解决方法,您可以使用
MOI.get(backend(model).optimizer, Gurobi.ModelAttribute("IsMIP"))
我已提出问题,因此在以后的版本(https://github.com/JuliaOpt/MathOptInterface.jl/issues/1092)中得到解决。