Линейная релаксация невозможна в PuLP

Вопрос или проблема

Я моделирую оптимальное поведение бытовой батареи. Цена покупки из сети отличается от цены продажи в сеть (цена покупки всегда выше). Как мне правильно смоделировать это? В настоящее время я постоянно сталкиваюсь с проблемой, что линейная релаксация является невыполнимой.

`import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from pulp import LpMaximize, LpProblem, LpVariable, lpSum, LpBinary

# Константы
BATTERY_CAPACITY = 5  # кВтч
BATTERY_EFFICIENCY = 0.9  # %
MAX_CHARGE_RATE = 1  # кВт
MAX_DISCHARGE_RATE = 1  # кВт
HOURS_IN_YEAR = 24 * 365
HOURS_IN_DAY = 24
YEARLY_USE = 5700
YEARLY_PV_GEN = 0

# Чтение данных из CSV файла
data = pd.read_csv('DynamicPriceInput.csv', sep=';', decimal=",")

# Корректировка почасовых значений по годовым итогам
data['pv_generation'] *= YEARLY_PV_GEN
data['household_load'] *= YEARLY_USE

# Инициализация задачи линейного программирования
prob = LpProblem("Battery_Optimization", LpMaximize)

# Переменные решения для зарядки/разрядки
charge_discharge = LpVariable.dicts("charge_discharge", range(HOURS_IN_YEAR), -MAX_DISCHARGE_RATE, MAX_CHARGE_RATE)
soc = LpVariable.dicts("soc", range(HOURS_IN_YEAR), 0, BATTERY_CAPACITY)

# Вспомогательные переменные для покупки и продажи
buy_from_grid = LpVariable.dicts("buy_from_grid", range(HOURS_IN_YEAR), lowBound=0)
sell_to_grid = LpVariable.dicts("sell_to_grid", range(HOURS_IN_YEAR), lowBound=0)

for t in range(HOURS_IN_YEAR):
    # Чистая нагрузка сети — это разница между нагрузкой домохозяйства, генерацией солнечной энергии и зарядкой/разрядкой батареи
    net_load = data['household_load'][t] - data['pv_generation'][t] + charge_discharge[t]

    # Применение ограничения, что чистая нагрузка либо покупается, либо продается из/в сеть
    prob += net_load == buy_from_grid[t] - sell_to_grid[t]

# Целевая функция для минимизации чистых затрат (покупка из сети минус продажа в сеть)
prob += lpSum([
    buy_from_grid[t] * data['buy_price'][t] - sell_to_grid[t] * data['sell_price'][t]
    for t in range(HOURS_IN_YEAR)
])

# Ограничения
for t in range(1, HOURS_IN_YEAR):
    prob += soc[t] == soc[t-1] + (charge_discharge[t] * BATTERY_EFFICIENCY)
    prob += soc[t] >= 0  # SOC не может быть отрицательным
    prob += soc[t] <= BATTERY_CAPACITY  # SOC не может превышать емкость батареи

# Решение задачи
prob.solve()`

Ответ или решение

Решение проблемы недостижимости линейной релаксации в PuLP

При моделировании оптимального поведения батареи для домохозяйства с использованием библиотеки PuLP вы столкнулись с проблемой недостижимости линейной релаксации. Это может произойти по нескольким причинам, связанным как с настройкой самой модели, так и с некорректными данными. Давайте подробно разберем возможные слабые места в вашем коде и предложим решения.

Основные проблемы

  1. Логические ошибки в определении переменных и ограничений: Когда вы задаете переменные, важно убедиться, что они корректно отражают реалии: токи зарядки и разрядки, уровни заряда и т.д. Некоторые ограничения могут конфликтовать друг с другом.

  2. Несоответствующие логические связи между переменными: Ваша модель должна обеспечить корректные связи между переменными зарядки/разрядки батареи и покупок/продаж энергии из сети.

  3. Неправильная инициализация или преобразование данных: Убедитесь, что данные, загружаемые из CSV, корректны и не содержат нулевых значений, что может привести к недостижимости решения.

Возможные решения

1. Проверка логики ограничений

Убедитесь, что в вашем коде заложены правильные зависимости между переменными. Например, в части ограничения для обеспечения уровня заряда батареи (SoC):

for t in range(1, HOURS_IN_YEAR):
    prob += soc[t] == soc[t-1] + (charge_discharge[t] * BATTERY_EFFICIENCY)

Это ограничение предполагает, что зарядка/разрядка батареи влияет на уровень заряда, однако преобразование charge_discharge учитывает эффективность батареи и может не учитывать, что батарея не может одновременно заряжаться и разряжаться. Необходимо четко определить, что charge_discharge может принимать только положительные или отрицательные значения в зависимости от контекста (т.е., зарядка или разрядка).

2. Общая формулировка задачи

Ваше определение целевой функции также может быть потенциальным источником проблемы. Убедитесь, что функция включает все выходные и входные параметры корректно:

prob += lpSum([
    buy_from_grid[t] * data['buy_price'][t] - sell_to_grid[t] * data['sell_price'][t]
    for t in range(HOURS_IN_YEAR)
])

Не забывайте, что пиковые нагрузки и цены могут существенно повлиять на возможность нахождения допустимого решения. Проверьте также наличие нулевых или отрицательных цен.

3. Выявление конфликтующих ограничений

В вашем коде вы добавили ограничения на уровне заряда (SoC), которые могут быть конфликтующими:

prob += soc[t] >= 0  # SoC не может быть отрицательным
prob += soc[t] <= BATTERY_CAPACITY  # SoC не может превышать емкость батареи

В случае если заряд в battery unknown или так же если не может достигнуть определённого уровня примерно в случае покупки и продажи энергии, вам стоит добавить проверки, которые учитывают как максимальную, так и минимальную мощность.

4. Проверка входных данных

Обязательно проверьте CSV-файл (DynamicPriceInput.csv), чтобы убедиться, что не содержатся пропуски или аномальные значения. Поля с нулевыми или отрицательными значениями могут значительно изменять поведение модели.

Заключение

Проблема недостижимости линейной релаксации в PuLP может быть решена путем анализа логики вашей модели, проверки взаимосвязей между переменными и корректного извлечения данных. Убедитесь, что все ограничения взаимодополняющи и что они соответствуют физическим возможностям батареи. Применяя все предложенные рекомендации, вы сможете улучшить вашу модель и добиться корректного решения задачи оптимизации.

Не забывайте проводить периодические тесты и отладку вашей модели, чтобы убедиться в ее работоспособности!

Оцените материал
Добавить комментарий

Капча загружается...