小说网站排名人气,哪里做网站的,wordpress 拼图,wordpress滑块验证码addVar 和 addVars作为 Gurobi模型对象中的方法#xff0c;常常用来生成变量#xff0c;本文介绍了Python中的这两个接口的使用
addVar addVar(lb0.0, ubfloat(inf), obj0.0, vtypeGRB.CONTINUOUS, name, columnNone) lb 和 ub让变量在生成的时候就有下界和上届#xff0c…addVar 和 addVars作为 Gurobi模型对象中的方法常常用来生成变量本文介绍了Python中的这两个接口的使用
addVar addVar(lb0.0, ubfloat(inf), obj0.0, vtypeGRB.CONTINUOUS, name, columnNone) lb 和 ub让变量在生成的时候就有下界和上届
obj 确定了生成的变量在 目标函数的系数的取值
vtype 确定了变量取值的类型 (GRB.CONTINUOUS, GRB.BINARY, GRB.INTEGER, GRB.SEMICONT, or GRB.SEMIINT)
name 确定了这个参数的名字
column这个参数可以用来确定在已经存在的约束条件中这个变量的系数但是由于在新版本中可以直接在生成约束条件(即调用addConstr)的时候就直接指定具体的约束条件所以column参数并不经常使用但是下面的代码还是给出这个参数的使用方法 max 3x 2y x y 10 2x y 15 x 0, y 0 m gp.Model(example)
m.setParam(OutputFlag, 0) # 优化完成后不打印许可和/或计算服务器信息
# 添加约束
c1 m.addConstr(0, GRB.LESS_EQUAL, 10, namec1)
c2 m.addConstr(0, GRB.LESS_EQUAL, 15, namec2)# 使用column参数添加变量
x m.addVar(lb0, ubGRB.INFINITY, obj3, vtypeGRB.CONTINUOUS, namex, columngp.Column([1, 2], [c1, c2]))
y m.addVar(lb0, ubGRB.INFINITY, obj2, vtypeGRB.CONTINUOUS, namey, columngp.Column([1, 1], [c1, c2]))# 设置目标函数最大化 3x 2y由于所有的决策变量和约束条件都以已经确定
# 而且gurobi中是默认最大化目标函数所以下面这句话可以选择不打
# m.setObjective(3 * x 2 * y, GRB.MAXIMIZE)# 优化模型
m.optimize()if m.status GRB.OPTIMAL:# 打印结果
else:# 无解
有了新版的设计可以直接写成如下形式
m gp.Model(example)
m.setParam(OutputFlag, 0)
x m.addVar(lb0, ubGRB.INFINITY, vtypeGRB.CONTINUOUS, obj3, namex)
y m.addVar(lb0, ubGRB.INFINITY, vtypeGRB.CONTINUOUS, obj2, namey)m.addConstr(x y 10, namec1)
m.addConstr(2 * x y 15, namec2)m.optimize()if m.Status GRB.OPTIMAL:print(fOptimal solution is {x.x}, {y.x})print(fOptimal value is {m.objVal})
else:print(No solution!)
值得注意的是 1. 调用addVar变量之后返回值是与addVar中传入的参数不同的比如 写下 x m.addVar() 这句代码之后这个变量名 x 是你在Python代码中用来操作和引用这个变量的标识符。 而调用y model.addVar(vtypeGRB.INTEGER, obj1.0, namey)其中name y的参数就是在Gurobi模型内部使用用于在模型的输出、日志文件或错误消息中标识该变量 2.调用 addVar接口其返回值的类型是 gurobipy.Var返回的这个变量可以直接和整数进行加减乘除运算运算的结果可以作为目标函数或者约束条件但是不能直接与浮点数进行非线性运算如 x m.addVar(); x ** 0.5; 但是可以使用其他方法实现非线性约束的效果具体可以看我其他的博客 addVars addVars ( *indices , lb0.0 , ubfloat(inf) , obj0.0 , vtypeGRB.CONTINUOUS , name ) 与addVar不同的是addVars的第一个参数是一个参数包对这个参数包可以传入多种形式的参数包括 1. 数字序列: x m.addVars(2, 3, 2)x 是一个包含 2 * 3 * 2 个键值对的 tupledict 2. 单个list: x m.addVars( [1, 2, 3, 4] )x 是以 1, 2, 3, 4 为key 的 tupledict 3. 多个list: x m.addVars( [1, 2], [a, b] )x 是以(1, a) 和 (2, b)为 key 的tupledict 4. tuplelist: x m.addVars( [ (3, a), (7, b) ] )x 是分别以这两个元组为 key 的 tupledict 可以看到addVars在调用的过程中会生成很多变量这些变量应该怎么配合lb, ub, obj, vtype, name 这些参数实现不同的变量设置不同的属性
使用列表即可比如如下代码
z m.addVars(3, obj[1.0, 2.0, 1.2], name[a, b, c])
将会生成以0, 1, 2为key的三个键值对为tupledict对象的内容其中z1的系数是1.0在 gurobi 内部的名称是“a”, 以此类推这样一下生成3个变量的同时还可以规定这三个变量的系数和名称
addVar 和 addVars的返回值
addVar 的返回值类型是 class gurobipy.Var
addVars 的返回值类型是 class gurobipy.tupledict
所以想要使用这两种方法的返回值构建一个表达式需要将 addVars 的返回值转成其他形式
可以使用 sum() 方法代码示例如下
y m.addVar(vtypeGRB.CONTINUOUS, namey1)
z m.addVars(3, obj[1.0, 2.0, 1.2], name[z1, z2, z3])
m.update()
print(y z.sum())
代码将打印 y1 z1 z2 z3
添加变量到底是在干什么 我们知道Gurobi 作为一个优化问题的求解器构建模型的过程实际上就是在声明和定义变量调用 addVar(s) 方法实际上就是将这些声明和定义后的变量进行暂存 暂存过程包括对变量的暂存和对约束条件的暂存 在调用addVar(s) 和 addConstr系列方法之后 1. 变量会被暂存到模型的内部变量列表中。这些变量在暂存状态下不会被完全初始化但Gurobi会记录它们的基本信息如变量类型、上下界、目标函数系数等 2. 约束条件会被暂存到模型的内部约束列表中。这些约束在暂存状态下不会被完全初始化但Gurobi会记录它们的基本信息如约束类型、左侧表达式、右侧常数等 然后这些变量 / 表达式将 处于暂存状态 暂存状态的可视化
添加变量并直接打印这个变量
z m.addVars(3, obj[1.0, 2.0, 1.2])
print(z) 打印结果 {0: gurobi.Var *Awaiting Model Update*, 1: gurobi.Var *Awaiting Model Update*, 2: gurobi.Var *Awaiting Model Update*} 暂存的意义 性能优化 Gurobi在内部进行了优化避免在每次添加变量或约束时立即进行更新因为这可能会导致不必要的性能开销。通过将这些操作暂存起来Gurobi可以在适当的时候一次性进行更新提高效率。 批量处理 在添加大量变量和约束时批量更新可以显著提高性能。例如当你在循环中添加大量变量和约束时调用一次 model.update() 比每次添加一个变量或约束后都调用 model.update() 要高效得多。
Gurobi 模型的 update() 方法 Gurobi 会遍历这些暂存的变量和约束将它们完全初始化并添加到模型的内部数据结构中所谓的添加到内部数据结构就是给变量 / 约束分配一个唯一的索引 在调用 update() 方法之后这些变量 / 表达式将 处于完全初始化状态 完全初始化状态的可视化
添加变量更新之后再打印这个变量
z m.addVars(3, obj[1.0, 2.0, 1.2], name[z1, z2, z3])
m.update()
print(z) 打印结果 {0: gurobi.Var z1, 1: gurobi.Var z2, 2: gurobi.Var z3}