Pyomo:弃用:不推荐使用 __getitem__ 从其(有序)位置返回设定值

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

我正在使用 Pyomo,我有以下几行

outputVariables_list = [model.param1, model.variable1]
optimal_values_list = [[pyo.value(model_item[key]) for key in model_item] for model_item in outputVariables_list] 

当我运行它时,我收到一个我不明白的警告:

WARNING: DEPRECATED: Using __getitem__ to return a set value from its
    (ordered) position is deprecated.  Please use at()  (deprecated in 6.1,
    will be removed in 7.0)

我尝试了以下行,但这导致了一个错误:

optimal_values_list = [[pyo.at(model_item[key]) for key in model_item] for model_item in outputVariables_list]

此外,我尝试使用

pyo.value(model_item.at[key])
pyo.value(model_item.at(key)
都导致 AttributeError: 'IndexedParam' object has no attribute 'at'

你知道如何解决这个问题吗?

编辑:我使用的 pyomo 组件的完整列表可以在以下行中看到(名称表明它是参数、变量还是集合):

outputVariables_list_BT2 = [model.param_helpTimeSlots_BT2, model.variable_heatGenerationCoefficient_SpaceHeating_BT2, model.variable_heatGenerationCoefficient_DHW_BT2, model.variable_help_OnlyOneStorage_BT2, model.variable_temperatureBufferStorage_BT2, model.variable_usableVolumeDHWTank_BT2,  model.variable_electricalPowerTotal_BT2, model.variable_pvGeneration_BT2, model.variable_windPowerAssigned_BT2,  model.param_heatDemand_In_W_BT2, model.param_DHWDemand_In_W_BT2, model.param_electricalDemand_In_W_BT2, model.param_pvGenerationNominal_BT2, model.param_outSideTemperature_In_C, model.param_windAssignedNominal_BT2,  model.param_COPHeatPump_SpaceHeating_BT2, model.param_COPHeatPump_DHW_BT2, model.param_electricityPrice_In_Cents, model.set_timeslots]

温馨提示:大家好,关于这个问题我还有2个问题:

  1. 我不明白的是,Pyomo 告诉我使用“at”而不是 2__getitem__”,但这不起作用,因为我在使用 at 时遇到错误。这是一个非常令人困惑的建议。

  2. 有没有办法通过告诉 pyomo 不要显示警告来抑制警告?我使用的集合始终具有自然顺序(时隙),因此警告似乎与我的应用程序无关,并且数据帧看起来完全符合它们的要求。我只需要确保不要将 pyomo 更新到 7.0 版。因此,在这种情况下,如果我无法按照 Pyomo 的建议使用“at”(但目前还行不通),那么忽略警告似乎是一个不错的选择

任何人都可以帮我解决这些问题吗?

pyomo
1个回答
0
投票

如评论中所述,这里的核心问题是在上面的构造中,您通过使用

[ ]
和隐式索引从集合中获取项目。这是一个已弃用的功能,现在已被
.at()
构造所取代。但是,如果您使用集合是 无序的项目分组 的默认和普遍假设,您的生活会更长寿、更快乐。是的,在某些情况下顺序很重要,
pyomo
支持排序,因为有时需要知道第一个和最后一个,等等。在时间段等情况下。

最后我要解决的更大问题是您将集合提取到数据框索引中,我认为您正在以一种危险的方式进行操作,可能会导致丢失正确的索引。

所以这种类型的活动 for sets 是导致警告的原因:

In [28]: import pyomo.environ as pyo

In [29]: m = pyo.ConcreteModel()

In [30]: m.S = pyo.Set(initialize=range(1,4))

In [31]: print([m.S[key] for key in m.S])  # <- this is bad, don't do this
WARNING: DEPRECATED: Using __getitem__ to return a set value from its
    (ordered) position is deprecated.  Please use at()  (deprecated in 6.1,
    will be removed in (or after) 7.0) (called from <ipython-
    input-31-5ec773658fba>:1)
[1, 2, 3]

这在两个方面是不好的:(1)它使用不推荐使用的方法来获取项目并假定排序,以及(2)您使用设置值作为位置索引,这是非常危险的。即:

In [32]: m.T = pyo.Set(initialize=['A', 'B', 'C'])

In [33]: print([m.T[key] for key in m.T])
WARNING: DEPRECATED: Using __getitem__ to return a set value from its
    (ordered) position is deprecated.  Please use at()  (deprecated in 6.1,
    will be removed in (or after) 7.0) (called from <ipython-
    input-33-6c1cfbef0fe7>:1)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/pyomo/core/base/set.py:1485, in _OrderedSetMixin._to_0_based_index(self, item)
   1484 try:
-> 1485     if item != int(item):
   1486         raise IndexError(
   1487             "%s indices must be integers, not %s"
   1488             % (self.name, type(item).__name__,))

ValueError: invalid literal for int() with base 10: 'A'

所以,到了如何将事物放入数据框的地步。底部的示例显示了一个很好的方法。请注意,我只是初始化变量,使其具有一些值——这通常是求解器的工作。您的方法(如果可行)非常危险,因为上面指出的问题是您隐含地依赖集合成员的正确排序来拉出内容,您可能会失去集合项与集合值的“对齐”。类似于这样做:

In [36]: m.U = pyo.Set(initialize=[4, 1, 3, 2])

In [37]: print([m.U[key] for key in m.U])
WARNING: DEPRECATED: Using __getitem__ to return a set value from its
    (ordered) position is deprecated.  Please use at()  (deprecated in 6.1,
    will be removed in (or after) 7.0) (called from <ipython-
    input-37-621c2f20b151>:1)
[2, 4, 3, 1]

只是隐蔽到系列,它将被感兴趣的集合作为键值对(pd.Series 或字典的核心)索引并转换...

import pyomo.environ as pyo
import pandas as pd

m = pyo.ConcreteModel()
m.S = pyo.Set(initialize=list('ABC'))
m.X = pyo.Var(m.S, initialize={'A': 2, 'B': 3, 'C': 4.5})
m.cost = pyo.Param(m.S, initialize={'A':1.3, 'B': 2.4, 'C': 6.1})

items_of_interest = [m.X, m.cost]  # <-- note:  does not include any sets--unnecessary as they are key-value maps below.

records = [pd.Series(t.extract_values(), name = t.name) for t in items_of_interest]

results_df = pd.concat(records, axis=1)

print(results_df)

产量:

     X  cost
A  2.0   1.3
B  3.0   2.4
C  4.5   6.1
[Finished in 461ms]
© www.soinside.com 2019 - 2024. All rights reserved.