【问题标题】:How do I dynamically add variables to list in Pyomo?如何在 Pyomo 中动态添加变量到列表?
【发布时间】:2021-11-28 07:51:29
【问题描述】:

作为在创建具体模型时触发的 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,但我找不到说明其工作原理的文档或示例。

【问题讨论】:

    标签: python variables pyomo


    【解决方案1】:

    VarList 的工作方式与 Pyomo 中的 IndexedVar 非常相似 你需要了解几件事:

    1. 变量索引是不断变化的,这意味着你需要检查实际长度以避免添加你不会使用的变量,或者使用没有添加的变量。

    2. 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 类,其工作方式与此方法非常相似。您可以在Pyomo documentation 中查看它,不同之处在于您可以将不同类型的变量分配给同一个列表

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

    【讨论】:

    • 嗨@pybegginer,很抱歉回复缓慢,感谢您的回答。我现在设法在 pyomo.environ VarList 的约束下工作,但正如您所指出的,内核 API 实际上会提供更大的灵活性。
    猜你喜欢
    • 2021-08-21
    • 2023-03-05
    • 1970-01-01
    • 2020-08-04
    • 1970-01-01
    • 2022-11-16
    • 2015-07-04
    • 1970-01-01
    相关资源
    最近更新 更多