building-agents/generate_optimization.py

191 lines
6.2 KiB
Python

import numpy as np
import pandas as pd
import json
from scipy.optimize import minimize
from pyswarm import pso
# 读取数据
file_path = './data.csv'
data = pd.read_csv(file_path)
# 初始化状态
initial_soc = 0.4 # 电池初始荷电状态
initial_sg1 = 0
initial_sg2 = 0
initial_sg3 = 0
battery_capacity = 500 * initial_soc
# 参数设置
battery_efficiency = 0.9
battery_degradation = 0.01
battery_holding = 0.1
solar_cofficient = 0.01
volatage_change_percent = 0.1
wind_cofficient = 0.01
# 发电机参数
DG_parameters = {
'gen_1': {'a': 0.0034, 'b': 3, 'c': 30, 'power_output_max': 150, 'power_output_min': 10, 'ramping_up': 100,
'ramping_down': 100},
'gen_2': {'a': 0.001, 'b': 10, 'c': 40, 'power_output_max': 375, 'power_output_min': 50, 'ramping_up': 100,
'ramping_down': 100},
'gen_3': {'a': 0.001, 'b': 15, 'c': 70, 'power_output_max': 500, 'power_output_min': 100, 'ramping_up': 200,
'ramping_down': 200}
}
NUM_GEN = len(DG_parameters.keys())
period = 100 # 处理前 100 个数据
def get_dg_info(parameters):
p_max = []
p_min = []
ramping_up = []
ramping_down = []
a_para = []
b_para = []
c_para = []
for name, gen_info in parameters.items():
p_max.append(gen_info['power_output_max'])
p_min.append(gen_info['power_output_min'])
ramping_up.append(gen_info['ramping_up'])
ramping_down.append(gen_info['ramping_down'])
a_para.append(gen_info['a'])
b_para.append(gen_info['b'])
c_para.append(gen_info['c'])
return p_max, p_min, ramping_up, ramping_down, a_para, b_para, c_para
p_max, p_min, ramping_up, ramping_down, a_para, b_para, c_para = get_dg_info(parameters=DG_parameters)
# 目标函数
def objective(x, period_batch, start, initial_states):
total_cost = 0
soc, sg1, sg2, sg3 = initial_states
for t in range(period_batch):
Ac, Ag1, Ag2, Ag3, Av = x[t * 5:(t + 1) * 5]
Pc = max(0.2, min(0.8, soc + 0.2 * Ac * 0.9))
Pg1 = max(0, min(150, 100 * Ag1 + sg1))
Pg2 = max(0, min(375, 100 * Ag2 + sg2))
Pg3 = max(0, min(500, 200 * Ag3 + sg3))
Pso = max(0, (0.2 * data['irradiance'][start + t] + 0.05 * data['temperature'][start + t] - 9.25) * (1 + Av))
if 3 <= data['wind_speed'][start + t] < 8:
Pw = data['wind_speed'][start + t] ** 3 * 172.2625 / 1000
elif 8 <= data['wind_speed'][start + t] < 12:
Pw = 64 * 172.2625 / 125
else:
Pw = 0
P = Pc + Pg1 + Pg2 + Pg3 + Pso + Pw
if P >= data['load'][start + t]:
Ee = P - data['load'][start + t]
Es = 0
else:
Es = data['load'][start + t] - P
Ee = 0
Cb = 0.01 * battery_capacity + 0.1 * Pc
Cg1 = 0.0034 * Pg1 ** 2 + 3 * Pg1 + 30
Cg2 = 0.001 * Pg2 ** 2 + 10 * Pg2 + 40
Cg3 = 0.001 * Pg3 ** 2 + 15 * Pg3 + 70
Cs = 0.01 * Pso
Cw = 0.01 * Pw
Rs = 0.5 * data['price'][start + t] * Ee
Cp = data['price'][start + t] * Es
Pe = (Ee - 100) * 50 if Ee > 100 else 0
Ps = (Es - 100) * 50 if Es > 100 else 0
total_cost += (Cb + Cg1 + Cg2 + Cg3 + Cs + Cw + Pe + Ps - Rs + Cp) / 1000
soc = Pc
sg1 = Pg1
sg2 = Pg2
sg3 = Pg3
return total_cost
# 约束条件
def constraint(x, period_batch, start, initial_states):
constraints = []
soc, sg1, sg2, sg3 = initial_states
for t in range(period_batch):
Ac, Ag1, Ag2, Ag3, Av = x[t * 5:(t + 1) * 5]
Pc = max(0.2, min(0.8, soc + 0.2 * Ac * 0.9))
Pg1 = max(10, min(150, 100 * Ag1 + sg1))
Pg2 = max(50, min(375, 100 * Ag2 + sg2))
Pg3 = max(100, min(500, 200 * Ag3 + sg3))
Pso = max(0, (0.2 * data['irradiance'][start + t] + 0.05 * data['temperature'][start + t] - 9.25) * (1 + Av))
if 3 <= data['wind_speed'][start + t] < 8:
Pw = data['wind_speed'][start + t] ** 3 * 172.2625 / 1000
elif 8 <= data['wind_speed'][start + t] < 12:
Pw = 64 * 172.2625 / 125
else:
Pw = 0
P = Pc + Pg1 + Pg2 + Pg3 + Pso + Pw
# 保证变化后的值不小于最小值
constraints.append(Pc - 0.2)
constraints.append(Pg1 - 10)
constraints.append(Pg2 - 50)
constraints.append(Pg3 - 100)
constraints.append(P - data['load'][start + t])
soc = Pc
sg1 = Pg1
sg2 = Pg2
sg3 = Pg3
return constraints
actions = []
batch_size = 10 # 每次处理 10 个数据
total_batches = 10 # 总共处理 100 个数据
start = 0
for batch_num in range(total_batches):
end = min(start + batch_size, period)
period_batch = end - start
# 初始化初始状态
initial_states = (initial_soc, initial_sg1, initial_sg2, initial_sg3)
# # 使用随机初始化更接近实际情况
# x0 = np.random.uniform(0, 1, period_batch * 5)
# bounds = [(-1, 1)] * (period_batch * 5)
# cons = {'type': 'ineq', 'fun': lambda x: constraint(x, period_batch, start, initial_states)}
# result = minimize(lambda x: objective(x, period_batch, start, initial_states), x0, method='SLSQP', bounds=bounds,
# constraints=cons)
#
# actions.extend(result.x.reshape((period_batch, 5)).tolist())
# 使用粒子群优化算法
lb = [-1] * (period_batch * 5)
ub = [1] * (period_batch * 5)
xopt, fopt = pso(lambda x: objective(x, period_batch, start, initial_states), lb, ub,
ieqcons=[lambda x: constraint(x, period_batch, start, initial_states)], maxiter=100, swarmsize=50)
actions.extend(xopt.reshape((period_batch, 5)).tolist())
# 更新初始状态为当前批次最后一个状态
last_action = actions[-1]
initial_soc = max(0.2, min(0.8, initial_soc + 0.2 * last_action[0] * 0.9))
initial_sg1 = max(10, min(150, 100 * last_action[1] + initial_sg1))
initial_sg2 = max(50, min(375, 100 * last_action[2] + initial_sg2))
initial_sg3 = max(100, min(500, 200 * last_action[3] + initial_sg3))
start += batch_size
actions_json_path = './actions_batch_p.json'
try:
with open(actions_json_path, 'w') as f:
json.dump(actions, f)
print(f"文件保存成功:{actions_json_path}")
except Exception as e:
print(f"文件保存失败:{e}")