如何基于多列表使用Gurobi的addVars函数创建绑定数值的需求变量
问题解答:正确用Gurobi创建需求变量/参数
我来帮你理清楚这个问题~你现在的困惑主要是搞错了Gurobi里addVars函数obj参数的作用,以及混淆了模型参数和决策变量的区别:
1. 你当前代码的问题
addVars里的obj=value参数,是用来设置这些变量在目标函数中的系数,而不是给变量赋予固定的需求值。所以你打印的是Gurobi的变量对象,自然看不到value里的数值——这些数值只是告诉模型“在优化目标时,这个变量的权重是多少”,不是变量本身的取值。
2. 正确的处理方式
首先要明确:你的需求(客户c在时间t的数值)是已知的输入参数,不是需要模型求解的决策变量。这种情况下,根本不需要用addVars创建变量,直接用字典存储即可:
方案1:用字典存储需求参数(推荐,适用于已知需求的场景)
customer = ["c1","c1","c1","c2","c2","c2","c3","c3","c3"] time = [1,2,3, 1,2,3, 1,2,3] value = [4, 8, 9, 2, 3, 4, 5, 7, 9] # 把(customer, time)作为键,value作为值,创建需求字典 demand_params = dict(zip(zip(customer, time), value)) # 直接获取对应需求值 print(demand_params[("c1", 1)]) # 输出4 print(demand_params[("c3", 3)]) # 输出9
方案2:如果确实需要把需求设为固定值的变量(特殊建模场景)
如果因为某些原因,你必须把需求做成Gurobi变量(比如需求是固定值,但需要参与约束),可以通过设置变量的上下界为同一个值,或者添加约束来固定变量取值:
import gurobipy as gp from gurobipy import GRB model = gp.Model() customer = ["c1","c1","c1","c2","c2","c2","c3","c3","c3"] time = [1,2,3, 1,2,3, 1,2,3] value = [4, 8, 9, 2, 3, 4, 5, 7, 9] indices = list(zip(customer, time)) # 方式1:创建变量时直接设置上下界为需求值,固定变量 demand = model.addVars(indices, lb=value, ub=value, name="demand") # 方式2:先创建变量,再添加约束固定值 # demand = model.addVars(indices, name="demand") # for idx, val in zip(indices, value): # model.addConstr(demand[idx] == val, name=f"fix_demand_{idx}") # 优化后即可获取变量的固定值 model.optimize() for idx in indices: print(f"{demand[idx].VarName} = {demand[idx].X}")
总结
- 如果你只是需要存储和引用已知的需求数据,用字典就足够了,这是最直接高效的方式。
- 只有当需求是需要模型求解的未知决策变量时,才需要用
addVars创建变量;如果要固定变量值,不要用obj参数,而是通过上下界或约束实现。
内容的提问来源于stack exchange,提问作者Tobias
相关产品推荐
相关产品推荐

