如何编写 pyomo 优化来选择最佳可再生能源量?

问题描述 投票:0回答:0

背景

我正在尝试编写一个 pyomo 优化,它接受客户的电力负荷和几个可再生能源项目的发电数据,然后优化解决可再生能源项目的最低成本选择,以最大限度地减少电力消耗,受一些限制。

我试过的

使用 pyomo readthedocs 和 stackoverflow。我已经写了我的第一次尝试(如下),但我有两个问题。

问题

  1. 错误:索引为 0 的表达式“d_spill_var”的规则失败:PyomoException: 无法转换非常量 Pyomo 表达式

我认为这是因为我试图为我的一个依赖表达式返回一个 max(expr, 0) 值。然而,即使我改变了这个,我仍然会遇到下面的问题 2;

  1. RuntimeError:无法写入合法的 LP 文件。目标“目标”具有非二次的非线性项。

请求帮助

有人可以指出解决上述两个问题的正确方向吗?任何帮助将不胜感激!

代码

import os
import pandas as pd
from pyomo.environ import *
import datetime


def model_to_df(model, first_period, last_period):

    # Need to increase the first & last hour by 1 because of pyomo indexing
    periods = range(model.T[first_period + 1], model.T[last_period + 1] + 1)
    spot = [value(model.spot[i]) for i in periods]
    load = [value(model.load[i]) for i in periods]
    slr1 = [value(model.slr1_size[i]) for i in periods]
    slr2 = [value(model.slr2_size[i]) for i in periods]
    slr3 = [value(model.slr3_size[i]) for i in periods]
    wnd1 = [value(model.wnd1_size[i]) for i in periods]
    wnd2 = [value(model.wnd2_size[i]) for i in periods]
    wnd3 = [value(model.wnd3_size[i]) for i in periods]
    d_slrgen_var = [value(model.d_slrgen_var[i]) for i in periods]
    d_wndgen_var = [value(model.d_wndgen_var[i]) for i in periods]
    d_spill_var = [value(model.d_spill_var[i]) for i in periods]
    d_selfcons_var = [value(model.d_selfcons_var[i]) for i in periods]

    df_dict = {
        'Period': periods,
        'spot': spot,
        'load': load,
        'slr1': slr1,
        'slr2': slr2,
        'slr3': slr3,
        'wnd1': wnd1,
        'wnd2': wnd2,
        'wnd3': wnd3,
        'd_slrgen_var': d_slrgen_var,
        'd_wndgen_var': d_wndgen_var,
        'd_spill_var': d_spill_var,
        'd_selfcons_var': d_selfcons_var
    }

    df = pd.DataFrame(df_dict)

    return df

LOCATION = r"C:\cbc-win64"
os.environ["PATH"] = LOCATION + ";" + os.environ["PATH"]

df = pd.DataFrame({
    'hour': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23],
    'load': [100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100],
    'spot': [65.4, 62.7, 60.9, 60.3, 61.8, 64.5, 65.9, 57.9, 39.7, 28.3, 20.9, 16.3, 18.1, 23.9, 32.3, 43.2, 59.3, 76.3, 80.5, 72.5, 73.1, 69.0, 67.9, 67.7],
    'slr1': [0.00, 0.00, 0.00, 0.00, 0.00, 0.04, 0.20, 0.44, 0.60, 0.69, 0.71, 0.99, 1.00, 0.66, 0.75, 0.63, 0.52, 0.34, 0.14, 0.02, 0.00, 0.00, 0.00, 0.00],
    'slr2': [0.00, 0.00, 0.00, 0.00, 0.03, 0.19, 0.44, 0.68, 1.00, 0.83, 0.90, 0.88, 0.98, 0.94, 0.83, 0.70, 0.36, 0.11, 0.02, 0.00, 0.00, 0.00, 0.00, 0.00],
    'slr3': [0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.03, 0.17, 0.39, 0.87, 0.91, 1.00, 0.89, 0.71, 0.71, 0.85, 0.63, 0.52, 0.32, 0.12, 0.02, 0.00, 0.00, 0.00],
    'wnd1': [1.00, 0.72, 0.74, 0.94, 0.69, 0.90, 0.92, 0.76, 0.51, 0.35, 0.31, 0.34, 0.37, 0.28, 0.35, 0.40, 0.39, 0.32, 0.42, 0.48, 0.74, 0.63, 0.80, 0.97],
    'wnd2': [0.95, 0.67, 0.82, 0.48, 0.51, 0.41, 0.33, 0.42, 0.34, 0.30, 0.39, 0.29, 0.34, 0.55, 0.67, 0.78, 0.84, 0.73, 0.77, 0.89, 0.76, 0.97, 1.00, 0.91],
    'wnd3': [0.32, 0.35, 0.38, 0.28, 0.33, 0.38, 0.41, 0.38, 0.51, 0.65, 0.54, 0.88, 0.93, 0.89, 0.90, 1.00, 0.90, 0.76, 0.76, 0.92, 0.71, 0.56, 0.52, 0.40]
})

first_model_period = df['hour'].iloc[0]
last_model_period = df['hour'].iloc[-1]

# **********************
# Build Model
# **********************
model = ConcreteModel()

# Fixed Paramaters
model.T = Set(initialize=df.index.tolist(), doc='hourly intervals', ordered=True)

