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

查看:488
本文介绍了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公式,这是您的代码的有效示例.对于抽象模型而言,它的作用不只是延迟将模型初始化为具体模型而已.因此,它知道将要使用的集合,但是在初始化之前,它无法知道其内容.例如,它知道参数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 ,然后跳到此页面:

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天全站免登陆