Gurobi创建数学模型的顺序
- 创建决策变量
addVar()
- 整合变量
update()
- 创建目标函数
setObjective()
- 创建约束
addConstr()
- 优化
optimize()
拿一段代码举个例子
import gurobipy as gp
# 创建模型
model = gp.Model()
# 定义变量
x = model.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name="x")
y = model.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name="y")
# 添加初始约束
model.addConstr(x + y <= 1, name="c1")
# 更新模型,添加新变量和约束
model.update()
# 定义新变量
z = model.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name="z")
# 添加新约束
model.addConstr(y + z <= 1, name="c2")
# 更新模型,确保新变量和约束被加入
model.update()
# 设置目标函数
model.setObjective(x + y + z, sense=gp.GRB.MAXIMIZE)
# 求解优化问题
model.optimize()
# 输出结果
print("Optimal solution:")
for v in model.getVars():
print(f"{v.varName} = {v.x}")
print(f"Optimal objective value: {model.objVal}")
- Q1:一定要用
model()
方法么?
A1:当然!需要先创建优化模型并在这个模型上定义变量、约束和目标函数,最后进行求解。
model = gp.Model()
- Q2:
vtype
是什么?都有哪些类型?
A2:在 Gurobi 中,变量的类型vtype
用于指定变量的性质,即它是离散变量还是连续变量。
GRB.CONTINUOUS
: 连续型变量,可以取任何实数值。
GRB.BINARY
: 二元变量,取值为 0 或 1,常用于表示选择性决策。
GRB.INTEGER
: 整数变量,取值为整数。
GRB.SEMICONT
: 半连续变量,可以取实数值,但在某个范围内只能为 0 或者非零。
GRB.SEMIINT
: 半整数变量,取值为整数,但在某个范围内只能为 0 或者非零。
# 定义了两个连续变量
x = model.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name="x")
y = model.addVar(lb=0, ub=1, vtype=gp.GRB.CONTINUOUS, name="y")
- Q3:一般什么时候用
update()
方法呢?
A3:Gurobi官方文档里是这样说的,“如果你在模型里进行了非阶段性更改”,就要使用update()
方法。
有时候,我们可能希望根据某些条件动态地添加变量或约束。
因此,一种常见情况是在模型的初始状态下只添加一部分变量或约束,然后在后续的迭代中逐步添加其他变量或约束。这种情况下,你可以在每次迭代之前使用model.update()
来更新模型,以便包含最新的变量和约束。
另外,使用model.update()
方法也可以减少构建模型时的内存消耗,特别是当模型非常大或包含大量约束和变量时。通过分批次地添加变量和约束,可以降低内存占用并提高性能。
# 更新模型,确保新变量和约束被加入
model.update()
- Q4:
sense
有哪些可选参数?
A4:在Gurobi中,目标函数的方向由sense
指定,它表示优化问题是最大化还是最小化。sense
参数有以下可选参数:
GRB.MAXIMIZE
: 表示最大化目标函数。
GRB.MINIMIZE
: 表示最小化目标函数。