如何在Pyomo中动态地将变量添加到列表中?

2024-09-20 23:04:30 发布

您现在位置:Python中文网/ 问答频道 /正文

作为创建具体模型时触发的BuildAction规则的一部分,我动态地创建额外的“内部”决策变量(取决于构建时提供的数据)

除了创建这些变量(在约束表达式中使用),我知道我还需要将它们添加到模型中,以避免“变量'XXX'不是要写出的模型的一部分,而是出现在这个模型上使用的表达式中。”错误

VarList类似乎就是为此而设计的(类似于ConstraintList类,我已经成功地将其用于动态创建的约束)。但是,我找不到关于如何从预先创建的变量填充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,但是我找不到说明这是如何工作的文档或示例


Tags: 数据文档模型self表达式规则错误动态
1条回答
网友
1楼 · 发布于 2024-09-20 23:04:30

VarList的工作原理与Pyomo中的IndexedVar非常相似 您需要了解以下几点:

  1. 变量索引不断变化,这意味着您需要检查实际长度,以避免添加您不使用的变量,或使用尚未添加的变量

  2. VarList().add()方法将变量添加到变量类型中。这意味着,如果VarList()被创建为整数或非负变量,则您将添加的所有变量将分别为整数或非负变量

我将写下一个示例,向您展示它的工作原理:

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类,其工作原理与此方法非常类似。您可以在Pyomo documentation中检查它,不同的是您可以将不同类型的变量分配给同一个列表

我不完全理解您在建模什么,但是您可以始终使用AbstractModel()类,然后使用model.create_instance(data=data)填充一些外部数据(无论是.dat文件还是dict)。这样,您的模型总是在某些已定义的集合中参数化

相关问题 更多 >

    热门问题