Вопрос или проблема
Я моделирую оптимальное поведение бытовой батареи. Цена покупки из сети отличается от цены продажи в сеть (цена покупки всегда выше). Как мне правильно смоделировать это? В настоящее время я постоянно сталкиваюсь с проблемой, что линейная релаксация является невыполнимой.
`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 вы столкнулись с проблемой недостижимости линейной релаксации. Это может произойти по нескольким причинам, связанным как с настройкой самой модели, так и с некорректными данными. Давайте подробно разберем возможные слабые места в вашем коде и предложим решения.
Основные проблемы
-
Логические ошибки в определении переменных и ограничений: Когда вы задаете переменные, важно убедиться, что они корректно отражают реалии: токи зарядки и разрядки, уровни заряда и т.д. Некоторые ограничения могут конфликтовать друг с другом.
-
Несоответствующие логические связи между переменными: Ваша модель должна обеспечить корректные связи между переменными зарядки/разрядки батареи и покупок/продаж энергии из сети.
-
Неправильная инициализация или преобразование данных: Убедитесь, что данные, загружаемые из 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 может быть решена путем анализа логики вашей модели, проверки взаимосвязей между переменными и корректного извлечения данных. Убедитесь, что все ограничения взаимодополняющи и что они соответствуют физическим возможностям батареи. Применяя все предложенные рекомендации, вы сможете улучшить вашу модель и добиться корректного решения задачи оптимизации.
Не забывайте проводить периодические тесты и отладку вашей модели, чтобы убедиться в ее работоспособности!