Gurobi + Python

自学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

 

 

 

 
  • 6
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是使用GurobiPython求解双目标线性规划的示例代码: ```python import gurobipy as gp # 创建模型 model = gp.Model('bilevel_problem') # 创建变量 x1 = model.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name='x1') x2 = model.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name='x2') y1 = model.addVar(lb=0, ub=gp.GRB.INFINITY, vtype=gp.GRB.CONTINUOUS, name='y1') y2 = model.addVar(lb=0, ub=gp.GRB.INFINITY, vtype=gp.GRB.CONTINUOUS, name='y2') # 创建约束条件 constr1 = model.addConstr(2*x1 + x2 <= y1, name='constr1') constr2 = model.addConstr(x1 + 2*x2 <= y2, name='constr2') # 定义目标函数 model.setObjective(y1 + y2, gp.GRB.MINIMIZE) # 创建子问题 submodel1 = gp.Model('subproblem1') submodel2 = gp.Model('subproblem2') # 创建子问题变量 subx1 = submodel1.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name='subx1') subx2 = submodel1.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name='subx2') suby1 = submodel1.addVar(lb=0, ub=gp.GRB.INFINITY, vtype=gp.GRB.CONTINUOUS, name='suby1') submodel1.update() subx1 = submodel2.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name='subx1') subx2 = submodel2.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name='subx2') suby2 = submodel2.addVar(lb=0, ub=gp.GRB.INFINITY, vtype=gp.GRB.CONTINUOUS, name='suby2') submodel2.update() # 创建子问题约束条件 subconstr1 = submodel1.addConstr(2*subx1 + subx2 <= suby1, name='subconstr1') submodel1.setObjective(suby1, gp.GRB.MAXIMIZE) subconstr2 = submodel2.addConstr(subx1 + 2*subx2 <= suby2, name='subconstr2') submodel2.setObjective(suby2, gp.GRB.MAXIMIZE) # 添加双层问题约束条件 model.addConstr(suby1 <= y1, name='subconstr1') model.addConstr(suby2 <= y2, name='subconstr2') # 求解模型 model.optimize() # 输出结果 print('x1=', x1.x) print('x2=', x2.x) print('y1=', y1.x) print('y2=', y2.x) ``` 在上面的代码中,我们定义了四个变量和两个约束条件,然后为目标函数设置了两个目标。接下来,我们创建了两个子问题,并分别定义了它们的变量和约束条件。然后,我们将子问题的解添加到双层问题的约束条件中,并使用 `optimize()` 方法求解模型。最后,我们输出了模型的解。 需要注意的是,双目标线性规划具有较高的计算复杂度和较多的局限性,需要根据具体问题进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值