为什么 pyomo 在约束中解压命名元组?

问题描述 投票:0回答:1

我是 pyomo 的新手,我想了解为什么它可以与 nametuple 一起工作。 有代码示例:

from collections import namedtuple

import pyomo.environ as pyo
Product = namedtuple("Product", "product quantity")
products = pyo.Set(initialize=[Product("product1", 10), Product("product2", 20)])
model = pyo.ConcreteModel()
model.product_quantity = pyo.Var(products, within = pyo.NonNegativeReals)
def rule_product_quantity(model, prod):
    return model.product_quantity[prod] >= prod.quantity
model.ct_product_lim = pyo.Constraint(products, rule = rule_product_quantity)

这给了我一个错误:

Traceback (most recent call last):
  File "C:\MyFolder\problem.py", line 10, in <module>
    model.ct_product_lim = pyo.Constraint(products, rule = rule_product_quantity)
  File "C:\Users\Alex\AppData\Local\Programs\Python\Python39\lib\site-packages\pyomo\core\base\block.py", line 568, in __setattr__
    self.add_component(name, val)
  File "C:\Users\Alex\AppData\Local\Programs\Python\Python39\lib\site-packages\pyomo\core\base\block.py", line 1126, in add_component
    val.construct(data)
  File "C:\Users\Alex\AppData\Local\Programs\Python\Python39\lib\site-packages\pyomo\core\base\constraint.py", line 800, in construct
    self._setitem_when_not_present(index, rule(block, index))
  File "C:\Users\Alex\AppData\Local\Programs\Python\Python39\lib\site-packages\pyomo\core\base\initializer.py", line 314, in __call__
    return self._fcn(parent, *idx)
TypeError: rule_product_quantity() takes 2 positional arguments but 3 were given

我想这意味着,Constraint 中的 pyomo 自动将命名元组解包到字段序列中,然后将其发送到规则。

但目的是什么?

使该代码正常工作的最佳方法是什么?

pyomo namedtuple
1个回答
0
投票

它会解压所有元组。 至于根本原因... IDK。 但它对于操纵由多个集合或集合组合索引的约束等非常有效。

对于您的代码,我只是计划在定义中分别捕获

product
quantity
,知道它们将被解包,如下面的
C1
所示。

import pyomo.environ as pyo

m = pyo.ConcreteModel()

m.A = pyo.Set(initialize=[1,2,3])
m.B = pyo.Set(initialize=['dog', 'cat'])
m.C = pyo.Set(initialize=['red', 'green'])

m.AB = pyo.Set(initialize=m.A * m.B)
m.ABC = pyo.Set(initialize=m.A * m.B * m.C)

m.x = pyo.Var(m.A, m.B)
m.y = pyo.Var(m.C)
m.z = pyo.Var(m.B, m.C)

# shows unpacking
def C1(m, a, b):
    return m.x[a, b] <= 1
m.C1 = pyo.Constraint(m.AB, rule=C1)

# shows use of multiple/multi-indexed sets
def C2(m, a, b, c):
    return m.x[a, b] <= m.y[c]
m.C2 = pyo.Constraint(m.AB, m.C, rule=C2)

# shows gather of indices
def C3(m, *abc):
    return m.x[abc[:2]] >= m.z[abc[-2:]]
m.C3 = pyo.Constraint(m.ABC, rule=C3)
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.