PYOMO优化问题(热存储+锅炉+热泵)

发布于 2025-01-22 06:09:34 字数 5632 浏览 1 评论 0原文

嗨,我写了一个PYOMO脚本,以优化具有3个组件(热存储,锅炉和热泵)的调度图案。它似乎有效,直到定义有关热存储的约束为止。谁能帮助我理解为什么没有最佳解决方案,哪个约束(不是排放约束)定义错误?谢谢您的帮助!

import pyomo.environ as pyo
from pyomo.environ import *
from pyomo.opt import SolverFactory
from pyomo.opt import TerminationCondition

# solver function

solver = SolverFactory("glpk")
model = ConcreteModel()

# creating a timeframe

number_of_period = 8760
model.time_set = pyo.Set(initialize=range(1, number_of_period+1), ordered=True)

# loading csv input files

input_assumptions = pd.read_csv('input_assumptions.csv')
input_price = pd.read_csv('prices.csv')
input_price_new = pd.DataFrame(input_price)
demand = input_assumptions['Total network demand (MWh)']
demand_new = pd.DataFrame(demand)

#parameters

model.Price = pyo.Param(model.time_set, initialize=dict(enumerate(input_price_new['Electricity prices'], 1)), within=pyo.Any)
model.Demand = pyo.Param(model.time_set, initialize=dict(enumerate(demand_new['Total network demand (MWh)'], 1)), within=pyo.Any)
model.HP_max = pyo.Param(model.time_set, initialize=dict(enumerate(input_assumptions['Max Heat pump'], 1)), within=pyo.Any)

#variables

model.b_min_cap = pyo.Param(initialize=0)
model.b_max_cap = pyo.Param(initialize=8.708)

model.b_soc = pyo.Var(model.time_set, domain = pyo.NonNegativeReals, bounds = (model.b_min_cap, model.b_max_cap))
model.b_discharge = pyo.Var(model.time_set, domain = pyo.NonNegativeReals, initialize = 0)
model.b_charge = pyo.Var(model.time_set, domain = pyo.NonNegativeReals, initialize = 0)

def HP_domain(model, i):
    upper_HP = input_assumptions['Max Heat pump']
    lower = input_assumptions['lower']
    return(0, upper_HP[i-1])

model.HP_var = pyo.Var(model.time_set, domain = pyo.NonNegativeReals, bounds=HP_domain, initialize = 0)

model.Boiler_var = pyo.Var(model.time_set, domain = pyo.NonNegativeReals, bounds=(0, 24), initialize = 0)

#definition of the objective

def minimise(model):
    return pyo.summation(model.Price, model.HP_var)

model.obj = pyo.Objective(rule=minimise, sense=pyo.minimize)

#constraints

def Soc_constraint(model, i):
    if i == model.time_set.first():
        return model.b_soc[i] == model.b_max_cap # starting at 100 % charge level 
    else: 
        return model.b_soc[i] == model.b_soc[i-1] - model.b_discharge[i-1] + model.b_charge[i-1]
model.soc_c = pyo.Constraint(model.time_set, rule=Soc_constraint)

def dispatch_rule(model, i):
    return sum(model.b_discharge[i] for i in range(1, 8761)) + sum(model.b_charge[i] for i in range(1, 8761)) == 0
model.Summ = pyo.Constraint(rule=dispatch_rule)

def discharge_constraint_two(model, i):
    return model.b_discharge[i]  <= model.b_soc[i] # Maximum discharge rate within a single hour
model.discharge_two = pyo.Constraint(model.time_set, rule=discharge_constraint_two)

def charge_constraint_one(model, i):
    return model.b_charge[i] <= model.HP_max[i] - model.Demand[i] # Maximum charge rate within a single hour
model.charge_one = pyo.Constraint(model.time_set, rule=charge_constraint_one)

def charge_constraint_two(model, i):
    return model.b_charge[i] <= 8.708 - model.b_soc[i] # Maximum charge rate within a single hour
model.charge_two = pyo.Constraint(model.time_set, rule=charge_constraint_two)

