简体   繁体   English

在Pyomo中,是否可以基于多个表达式编写目标函数或约束?

[英]In Pyomo, Is it possible to write an objective function or a constraint based on several Expressions?

I am quite new in Pyomo and I try to write the objective function and a constraint of my model by using several methods. 我是Pyomo的新手,我尝试使用几种方法编写目标函数和模型约束。 Actually, I would like to construct the objective function/constraint based on several contributions of different object types implemented in different python scripts. 实际上,我想基于在不同python脚本中实现的不同对象类型的几种贡献来构造目标函数/约束。

For doing this, I have used pyomo Expression objects. 为此,我使用了pyomo Expression对象。 I don't know if this is the right object to use. 我不知道这是否是正确的对象。

To illustrate my question, here is an example code implementing what I would like to do: 为了说明我的问题,这是一个示例代码,实现了我想做的事情:

import pyomo.environ
model = pyomo.environ.ConcreteModel()

model.market = pyomo.environ.Set(initialize=['market'])

model.ask_price = pyomo.environ.Param(model.market, initialize={'market' : 12})
model.bid_price = pyomo.environ.Param(model.market, initialize={'market' : 10})
model.ask_liquidity = pyomo.environ.Param(model.market, initialize={'market' : 100})
model.bid_liquidity = pyomo.environ.Param(model.market, initialize={'market' : 100})

model.VOLUME_BUY = pyomo.environ.Var(model.market, within = pyomo.environ.NonNegativeReals)
model.VOLUME_SELL = pyomo.environ.Var(model.market, within = pyomo.environ.NonNegativeReals)

def max_buy(model, market):
    return model.VOLUME_BUY[market] <= model.ask_liquidity[market]

model.max_buy_equation = pyomo.environ.Constraint(model.market, rule=max_buy)

def max_sell(model, market):
    return model.VOLUME_SELL[market] <= model.bid_liquidity[market]

model.max_sell_equation = pyomo.environ.Constraint(model.market, rule=max_sell)

I then try to implement my objective function. 然后,我尝试实现我的目标功能。 If I try to implement it basically, everything works correctly: 如果我尝试基本实现它,那么一切都会正常工作:

def total_objective(model):
    return   sum(model.VOLUME_BUY[market] * model.ask_price[market] for market in model.market) \
           - sum(model.VOLUME_SELL[market] * model.bid_price[market] for market in model.market)

model.objective = pyomo.environ.Objective(rule=total_objective, sense=-1)

But if I try to use expression objects : 但是,如果我尝试使用表达式对象:

def objective_component1(model):
    return sum(model.VOLUME_BUY[market] * model.ask_price[market] for market in model.market)

model.obj_component1 = pyomo.environ.Expression(rule=objective_component1)

def objective_component2(model):
    return - sum(model.VOLUME_SELL[market] * model.bid_price[market] for market in model.market)

model.obj_component2 = pyomo.environ.Expression(rule=objective_component2)

model.objective = pyomo.environ.Objective(rule=model.obj_component1 + model.obj_component2, sense=-1)

I get an error : 我得到一个错误:

ValueError: No value for uninitialized NumericValue object VOLUME_BUY[market]

I even try to write the expression as follows: 我什至尝试将表达式编写如下:

obj1 = sum(model.VOLUME_BUY[market] * model.ask_price[market] for market in model.market)
obj2 = - sum(model.VOLUME_SELL[market] * model.bid_price[market] for market in model.market)
model.objective = pyomo.environ.Objective(rule=obj1 + obj2, sense=-1)

But I get the same error. 但是我得到了同样的错误。

I don't understand why I get a uninitialized error message for a variable object. 我不明白为什么我会收到变量对象的未初始化错误消息。 Maybe the expression pyomo object is not the right object to use to construct my objective function ? 也许表达式pyomo对象不是用于构造我的目标函数的正确对象?

Note that I also want to construct the balance constraint of my model using different expressions and I don't manage to do it either. 请注意,我也想使用不同的表达式来构造模型的平衡约束,我也无法做到这一点。

I am using Python 2.7 and pyomo 4.4.1. 我正在使用python 2.7和pyomo 4.4.1。

Thanks in advance for your help ! 在此先感谢您的帮助 !

I believe the problem is that you are using the rule keyword to initialize the Objective object. 我相信问题是您正在使用rule关键字来初始化Objective对象。 You really only need to do this when starting from an AbstractModel (or when declaring an indexed component). 实际上,仅从AbstractModel开始(或声明索引的组件时)才需要这样做。 Since Pyomo expressions are callable, it is not distinguishing what you are passing it from a standard function (so it calls it, expecting it to return an expression, but it actually just evaluates the expression). 由于Pyomo表达式是可调用的,因此它不会区分您将其与标准函数传递的内容(因此它调用它,希望它返回一个表达式,但实际上只是对表达式求值)。

Changing rule= to expr= should fix things. rule=更改为expr=应该可以解决问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM