问题获取决策变量以在Pyomo中正确优化

时间:2018-11-12 18:21:42

标签: python optimization pyomo glpk clp

我在使用pyomo时遇到一个简单的多周期优化问题。该模型的目标是根据该小时的火花价差(电价-燃气价格*热量费率+可变成本)来确定电厂应开启或关闭的时间。 Spark传播可以为负值,表示工厂应该关闭,也可以为正值,表示工厂应该运行。

目前的结果表明,尽管火花蔓延为负,该装置仍会打开并运行。

给定一个小时的火花传播,如何在每个时间步打开和关闭工厂?

我确信这是一个相当简单的解决方案,但是对于pyomo和优化问题我还是很陌生,因此非常感谢任何指导和帮助。

gas_price = [2.81,2.81,2.81,2.81,2.81,2.81,2.81,2.81,2.81,2.81,2.81,2.81,2.81,2.81,2.81,2.81,2.81]
power_price = [26.24,23.8,21.94,20.4,21.2,19.98,19.34,18.83,19.19,18.48,21,21.77,23.45,26.53,29.85,31.8,28.7]

priceDict = dict(enumerate(power_price))
gasDict = dict(enumerate(gas_price))

m = en.ConcreteModel()

m.Time = en.RangeSet(0, len(power_price)-1)
m.powerPrice = en.Param(m.Time, initialize=priceDict)
m.gasPrice = en.Param(m.Time, initialize=gasDict)

m.generation = en.Var(m.Time, bounds=(0,800),
initialize=0)
m.spark = en.Var(m.Time,initialize=0)
m.heatRate = en.Var(m.Time,initialize=7)
m.vom = en.Var(m.Time,initialize=2)

m.max_gen = en.Param(initialize=800)


def Obj_fn(m):
    return sum((m.spark[i]*m.generation[i]) for i in m.Time)
m.total_cost = en.Objective(rule=Obj_fn,sense=en.maximize)

# 7 is the heat rate of the plant
def spark_rule(m,i):
    return (m.spark[i] == m.powerPrice[i]-(m.gasPrice[i]*7+m.vom[i]))
m.hourly_spark = en.Constraint(m.Time,rule=spark_rule)

def generation_rule(m,i):
    return (0<=m.generation[i]<=m.max_gen)
m.t_generation_rule = en.Constraint(m.Time, rule=generation_rule)


opt = SolverFactory("clp",executable='C:\\clp.exe')
results = opt.solve(m)

该模型的输出当前为:

Time Generation     Spark Spread
1   0               6.57
2   800             4.13
3   800             2.27
4   800             0.73
5   800             1.53
6   800             0.31
7   800            -0.33
8   800            -0.84
9   800            -0.48
10  800            -1.19
11  800             1.33
12  800             2.1
13  800             3.78
14  800             6.86
15  800            10.18
16  800            12.13
17  800             9.03

1 个答案:

答案 0 :(得分:0)

我在这里可能是错的,但是我认为您实际上是在将heatRatevom定义为参数,而不是变量。

这导致一个奇怪的问题,因为只要“火花”价格为正,工厂自然会使用其最大功率,而当火花价格为负时,工厂将自然使用其最大功率。我想您稍后会添加更多约束。

如果heatRatevom已修复,则可以通过以下方式重新定义问题:

from pyomo import environ as pe

gas_price = [2.81,2.81,2.81,2.81,2.81,2.81,2.81,2.81,2.81,2.81,2.81,2.81,2.81,2.81,2.81,2.81,2.81]
power_price = [26.24,23.8,21.94,20.4,21.2,19.98,19.34,18.83,19.19,18.48,21,21.77,23.45,26.53,29.85,31.8,28.7]

priceDict = dict(enumerate(power_price))
gasDict = dict(enumerate(gas_price))

m = pe.ConcreteModel()

m.Time = pe.RangeSet(0, len(power_price)-1)

# this are all input parameters
m.powerPrice = pe.Param(m.Time, initialize=priceDict)
m.gasPrice = pe.Param(m.Time, initialize=gasDict)
m.vom = pe.Param(default=7)
m.heatRate = pe.Param(default=2)
m.maxGen = pe.Param(default=800)

# this is a "dependent" parameter
m.spark = pe.Param(m.Time,
    initialize = lambda m,t: m.powerPrice[t]-(m.gasPrice[t]*7+m.vom)
)

# this is the only variable
m.generation = pe.Var(m.Time, 
    initialize=0,
    bounds = (0, m.maxGen)
)

def Obj_fn(m):
    return sum((m.spark[t]*m.generation[t]) for t in m.Time)

m.total_cost = pe.Objective(rule=Obj_fn,sense=pe.maximize)