def Sum_Const(model, i):
    return model.HP_var[i] + model.Boiler_var[i] + model.b_discharge[i] - model.b_charge[i] == model.Demand[i]
model.SumConst = pyo.Constraint(model.time_set, rule=Sum_Const)

def Summation_Const(model, i):
    return sum(model.HP_var[i] for i in range(1, 8761)) + sum(model.Boiler_var[i] for i in range(1, 8761)) == sum(model.Demand[i] for i in range(1, 8761))
model.Summ = pyo.Constraint(rule=Summation_Const)

def Emission_Const(model, i):
    total_gas = sum(model.Boiler_var[i] for i in range(1, 8761))
    total_elec = sum(model.HP_var[i] for i in range(1, 8761))
    total_demand = sum(model.Demand[i] for i in range(1, 8761))
    return ((total_elec / 2.97 * 0.219) + (total_gas / 0.85 * 0.184)) / (total_demand * 0.984) == 0.1
model.Emission = pyo.Constraint(rule=Emission_Const)'''

GLPSOL--GLPK LP/MIP Solver 5.0
Parameter(s) specified in the command line:
 --mipgap 0.015 --write C:\Users\MATE~1.TOT\AppData\Local\Temp\tmpyopw_8dk.glpk.raw
 --wglp C:\Users\MATE~1.TOT\AppData\Local\Temp\tmp9aorspj7.glpk.glp --cpxlp
 C:\Users\MATE~1.TOT\AppData\Local\Temp\tmpmlk9d5az.pyomo.lp
Reading problem data from 'C:\Users\MATE~1.TOT\AppData\Local\Temp\tmpmlk9d5az.pyomo.lp'...
17523 rows, 43800 columns, 96358 non-zeros
201490 lines were read
Writing problem data to 'C:\Users\MATE~1.TOT\AppData\Local\Temp\tmp9aorspj7.glpk.glp'...
201484 lines were written
GLPK Simplex Optimizer 5.0
17523 rows, 43800 columns, 96358 non-zeros
Preprocessing...
17521 rows, 35038 columns, 87595 non-zeros
Scaling...
 A: min|aij| =  1.576e-06  max|aij| =  1.000e+00  ratio =  6.345e+05
GM: min|aij| =  7.640e-01  max|aij| =  1.309e+00  ratio =  1.713e+00
EQ: min|aij| =  5.836e-01  max|aij| =  1.000e+00  ratio =  1.713e+00
Constructing initial basis...
Size of triangular part is 17520
      0: obj =   0.000000000e+00 inf =   6.458e+04 (4)
Perturbing LP to avoid stalling [11026]...
  13932: obj =   2.831720898e+06 inf =   9.314e+02 (1) 84
  17298: obj =   2.831720898e+06 inf =   9.314e+02 (1)
LP HAS NO PRIMAL FEASIBLE SOLUTION
glp_simplex: unable to recover undefined or non-optimal solution
If you need actual output for non-optimal solution, use --nopresol
Time used:   6.5 secs
Memory used: 37.8 Mb (39629941 bytes)
Writing basic solution to 'C:\Users\MATE~1.TOT\AppData\Local\Temp\tmpyopw_8dk.glpk.raw'...
61332 lines were written
Model unknown

Hi there, I have written a Pyomo script to optimize a dispatch pattern with 3 components (thermal storage, boiler and heat pump). It seems to work until constraints are defined regarding the thermal storage. Could anyone help me understand why there is no optimal solution, and which constraint (its not the emission constraint) is defined wrong? Thank you for your help!

import pyomo.environ as pyo
from pyomo.environ import *
from pyomo.opt import SolverFactory
from pyomo.opt import TerminationCondition

# solver function

solver = SolverFactory("glpk")
model = ConcreteModel()

# creating a timeframe

number_of_period = 8760
model.time_set = pyo.Set(initialize=range(1, number_of_period+1), ordered=True)

# loading csv input files

input_assumptions = pd.read_csv('input_assumptions.csv')
input_price = pd.read_csv('prices.csv')
input_price_new = pd.DataFrame(input_price)
demand = input_assumptions['Total network demand (MWh)']
demand_new = pd.DataFrame(demand)

#parameters

model.Price = pyo.Param(model.time_set, initialize=dict(enumerate(input_price_new['Electricity prices'], 1)), within=pyo.Any)
model.Demand = pyo.Param(model.time_set, initialize=dict(enumerate(demand_new['Total network demand (MWh)'], 1)), within=pyo.Any)
model.HP_max = pyo.Param(model.time_set, initialize=dict(enumerate(input_assumptions['Max Heat pump'], 1)), within=pyo.Any)

#variables

model.b_min_cap = pyo.Param(initialize=0)
model.b_max_cap = pyo.Param(initialize=8.708)

model.b_soc = pyo.Var(model.time_set, domain = pyo.NonNegativeReals, bounds = (model.b_min_cap, model.b_max_cap))
model.b_discharge = pyo.Var(model.time_set, domain = pyo.NonNegativeReals, initialize = 0)
model.b_charge = pyo.Var(model.time_set, domain = pyo.NonNegativeReals, initialize = 0)

def HP_domain(model, i):
    upper_HP = input_assumptions['Max Heat pump']
    lower = input_assumptions['lower']
    return(0, upper_HP[i-1])

model.HP_var = pyo.Var(model.time_set, domain = pyo.NonNegativeReals, bounds=HP_domain, initialize = 0)

model.Boiler_var = pyo.Var(model.time_set, domain = pyo.NonNegativeReals, bounds=(0, 24), initialize = 0)

#definition of the objective

def minimise(model):
    return pyo.summation(model.Price, model.HP_var)

model.obj = pyo.Objective(rule=minimise, sense=pyo.minimize)

#constraints

def Soc_constraint(model, i):
    if i == model.time_set.first():
        return model.b_soc[i] == model.b_max_cap # starting at 100 % charge level 
    else: 
        return model.b_soc[i] == model.b_soc[i-1] - model.b_discharge[i-1] + model.b_charge[i-1]
model.soc_c = pyo.Constraint(model.time_set, rule=Soc_constraint)

def dispatch_rule(model, i):
    return sum(model.b_discharge[i] for i in range(1, 8761)) + sum(model.b_charge[i] for i in range(1, 8761)) == 0
model.Summ = pyo.Constraint(rule=dispatch_rule)

def discharge_constraint_two(model, i):
    return model.b_discharge[i]  <= model.b_soc[i] # Maximum discharge rate within a single hour
model.discharge_two = pyo.Constraint(model.time_set, rule=discharge_constraint_two)

def charge_constraint_one(model, i):
    return model.b_charge[i] <= model.HP_max[i] - model.Demand[i] # Maximum charge rate within a single hour
model.charge_one = pyo.Constraint(model.time_set, rule=charge_constraint_one)

def charge_constraint_two(model, i):
    return model.b_charge[i] <= 8.708 - model.b_soc[i] # Maximum charge rate within a single hour
model.charge_two = pyo.Constraint(model.time_set, rule=charge_constraint_two)

def Sum_Const(model, i):
    return model.HP_var[i] + model.Boiler_var[i] + model.b_discharge[i] - model.b_charge[i] == model.Demand[i]
model.SumConst = pyo.Constraint(model.time_set, rule=Sum_Const)

def Summation_Const(model, i):
    return sum(model.HP_var[i] for i in range(1, 8761)) + sum(model.Boiler_var[i] for i in range(1, 8761)) == sum(model.Demand[i] for i in range(1, 8761))
model.Summ = pyo.Constraint(rule=Summation_Const)

def Emission_Const(model, i):
    total_gas = sum(model.Boiler_var[i] for i in range(1, 8761))
    total_elec = sum(model.HP_var[i] for i in range(1, 8761))
    total_demand = sum(model.Demand[i] for i in range(1, 8761))
    return ((total_elec / 2.97 * 0.219) + (total_gas / 0.85 * 0.184)) / (total_demand * 0.984) == 0.1
model.Emission = pyo.Constraint(rule=Emission_Const)'''

