自学Gurobi的时候发现国内缺乏相对应的教程,大多止于浅层的gurobi安装和搭载,稍微深入点也只是最基础的模型建立:add variable, update, add constraint, set objective, optimize 和基本的读写。 甚至缺乏对于结果的解读。
Google到的内容比 百度 多的多。
最好的资料当然是官网的 http://www.gurobi.com/documentation/ 的 Example Tour 和 Referenec Manual;
存档一下学习中遇到的坑。
1. addConstr()
只能 ==, <=, >= ,不能<, >
2. if ... else
如果想实现 if x>0 : a = 1 ; else : a = 0
不能直接实现,要进行一定的转化。
x <= a * A <= A + x - B (A 为足够大的常数,B为足够小的正数(小于x可能达到的最小值,大于0),a为binary)
3. max_(), abs_()
这些函数,括号里面都必须是variable,不能是LinExpr(), 有必要的话,可以建成新的variable再使用max_()和abs_()函数
当结果是Model is infeasible 时:利用 Model.computeIIS() 来查问题(虽然我认为并不是太好用)
Reference :https://nathanbrixius.wordpress.com/2012/09/28/detecting-the-sources-of-model-infeasibility-using-gurobi/
model = Model()
vars = model.getVars()
constrs = model.getConstrs()
for i in range (len(constrs)):
print (constrs[i].getAttr(GRB.Attr.IISConstr))
for i in range(len(solution)):
print (solution[i].getAttr(GRB.Attr.IISLB), " ", vars[i].getAttr(GRB.Attr.IISUB))
输出 1 有问题; 0 没问题
4. 如何输出指定个数的较优解
PoolSearchMode 表示Gurobi搜索最优解的方式。 默认值为0,表示目标为搜索唯一最优解;设定为1,表示搜索多个解,但不保证解的质量;设定为2,表示搜索多个解,优先取高质量的解。
PoolSolutions 表示存储的解的个数。改变该参数并不能改变该模型的可行解个数。但在使用过程中发现,当PoolSearchModel = 2, 如果有很多个可行解,SolCount不会显示实际可行解个数(由于运行时间限制),此时改变PoolSolutions可改变SolCount,得到更多可行解。
X 当PoolSearchMode为默认值0时,求解得到唯一解,存储在X中,可通过以下代码得到该解
model = Model()
vars_x = model.addVar(lb=0, ub = 1, vtype = GRB.CONTINUOUS)
....
vars = model.getVars()
print ("最优解为"vars[0].getAttr("X"))
Xn 当PoolSearchMode为1或者2时,得到多个解(包括sub-optimal),存储在Xn中,可通过以下代码得到解。其中当SolutionNumber 设置为 0 时, 得到的解与 X 相同
model = Model()
vars_x = model.addVar(lb=0, ub = 1, vtype = GRB.CONTINUOUS)
model.setParam("PoolSearchMode",2)
model.setParam("PoolSolutions",10)
....
vars = model.getVars()
for i in range(10):
model.setParam("SolutionNumber",i)
print ("最优解为"vars[0].getAttr("Xn"))
SolCount 表示搜索得到的解个数,SolutionNumber一定小于SolCount
SolutionNumber 表示得到的解个数,可以将这个参数看作Xn的index,范围为[0,SolCount-1]。每修改一次,输出不同的Xn