Gurobi笔记(使用手册)
一、基本了解
1、求解范围
- 连续问题、整数问题、线性和二次凸问题、二次非凸问题、广义非线性问题等
- 广义非���性问题——广义函数约束
函数形式可以是高阶多项式、对数、指数、三角函数等非线性函数,那么Gurobi 会对这些函数自动分段线性化进行近似,用户可以通过参数来平衡近似的精度和速度。这样我们就允许在传统的线性和二次型模型中看到这些非线性函数,大大扩展了Gurobi求解器的适用范围,而且这些结果也具有全局最优性。
2、求解速度
线性规划速度 > 0-1 整数线性规划 > 整数线性规划 > 混合整数线性规划 > 非线性规划
在现实问题中,应用最广泛的数学规划问题类型是混合整数线性规划(MILP)。
3、学习资料
- 安装目录 examples, docs 目录下有完整的范例和使用手册、参考手册
- 官网 www.gurobi.com
- 在线手册:http://www.gurobi.com/documentation/
- 视频:http://www.gurobi.com/resources/seminars-andvideos/seminars-videos
- 在线课程:http://www.gurobi.com/academia/for-online-courses
- 中文网站 www.gurobi.cn
二、快速入门
1.常规步骤
MODEL = gurobipy.Model()#创建模型 x = MODEL.addVars(创建变量, vtype=gurobipy.GRB.CONTINUOUS, name="X")#创建变量 MODEL.update()#更新变量环境 MODEL.setObjective(创建目标函数, sense=gurobipy.GRB.MINIMIZE)#创建目标函数 MODEL.addConstrs(创建约束条件) #创建约束条件 MODEL.optimize() #执行最优化
2.基础模型
3.详细步骤
3.1 实例化求解器
MODEL = gurobipy.Model(name="") name 为模块名默认为空
import gurobipy as GRB MODEL = GRB.Model("Model_name") #创建模型
3.2 添加决策变量
(1) 单个变量
x = MODEL.addVar(lb=0.0, ub=gurobipy.GRB.INFINITY, vtype=gurobipy.GRB.CONTINUOUS, name="")
lb = 0.0 #变量的下界,默认为 0 ub = GRB.INFINITY: 变量的上界,默认为无穷大 vtype = GRB.CONTINUOUS #变量的类型,默认为连续型,可改为 GRB.BINARY 0-1变量,GRB.INTEGER 整型 name = "" #变量名,默认为空
x1 = MODEL.addVar(lb=0, ub=1, name="x1")
(2) 多个变量
x = MODEL.addVars(*indexes, lb=0, ub=gurobipy.GRB.INFINITY, vtype=gurobipy.GRB.CONTINUOUS, name="") # *indexes 不能含有中文字符 索引的集合 x = MODEL.addVars(3, 4, 5, vtype=gurobipy.GRB.BINARY, name="C") # 创建 3*4*5 个变量,使用 x[1,2,3] 进行访问
3.3 更新变量空间
MODEL.update()
3.4 添加目标函数
(1) 单目标函数
MODEL.setObjective(expression, sense=None) expression #表达式,可以是一次或二次函数类型 sense #求解类型,可以是 GRB.MINIMIZE(最小值) 或 GRB.MAXIMIZE(最大值) MODEL.setObjective(8 * x1 + 10 * x2 + 7 * x3 + 6 * x4 + 11 * x5 + 9 * x6, GRB.GRB.MINIMIZE)
(2) 多目标函数
MODEL.setObjectiveN(expression, index, priority=0, weight=1.0, abstol=0, reltol=0, name="") expression # 表达式,可以是一次或二次函数类型 index # 目标函数对应的序号 (默认 0,1,2,…), 以 index=0 作为目标函数的值, 其余值需要另外设置参数 priority # 分层序列法多目标决策优先级(整数值), 值越大优先级越高 weight #线性加权多目标决策权重(在优先级相同时发挥作用) abstol # 分层序列法多目标决策时允许的目标函数值最大的降低量 reltol #分层序列法多目标决策时允许的目标函数值最大的降低比率 reltol*|目标函数值|
注意: 所有的目标函数都为线性的,并且目标函数的优化方向一致(全部最大化或全部最小化)。可以通过乘以 -1 实现不同的优化方向。
1.合成型
# Obj1 = x + y weight = 1 # Obj2 = x - 5 * y weight = -2 # MODEL.setObjectiveN(x + y, index=0, weight=1, name='obj1') # MODEL.setObjectiveN(x -5 * y, index=1, weight=-2, name='obj2') # 即转化为: (x + y) - 2 * (x - 5 * y) = - x + 11 * y
2.分层型
# Obj1 = x + y priority = 5 # Obj2 = x - 5 * y priority = 1 # MODEL.setObjectiveN(x + y, index=0, priority=5, name='obj1') # MODEL.setObjectiveN(x -5 * y, index=1, priority=1, name='obj2') # 即转化为: 先优化 Obj1,再优化 Obj2(按照 priority 的大小关系)
注意: Gurobi 按照优先级大小优化(先优化Obj1),若没有设定abstol或reltol,在优化低优先级目标时,不会改变高优先级的目标值。假设Obj1=10,在优化 Obj2 时只能在使得 Obj1=10 的所有解中挑选最优解
3.混合型
MODEL.setObjectiveN(x + y, index=0, weight=1, priority=5, name='obj1') MODEL.setObjectiveN(x -5 * y, index=1, weight=-2, priority=1, name='obj2') # 则 先优化 Obj1 再优化 Obj2 最后相加作为目标值, 由于优先级不同, weight不会起作用
4.获取目标函数值
通过参数 ObjNumber 选择特定的目标,进而获得对应的目标函数值。
MODEL.setParam(gurobipy.GRB.Param.ObjNumber, i) # 第 i 个目标 print(MODEL.ObjNVal) # 打印第 i 个值
for i in range(model.NumObj): model.setParam(GRB.Param.ObjNumber, i) print('Obj%d = ' %(i+1), model.ObjNVal)
(3) 分段目标函数
setPWLObj(var,x,y) • var #指定变量的目标函数是分段线性 • x #定义分段线性目标函数的点的横坐标值(非减序列) • y #定义分段线性目标函数的点的纵坐标值
例1:
m.setPWLObj(x, [0, 2, 5], [0, 2, 3]) m.setAttr(GRB.Attr.ModelSense, -1)
注意: 对一些非线性模型,可以使用这一功能去线性逼近。
例2:
m.setPWLObj(x, [0,1/4, 1,7/4, 2], [3,41/9, 2,41/9,3])
3.5 添加约束条件
(1) 创建正常约束
MODEL.addConstr(expression, name="") expression # 布尔表达式,可以是一次或二次函数类型 name # 约束式的名称 # 单个约束 MODEL.addConstr(12 * x1 + 9 * x2 + 25 * x3 + 20 * x4 + 17 * x5 + 13 * x6 >= 60, "c0") # 多个约束 x = MODEL.addVars(20, 8, vtype=gurobipy.GRB.BINARY) # 写法 1 for i in range(20): MODEL.addConstr(x.sum(i, "*")
The End