GLPSOL--GLPK LP/MIP Solver 5.0
Parameter(s) specified in the command line:
 --mipgap 0.015 --write C:\Users\MATE~1.TOT\AppData\Local\Temp\tmpyopw_8dk.glpk.raw
 --wglp C:\Users\MATE~1.TOT\AppData\Local\Temp\tmp9aorspj7.glpk.glp --cpxlp
 C:\Users\MATE~1.TOT\AppData\Local\Temp\tmpmlk9d5az.pyomo.lp
Reading problem data from 'C:\Users\MATE~1.TOT\AppData\Local\Temp\tmpmlk9d5az.pyomo.lp'...
17523 rows, 43800 columns, 96358 non-zeros
201490 lines were read
Writing problem data to 'C:\Users\MATE~1.TOT\AppData\Local\Temp\tmp9aorspj7.glpk.glp'...
201484 lines were written
GLPK Simplex Optimizer 5.0
17523 rows, 43800 columns, 96358 non-zeros
Preprocessing...
17521 rows, 35038 columns, 87595 non-zeros
Scaling...
 A: min|aij| =  1.576e-06  max|aij| =  1.000e+00  ratio =  6.345e+05
GM: min|aij| =  7.640e-01  max|aij| =  1.309e+00  ratio =  1.713e+00
EQ: min|aij| =  5.836e-01  max|aij| =  1.000e+00  ratio =  1.713e+00
Constructing initial basis...
Size of triangular part is 17520
      0: obj =   0.000000000e+00 inf =   6.458e+04 (4)
