简体   繁体   English

是否可以为 Pyomo 优化(Python)设置不断变化的参数?

[英]Is is possible to have a ever changing parameter for a Pyomo optimization (Python)?

I am trying to do an optimization of an energy system which is constituted of 2 batteries that are supposed to supply energy when a signal (a request of energy) is sent.我正在尝试优化一个由 2 个电池组成的能源系统,这些电池应该在发送信号(能量请求)时提供能量。 I have created an abstract model in Pyomo to represent my problem and so far I manage to make it work, however my problem is that my data will continuously change depending on the results of my optimization.我在 Pyomo 中创建了一个抽象 model 来表示我的问题,到目前为止我设法让它工作,但我的问题是我的数据将根据我的优化结果不断变化。 For example if a signal is received and the batteries provide some energy then the State of Charge (SoC) will decrease (as there is less charge).例如,如果接收到信号并且电池提供一些能量,则 State 的电荷 (SoC) 将减少(因为电荷较少)。 I want to be able to update this value such that at the next optimization (when a successive signal comes in) my problem is solved using the real SoC.我希望能够更新此值,以便在下一次优化(当连续信号进入时)使用真正的 SoC 解决我的问题。 Another way to formulate this would be: is there a way to use dataframes as input parameters to my Pyomo optimization?另一种表达方式是:有没有办法使用数据帧作为我的 Pyomo 优化的输入参数?

This is my code.这是我的代码。 My set is called ASSETS because technically I would have multiple assets of different sorts (ie a classic lithium battery and maybe an hydrogen storage).我的集合称为资产,因为从技术上讲,我将拥有多种不同类型的资产(即经典的锂电池和可能的氢储存)。

# iterative1.py
from pyomo.environ import *
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt


## CREATING MODEL, SET AND PARAM
model = AbstractModel()

# Sets of PTU for which the model is being created for 

# model.PTU = Set() 
model.ASSETS = Set()

# Set up the param 
model.MinPower = Param(model.ASSETS)
model.MaxPower = Param(model.ASSETS)
model.Capacity = Param(model.ASSETS)
model.SoC = Param(model.ASSETS)
model.P_rated = Param(model.ASSETS)


    # DATA FROM the EMS csv

FR = 20 #requet of power
# model.SoC = 0.9 
P_rated = 1 #how much the asset is already in use during the request of power

    # Decision variable

# model.Psh = Var(model.PTU, within=Reals)
model.Psh = Var(model.ASSETS, within=Reals)

# Objective Function

def objective_rule(model):
        return FR - sum(model.Psh[i] for i in model.ASSETS)
    
model.PowerProvided = Objective(rule=objective_rule, sense=minimize)


# Constraints

        # defining the rules
        
def MinPowerRated_rule(model,i): # Min rated power limit
    return  - model.MaxPower[i] <= model.Psh[i] 

def MaxPowerRated_rule(model,i): # Max rated power limit
    return  model.Psh[i] <= model.MaxPower[i]

# def PowerRated_rule(model,i):
#     return  model.MinPower[i] <= model.Psh[i] <= model.MaxPower[i]

def MaxCapacityLimits_rule(model,i):  #Checks that the power flex is within the limits of the storage (discharge limit)
    return model.Psh[i] <= model.Capacity[i]*model.SoC[i]/4

def MinCapacityLimits_rule(model,i):  #Checks that the power flex is within the limits of the storage (charge limit)
    return model.Psh[i] >= - model.Capacity[i]*model.SoC[i]/4    

def MaxPowerAvailable_rule(model,i): 
    return model.Psh[i] <= model.MaxPower[i] - P_rated

    # return model.Psh[i] <= model.MaxPower[i] - model.P_rated[i]

def MinPowerAvailable_rule(model,i): 
    return model.Psh[i] >= - (model.MaxPower[i] - P_rated)

    # return model.Psh[i] >= - (model.MaxPower[i] - model.P_rated[i])

        # activating the constraints

model.MaxPowerRated = Constraint(model.ASSETS, rule=MaxPowerRated_rule)
model.MinPowerRated = Constraint(model.ASSETS, rule=MinPowerRated_rule)
model.MaxCapacityLimits = Constraint(model.ASSETS, rule=MaxCapacityLimits_rule)
model.MinCapacityLimits = Constraint(model.ASSETS, rule=MinCapacityLimits_rule)
model.MaxPowerAvailable = Constraint(model.ASSETS, rule=MaxPowerAvailable_rule)
model.MinPowerAvailable = Constraint(model.ASSETS, rule=MinPowerAvailable_rule)

        #create model instance


data = DataPortal() #DataPortal handles the .dat file 
data.load(filename="abstract.dat", model=model)
instance = model.create_instance(data)
opt = SolverFactory('glpk')
opt.solve(instance) 

and I am using the following.dat file to get the parameters for the constraints and objective function.我正在使用以下.dat 文件获取约束和目标 function 的参数。

ASSETS := 1 2; 

param MinPower := 
1 0
2 0;

param MaxPower := 
1 15
2 15;

param Capacity := 
1 30
2 30; 

param SoC :=
1 0.9
2 0.9;

I have tried to change SoC with a dataframe that I would update after every optimization but unfortunately I get an error.我试图用 dataframe 更改 SoC,我会在每次优化后更新它,但不幸的是我得到了一个错误。

I'd advise a couple of things...我会建议几件事......

  1. Switch over to a ConcreteModel in pyomo .切换到pyomo中的ConcreteModel They are easier to deal with and you can use basic python to read data of different types (if needed) or just encode the data into the program.它们更容易处理,您可以使用基本的 python 来读取不同类型的数据(如果需要)或者只是将数据编码到程序中。 It is easier to deal with and it will be more adaptable than trying to change something in an AbstractModel that you have loaded.与尝试更改已加载的AbstractModel中的某些内容相比,它更容易处理并且更具适应性。

  2. You model is "instantaneous" or static right now.你 model 是“瞬时”或 static 现在。 It does not represent the passage of time, which is fine.它不代表时间的流逝,这很好。 So if I understand you right, some part of the input data will change and you want to re-solve with no dependency on prior solutions.因此,如果我对您的理解是正确的,那么输入数据的某些部分将会发生变化,并且您想在不依赖于先前解决方案的情况下重新解决。 So, as a proof-of-concept, you could (a) make a concrete model, (b) get it running and QA it, (c) put it inside of a loop to solve and outside of the loop, change the input to the parameter and re-solve.因此,作为概念验证,您可以 (a) 制作一个具体的 model,(b) 让它运行并对其进行 QA,(c) 将其放入循环内以求解,并在循环外更改输入到参数并重新求解。

I have been looking around and the best way to do it is using a Dictionary.我一直在环顾四周,最好的方法是使用字典。 Pyomo has some examples that can be used as a template. Pyomo 有一些示例可以用作模板。 Inside the dictionary values of a dataframe can be directly inserted so that it creates this dynamic aspect (in the sense that the parameters will be changing according to the dataframe).在 dataframe 的字典值中可以直接插入,以便创建这个动态方面(在参数将根据数据帧更改的意义上)。 Someone else has advise to use a ConcreteModel but then you will have a very static (and very long to write) model which is not ideal (in the majority of the cases).其他人建议使用 ConcreteModel,但你会得到一个很长的 static(写起来很长)model,这并不理想(在大多数情况下)。

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

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