PYOMO:对抽象模型集的操作 [英] PYOMO: Operation on sets of abstract model

查看:22
本文介绍了PYOMO:对抽象模型集的操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想对抽象集进行操作.但它不起作用.

I want to operate on abstract sets. But it dosen't work.

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)

TypeError: 'NoneType' 对象不可迭代

TypeError: 'NoneType' object is not iterable

推荐答案

根据您告诉 Qi Chen 的内容,如果您使用 AbstractModel 公式,这里是您的代码的工作示例.问题是,对于抽象模型,它只会延迟将模型初始化为具体模型.因此,它知道将使用哪些集合,但是在您初始化它之前它无法知道它的内容.例如,它知道 param p 使用集合 s 作为域,但是无法知道 p 的值是什么和 s 的元素.

Based on what you told to Qi Chen, here is a working example of your code if you used the AbstractModel formulation. The thing, with abstract models, is that it doesn't do much more than delay the iniatilazion of your model into a concrete model. So, it knows what sets is going to be used, but it has no way of knowing its content until you initialize it. For example, it knows that param p use the set s as a domain, but there is no way of knowing what are the values of p and the elements of s.

话虽如此,您要做的是从单元化集 m.am.b 中填充您的 m.C 集.我和 Qi Chen 站在一起,ConcreteModels 是您的最佳选择.但是,这里提供了三种使用 AbstractModels 的方法.

That being said, what you are trying to do is populationg your m.C set from unititialized sets m.a and m.b. I stand with Qi Chen, ConcreteModels are just the best option for you. However, here are three ways of using AbstractModels.

选项 1在这里,您在初始化模型之后填充 m.C.create_instance() 基本上通过填充将您的抽象模型转变为具体模型.它返回相应的ConcreteModel.这样,您就有了足够的 AbstractModel(请记住,AbstractModel 不需要填充集合,只需知道正在使用哪些集合).因此,以下代码在初始化后填充 ConcreteModel 中的 m.C 集:

Option 1 Here you populate your m.C set after initializing your model. create_instance() basically turn your abstract model into a concrete model, by populating it. It returns the corresponding ConcreteModel. This way, you have a sufficient AbstractModel (remember, AbstractModel doesn't need to have populated sets, only to know which sets are being used). So, the following code populates your m.C set in a ConcreteModel, after it has been initialized:

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 listset 初始化.因此,在定义模型的集合时,首先创建您的集合(这次使用 Python 的内置集合).代码如下:

Option 2 Here, since you seem to know what are the content of your sets, you can define it before even making your AbstractModel. This is just a reminder that each set is usually initalized with a Python list or set. So, just create your sets first (this time using Python's built-in sets), at the moment of the definition of your model' Sets. Here is the code:

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 的一种更高级、更难的方法,因为基本上,它做同样的事情,即创建具有填充值和集合的模型.

But, again, since your sets are already defined, what I just showed you is just a fancier, harder way of creating a ConcreteModel, since basically, it does the same thing, that is to create a model with populated values and sets.

选项 3使用选项 1 和选项 2 的方式,您将无法更改集合的元素.比如下面的代码

Option 3 Using the way of Option 1 and Option 2, you will not be able to change the elements of your sets afterward. For example, the following code

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 类作为空白模型来放入数据时.如果你想这样使用它,恕我直言,这是唯一的好处使用 AbstractModel 的原因,那么您应该考虑阅读此页面:https://pyomo.readthedocs.io/en/latest/working_abstractmodels/data/index.html 然后,跳到这个页面:https://pyomo.readthedocs.io/en/latest/working_abstractmodels/data/raw_dicts.html,它向您展示了如何从数据填充空白 AbstractModel 的示例,在这种情况下,数据以 Python 字典的形式提供.他们说,在我向您展示的第一个链接中,这不是向模型提供数据的唯一方法,但其中有一个完整的工作示例.

That's a major inconvenient, especially when we try to use the AbstractModel class as a blank model to put data in. If you want to use it this way, and IMHO, this is the only good reason to use an AbstractModel, then you should consider having a read on this page: 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 , where it shows you an example of how to populate a blank AbstractModel from data, in this case, the data is provided in form of a Python dictionary. They say, in the first link I showed you, that it is not the only way of providing data to the model, but it has a complete working example in there.

主要思想是按照以下方式构建您的项目:

The main idea would be to build your project as following:

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)

还有其他方法可以将数据导入您的模型,但这只是为了向您展示一个简单的示例.

There exist other ways of importing data to your model, but this is just to show you an easy example.

这篇关于PYOMO:对抽象模型集的操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