Perturbing LP to avoid stalling [11026]...
  13932: obj =   2.831720898e+06 inf =   9.314e+02 (1) 84
  17298: obj =   2.831720898e+06 inf =   9.314e+02 (1)
LP HAS NO PRIMAL FEASIBLE SOLUTION
glp_simplex: unable to recover undefined or non-optimal solution
If you need actual output for non-optimal solution, use --nopresol
Time used:   6.5 secs
Memory used: 37.8 Mb (39629941 bytes)
Writing basic solution to 'C:\Users\MATE~1.TOT\AppData\Local\Temp\tmpyopw_8dk.glpk.raw'...
61332 lines were written
Model unknown

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

话少情深 2025-01-29 06:09:34

欢迎来到网站。您应该看几件事。

首先,您的模型中存在错误,因此我不确定您正在运行什么实际产生输出。具体而言,在您的一些约束中,您省略了需要传递给您功能的索引。像这样:

def Summation_Const(model, i):
    return sum(model.HP_var[i] for i in range(1, 8761)) + sum(model.Boiler_var[i] for i in range(1, 8761)) == sum(model.Demand[i] for i in range(1, 8761))
model.Summ = pyo.Constraint(rule=Summation_Const)

您没有传递i

其次,我担心您的排放限制。为什么它是平等约束而不是上限? (&lt; =

最重要的是,您需要关注结果语句,并看到它报告了该模型当前是不可行的。因此,不仅找不到最佳解决方案,还因为您有一些逻辑错误。您可以单独评论约束,以查看您是否可以找到罪魁祸首或做我在这篇文章中所建议的事情:

找出PYOMO模型的原因

Welcome to the site. There are a couple things you should look at.

First, there are errors in your model, so I'm not sure what you are running that actually produces output. Specifically, in several of your constraints, you are omitting the index that needs to be passed to your function. Like this one:

def Summation_Const(model, i):
    return sum(model.HP_var[i] for i in range(1, 8761)) + sum(model.Boiler_var[i] for i in range(1, 8761)) == sum(model.Demand[i] for i in range(1, 8761))
model.Summ = pyo.Constraint(rule=Summation_Const)

You aren't passing in i.

Second, I'm concerned about your Emission constraint. Why is it an equality constraint rather than an upper limit? (<=)

Most importantly, you need to focus on the result statement and see that it reports the model is currently INFEASIBLE. So it is not just that an optimal solution can't be found, it is that you have some logic errors. You can comment out the constraints individually to see if you can find the culprit or do something as I suggest in this post:

Finding out reason of Pyomo model infeasibility

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文