如何动态添加变量以在 Pyomo 中列出?
How do I dynamically add variables to list in Pyomo?
作为在创建具体模型时触发的 BuildAction 规则的一部分,我正在动态创建额外的“内部”决策变量(取决于构建时提供的数据)。
除了创建这些变量(在约束表达式中使用),我知道我还需要将它们添加到模型中以避免“变量 'XXX' 不是正在编写的模型的一部分出来,但出现在这个模型上使用的表达中。”错误。
VarList class 似乎是为此而设计的(类似于我已经成功用于动态创建约束的 ConstraintList class)。但是,我找不到有关如何从预先创建的变量填充 VarList 的文档。我可以创建一个 VarList 并向其添加变量,但这并不能让我控制变量的创建方式...
import pyomo.environ as pyo
self.vl = pyo.VarList()
newVar = self.vl.add() # this does not give me control over the variable creation
# and I can't set all required properties of newVar, once created
似乎我应该能够通过传递变量字典来创建 VarList,但我找不到说明其工作原理的文档或示例。
VarList
与 Pyomo
中的 IndexedVar
非常相似
你需要了解几件事:
变量索引是不断变化的,这意味着你需要检查实际长度,以避免添加你不会使用的变量,或者使用没有添加的变量。
VarList().add()
方法为一类变量添加变量。这意味着如果 VarList()
被创建为 Integer 或 NonNegativeReal 变量,您将添加的所有变量将分别为 Integer 或 NonNegativeReal
我将写下一个示例来向您展示它是如何工作的:
import pyomo.environ as pyo
#set the model
model = pyo.ConcreteModel()
#add variables in a for loop
#using add() method will add the variables
model.x = pyo.VarList(domain=pyo.Integers)
for i in range(2):
model.x.add() #Add a new index to defined variable x
#adding constraints
#Indexed variable starts at 1 and not in 0
model.myCons1 = pyo.Constraint(expr=2*model.x[1] + 0.5*model.x[2] <=20)
model.myCons2 = pyo.Constraint(expr=2+model.x[1] + 3*model.x[2] <=25)
#add an objective
model.Obj = pyo.Objective(expr=model.x[1] + model.x[2], sense=pyo.maximize)
#Solvint using gurobi
solver = pyo.SolverFactory('gurobi')
solver.solve(model, tee=True)
#Display the x variable results
model.x.display()
这导致以下输出(我将省略求解器输出的大部分)
Optimal solution found (tolerance 1.00e-04)
Best objective 1.300000000000e+01, best bound 1.300000000000e+01, gap 0.0000%
x : Size=2, Index=x_index
Key : Lower : Value : Upper : Fixed : Stale : Domain
1 : None : 8.0 : None : False : False : Integers
2 : None : 5.0 : None : False : False : Integers
如果您开始使用 kernel
建模层,您还可以使用 pyomo.kernel.variable_list
class,其工作方式与此方法非常相似。您可以在 Pyomo documentation 中检查它,不同之处在于您可以将不同类型的变量分配给同一个列表
我不完全明白你在建模什么,但你总是可以使用 AbstractModel()
class 然后用一些外部数据填充它(无论是 .dat
文件还是字典)使用 model.create_instance(data=data)
。这样,你的模型总是在一些定义的集合中被参数化。
作为在创建具体模型时触发的 BuildAction 规则的一部分,我正在动态创建额外的“内部”决策变量(取决于构建时提供的数据)。
除了创建这些变量(在约束表达式中使用),我知道我还需要将它们添加到模型中以避免“变量 'XXX' 不是正在编写的模型的一部分出来,但出现在这个模型上使用的表达中。”错误。
VarList class 似乎是为此而设计的(类似于我已经成功用于动态创建约束的 ConstraintList class)。但是,我找不到有关如何从预先创建的变量填充 VarList 的文档。我可以创建一个 VarList 并向其添加变量,但这并不能让我控制变量的创建方式...
import pyomo.environ as pyo
self.vl = pyo.VarList()
newVar = self.vl.add() # this does not give me control over the variable creation
# and I can't set all required properties of newVar, once created
似乎我应该能够通过传递变量字典来创建 VarList,但我找不到说明其工作原理的文档或示例。
VarList
与 Pyomo
中的 IndexedVar
非常相似
你需要了解几件事:
变量索引是不断变化的,这意味着你需要检查实际长度,以避免添加你不会使用的变量,或者使用没有添加的变量。
VarList().add()
方法为一类变量添加变量。这意味着如果VarList()
被创建为 Integer 或 NonNegativeReal 变量,您将添加的所有变量将分别为 Integer 或 NonNegativeReal
我将写下一个示例来向您展示它是如何工作的:
import pyomo.environ as pyo
#set the model
model = pyo.ConcreteModel()
#add variables in a for loop
#using add() method will add the variables
model.x = pyo.VarList(domain=pyo.Integers)
for i in range(2):
model.x.add() #Add a new index to defined variable x
#adding constraints
#Indexed variable starts at 1 and not in 0
model.myCons1 = pyo.Constraint(expr=2*model.x[1] + 0.5*model.x[2] <=20)
model.myCons2 = pyo.Constraint(expr=2+model.x[1] + 3*model.x[2] <=25)
#add an objective
model.Obj = pyo.Objective(expr=model.x[1] + model.x[2], sense=pyo.maximize)
#Solvint using gurobi
solver = pyo.SolverFactory('gurobi')
solver.solve(model, tee=True)
#Display the x variable results
model.x.display()
这导致以下输出(我将省略求解器输出的大部分)
Optimal solution found (tolerance 1.00e-04)
Best objective 1.300000000000e+01, best bound 1.300000000000e+01, gap 0.0000%
x : Size=2, Index=x_index
Key : Lower : Value : Upper : Fixed : Stale : Domain
1 : None : 8.0 : None : False : False : Integers
2 : None : 5.0 : None : False : False : Integers
如果您开始使用 kernel
建模层,您还可以使用 pyomo.kernel.variable_list
class,其工作方式与此方法非常相似。您可以在 Pyomo documentation 中检查它,不同之处在于您可以将不同类型的变量分配给同一个列表
我不完全明白你在建模什么,但你总是可以使用 AbstractModel()
class 然后用一些外部数据填充它(无论是 .dat
文件还是字典)使用 model.create_instance(data=data)
。这样,你的模型总是在一些定义的集合中被参数化。