Gurobi字典序多目标线性规划:时间限制下获取最后目标的MIPGap
解决Gurobi字典序多目标LP时间限制下获取最后目标编号与MIPGap的问题
1. 获取当前正在优化的目标编号
当时间限制触发导致求解中断时,可通过模型的GRB_IntAttr_CurrentObj属性获取当前处理的目标序号(C++ API中为0-based索引,即第一个目标为0,第二个为1,依此类推)。示例代码:
int currentObjIdx = model.get(GRB_IntAttr_CurrentObj);
该属性在求解中断(如GRB_TIME_LIMIT状态)时可正常获取,不会触发报错。
2. 手动计算当前目标的MIPGap
直接调用GRB_DoubleAttr_MIPGap报错(错误码10005)的原因是,时间限制触发时当前目标求解未完成,模型级的MIPGap属性尚未生成或不可用。此时可通过以下逻辑手动计算:
- 获取当前目标的最优可行解目标值:
GRB_DoubleAttr_ObjVal - 获取当前目标的松弛界:
GRB_DoubleAttr_ObjBound - 遵循Gurobi的MIPGap公式计算:
|ObjVal - ObjBound| / (1e-10 + |ObjVal|)
示例代码:
double objVal = model.get(GRB_DoubleAttr_ObjVal); double objBound = model.get(GRB_DoubleAttr_ObjBound); double mipGap = 0.0; // 处理无可行解或数值极小的情况 if (objVal == GRB_INFINITY || objVal == -GRB_INFINITY) { std::cout << "当前目标无可行解,无法计算MIPGap" << std::endl; } else { if (fabs(objVal) < 1e-10) { mipGap = fabs(objBound) / (1e-10 + fabs(objBound)); } else { mipGap = fabs(objVal - objBound) / (1e-10 + fabs(objVal)); } }
3. 注意事项
- 需先判断模型状态是否为
GRB_TIME_LIMIT,再执行上述属性获取与计算操作,避免无效状态下的错误。 - 若当前目标未找到可行解,
ObjVal会返回GRB_INFINITY(最大化目标)或-GRB_INFINITY(最小化目标),此时无法计算有效Gap,需提前做分支处理。
内容的提问来源于stack exchange,提问作者Farah Mind
相关产品推荐
相关产品推荐