model.load_v = Param(model.T, initialize=df.load, doc='customers load', within=Any)
model.spot_v = Param(model.T, initialize=df.spot, doc='spot price for each interval', within=Any)

model.slr1 = Param(model.T, initialize=df.slr1, doc='1MW output solar farm 1', within=Any)
model.slr2 = Param(model.T, initialize=df.slr2, doc='1MW output solar farm 2', within=Any)
model.slr3 = Param(model.T, initialize=df.slr3, doc='1MW output solar farm 3', within=Any)
model.wnd1 = Param(model.T, initialize=df.wnd1, doc='1MW output wind farm 1', within=Any)
model.wnd2 = Param(model.T, initialize=df.wnd2, doc='1MW output wind farm 2', within=Any)
model.wnd3 = Param(model.T, initialize=df.wnd3, doc='1MW output wind farm 3', within=Any)

# Variable Parameters
model.slr1_flag = Var(model.T, doc='slr 1 on / off', within=Binary, initialize=0)
model.slr2_flag = Var(model.T, doc='slr 2 on / off', within=Binary, initialize=0)
model.slr3_flag = Var(model.T, doc='slr 3 on / off', within=Binary, initialize=0)
model.wnd1_flag = Var(model.T, doc='wnd 1 on / off', within=Binary, initialize=0)
model.wnd2_flag = Var(model.T, doc='wnd 2 on / off', within=Binary, initialize=0)
model.wnd3_flag = Var(model.T, doc='wnd 3 on / off', within=Binary, initialize=0)

model.slr1_size = Var(model.T, bounds=(0, 1500), doc='selected size in MWs', initialize=0, within=NonNegativeIntegers)
model.slr2_size = Var(model.T, bounds=(0, 1500), doc='selected size in MWs', initialize=0, within=NonNegativeIntegers)
model.slr3_size = Var(model.T, bounds=(0, 1500), doc='selected size in MWs', initialize=0, within=NonNegativeIntegers)
model.wnd1_size = Var(model.T, bounds=(0, 1500), doc='selected size in MWs', initialize=0, within=NonNegativeIntegers)
model.wnd2_size = Var(model.T, bounds=(0, 1500), doc='selected size in MWs', initialize=0, within=NonNegativeIntegers)
model.wnd3_size = Var(model.T, bounds=(0, 1500), doc='selected size in MWs', initialize=0, within=NonNegativeIntegers)

model.total_gen = Var(model.T, initialize=0, within=NonNegativeReals)


# Dependent Expression Parameters
def dependent_solar_gen(model, t):
    "Total selected solar Generation"
    return (model.slr1[t] * model.slr1_flag[t] * model.slr1_size[t]) + \
           (model.slr2[t] * model.slr2_flag[t] * model.slr2_size[t]) + \
           (model.slr3[t] * model.slr3_flag[t] * model.slr3_size[t])


model.d_slrgen_var = Expression(model.T, rule=dependent_solar_gen)


def dependent_wind_gen(model, t):
    "Total selected wind Generation"
    return (model.wnd1[t] * model.wnd1_flag[t] * model.wnd1_size[t]) + \
           (model.wnd2[t] * model.wnd2_flag[t] * model.wnd2_size[t]) + \
           (model.wnd3[t] * model.wnd3_flag[t] * model.wnd3_size[t])


model.d_wndgen_var = Expression(model.T, rule=dependent_wind_gen)


def dependent_spill(model, t):
    "Volume of energy not consumed by customer (spilled into grid)"
    expr = (model.d_slrgen_var[t] + model.d_wndgen_var[t]) - model.load_v[t]
    return max(0, expr)


model.d_spill_var = Expression(model.T, rule=dependent_spill)


def dependent_self_cons(model, t):
    "Volume of energy consumed by customer"
    expr = (model.d_slrgen_var[t] + model.d_wndgen_var[t]) - model.d_spill_var[t]
    return expr


model.d_selfcons_var = Expression(model.T, rule=dependent_self_cons)


# -----------------------
# Constraints
# -----------------------
def min_spill(model, t):
    "Limit spill renewables to 10% of total"
    return model.d_spill_var[t] <= 0.1 * (model.d_slrgen_var[t] + model.d_wndgen_var[t])


model.min_spill_c = Constraint(model.T, rule=min_spill)


def load_match(model, t):
    "contract enough renewables to offset 100% load, even if its not time matched"
    return (model.d_slrgen_var[t] + model.d_wndgen_var[t]) >= model.load_v[t]


model.load_match_c = Constraint(model.T, rule=load_match)

# **********************
# Define the battery income, expenses, and profit
# **********************
green_income = sum(model.spot_v[t] * model.d_spill_var[t] for t in model.T)
black_cost = sum(model.spot_v[t] * (model.load_v[t] - model.d_selfcons_var[t]) for t in model.T)
slr_cost = sum(40 * model.d_slrgen_var[t] for t in model.T)
wnd_cost = sum(70 * model.d_wndgen_var[t] for t in model.T)
profit = green_income - black_cost - slr_cost - wnd_cost

model.objective = Objective(expr=profit, sense=maximize)

# Solve the model
# solver = SolverFactory('glpk')
solver = SolverFactory('cbc')
solver.solve(model, timelimit=10)

results_df = model_to_df(model, first_period=first_model_period, last_period=last_model_period)

print(results_df)
python optimization pyomo nonlinear-optimization linear-optimization
© www.soinside.com 2019 - 2024. All rights reserved.