PYOMO:对抽象模型集的操作
PYOMO: Operation on sets of abstract model
我想对抽象集进行操作。但是没用。
from pyomo.environ import *
m = AbstractModel()
m.A = Set(initialize=[0,1,2])
m.B = Set(initialize=[0])
m.C = m.A-m.B
instance = m.create_instance()
for c in instance.C.value:
print(c)
类型错误:'NoneType'对象不可迭代
如果你想以这种方式建模,你应该使用 ConcreteModel 并跳过创建实例行。您的模型和实例将是相同的。
所以也许我应该说说我的动机是什么。我想根据我的 AbstractModel 中的子集 m.C 定义约束,例如
def rule_name(m, c):
return something depends on c
m.rule_name = Constraint(m.C, rule=rule_name)
根据你告诉 Qi Chen 的内容,如果你使用 AbstractModel 公式,这里有一个代码的工作示例。对于抽象模型,问题在于它只是延迟将模型初始化为具体模型。因此,它 知道 将使用什么集合,但在您初始化它之前它无法知道其内容。例如,它知道 param p
使用集合 s
作为域,但是无法知道 p
的值和 s
的元素是什么.
也就是说,您要做的是从单元化集 m.a
和 m.b
填充您的 m.C
集。我支持 Qi Chen,ConcreteModels 是您最好的选择。但是,这里有三种使用 AbstractModels 的方法。
选项 1
在 初始化您的模型后,您在此处填充 m.C
集 。 create_instance()
基本上是通过填充将您的抽象模型变成具体模型。它returns对应ConcreteModel
。这样,您就有了足够的 AbstractModel
(请记住,AbstractModel
不需要填充集,只需要知道正在使用哪些集)。因此,以下代码在 ConcreteModel
初始化后填充 m.C
集:
m = AbstractModel()
m.A = Set(initialize=[0, 1, 2])
m.B = Set(initialize=[0])
m.C = Set()
instance = m.create_instance() # Here instance becomes your ConcreteModel
instance.C = instance.A - instance.B # The equivalent of line "m.C = m.A-m.B" but with your ConcreteModel
for c in instance.C:
print(c)
选项 2
在这里,由于您似乎知道集合的内容是什么,所以您甚至可以在制作 AbstractModel
之前定义它。这只是一个提醒,每个集合通常用 Python list
或 set
初始化。因此,在定义模型的集合时,首先创建集合(这次使用 Python 的内置集合)。这是代码:
from pyomo.environ import *
# Define the content of your model' Sets using built-in set
A = {0,1,2}
B = {0}
C = A - B
# You have all you need now to continue
m = AbstractModel()
m.A = Set(initialize=A)
m.B = Set(initialize=B)
m.C = Set(initialize=C)
instance = m.create_instance()
for c in instance.C:
print(c)
但是,同样,由于您的集合已经定义,我刚才向您展示的只是创建 ConcreteModel
的更高级、更难的方法,因为基本上,它做同样的事情,即创建具有填充值和集合的模型。
选项 3
使用选项 1 和选项 2 的方式,之后您将无法更改集合的元素。比如下面的代码
from pyomo.environ import *
A = {0, 1, 2}
B = {0}
C = A - B
m = AbstractModel()
m.A = Set(initialize=A)
m.B = Set(initialize=B)
m.C = Set(initialize=C)
# Pyomo's Sets are initialized, now, let's try to change their value:
A = {4, 5, 6}
B = {4}
instance = m.create_instance()
for c in instance.C:
print(c)
仍会打印
1
2
即使我们尝试打印
5
6
这是一个很大的不便之处,尤其是当我们尝试使用 AbstractModel
class 作为空白模型来放入数据时。如果你想这样使用它,恕我直言,这是使用 AbstractModel
的唯一充分理由,那么您应该考虑阅读此页面:https://pyomo.readthedocs.io/en/latest/working_abstractmodels/data/index.html and then, skip to this page: https://pyomo.readthedocs.io/en/latest/working_abstractmodels/data/raw_dicts.html,其中向您展示了如何从数据中填充空白 AbstractModel
的示例,在这种情况下,数据以 Python 字典的形式提供。他们说,在我向您展示的第一个 link 中,这不是向模型提供数据的唯一方法,但它有一个完整的工作示例。
主要想法是按如下方式构建您的项目:
from pyomo.environ import *
A = {0, 1, 2}
B = {0}
m = AbstractModel()
m.A = Set()
m.B = Set()
m.C = Set()
# ...
# Let's suppose you have completed your AbstractModel here (Params, Vars, Constraints and so on).
# This is the part where you put your data into a dictionary.
data = {None: {
'A': {None: A},
'B': {None: B},
'C': {None: A - B}
}}
# And here is the part where you initialize your model:
instance = m.create_instance(data)
for c in instance.C:
print(c)
还有其他方法可以将数据导入您的模型,但这只是为了向您展示一个简单的示例。
我想对抽象集进行操作。但是没用。
from pyomo.environ import *
m = AbstractModel()
m.A = Set(initialize=[0,1,2])
m.B = Set(initialize=[0])
m.C = m.A-m.B
instance = m.create_instance()
for c in instance.C.value:
print(c)
类型错误:'NoneType'对象不可迭代
如果你想以这种方式建模,你应该使用 ConcreteModel 并跳过创建实例行。您的模型和实例将是相同的。
所以也许我应该说说我的动机是什么。我想根据我的 AbstractModel 中的子集 m.C 定义约束,例如
def rule_name(m, c):
return something depends on c
m.rule_name = Constraint(m.C, rule=rule_name)
根据你告诉 Qi Chen 的内容,如果你使用 AbstractModel 公式,这里有一个代码的工作示例。对于抽象模型,问题在于它只是延迟将模型初始化为具体模型。因此,它 知道 将使用什么集合,但在您初始化它之前它无法知道其内容。例如,它知道 param p
使用集合 s
作为域,但是无法知道 p
的值和 s
的元素是什么.
也就是说,您要做的是从单元化集 m.a
和 m.b
填充您的 m.C
集。我支持 Qi Chen,ConcreteModels 是您最好的选择。但是,这里有三种使用 AbstractModels 的方法。
选项 1
在 初始化您的模型后,您在此处填充 m.C
集 。 create_instance()
基本上是通过填充将您的抽象模型变成具体模型。它returns对应ConcreteModel
。这样,您就有了足够的 AbstractModel
(请记住,AbstractModel
不需要填充集,只需要知道正在使用哪些集)。因此,以下代码在 ConcreteModel
初始化后填充 m.C
集:
m = AbstractModel()
m.A = Set(initialize=[0, 1, 2])
m.B = Set(initialize=[0])
m.C = Set()
instance = m.create_instance() # Here instance becomes your ConcreteModel
instance.C = instance.A - instance.B # The equivalent of line "m.C = m.A-m.B" but with your ConcreteModel
for c in instance.C:
print(c)
选项 2
在这里,由于您似乎知道集合的内容是什么,所以您甚至可以在制作 AbstractModel
之前定义它。这只是一个提醒,每个集合通常用 Python list
或 set
初始化。因此,在定义模型的集合时,首先创建集合(这次使用 Python 的内置集合)。这是代码:
from pyomo.environ import *
# Define the content of your model' Sets using built-in set
A = {0,1,2}
B = {0}
C = A - B
# You have all you need now to continue
m = AbstractModel()
m.A = Set(initialize=A)
m.B = Set(initialize=B)
m.C = Set(initialize=C)
instance = m.create_instance()
for c in instance.C:
print(c)
但是,同样,由于您的集合已经定义,我刚才向您展示的只是创建 ConcreteModel
的更高级、更难的方法,因为基本上,它做同样的事情,即创建具有填充值和集合的模型。
选项 3 使用选项 1 和选项 2 的方式,之后您将无法更改集合的元素。比如下面的代码
from pyomo.environ import *
A = {0, 1, 2}
B = {0}
C = A - B
m = AbstractModel()
m.A = Set(initialize=A)
m.B = Set(initialize=B)
m.C = Set(initialize=C)
# Pyomo's Sets are initialized, now, let's try to change their value:
A = {4, 5, 6}
B = {4}
instance = m.create_instance()
for c in instance.C:
print(c)
仍会打印
1
2
即使我们尝试打印
5
6
这是一个很大的不便之处,尤其是当我们尝试使用 AbstractModel
class 作为空白模型来放入数据时。如果你想这样使用它,恕我直言,这是使用 AbstractModel
的唯一充分理由,那么您应该考虑阅读此页面:https://pyomo.readthedocs.io/en/latest/working_abstractmodels/data/index.html and then, skip to this page: https://pyomo.readthedocs.io/en/latest/working_abstractmodels/data/raw_dicts.html,其中向您展示了如何从数据中填充空白 AbstractModel
的示例,在这种情况下,数据以 Python 字典的形式提供。他们说,在我向您展示的第一个 link 中,这不是向模型提供数据的唯一方法,但它有一个完整的工作示例。
主要想法是按如下方式构建您的项目:
from pyomo.environ import *
A = {0, 1, 2}
B = {0}
m = AbstractModel()
m.A = Set()
m.B = Set()
m.C = Set()
# ...
# Let's suppose you have completed your AbstractModel here (Params, Vars, Constraints and so on).
# This is the part where you put your data into a dictionary.
data = {None: {
'A': {None: A},
'B': {None: B},
'C': {None: A - B}
}}
# And here is the part where you initialize your model:
instance = m.create_instance(data)
for c in instance.C:
print(c)
还有其他方法可以将数据导入您的模型,但这只是为了向您展示一个简单的示例。