building-agents/genrtic_gpu_7.22.py

184 lines
7.2 KiB
Python

import json
import os
import time
import numpy as np
import pandas as pd
import torch
from concurrent.futures import ThreadPoolExecutor
from deap import base, creator, tools, algorithms
def fitness_torch(individuals, price, load, temperature, irradiance, wind_speed, prev_soc, prev_Pg1, prev_Pg2, prev_Pg3,
device):
individuals_torch = torch.tensor(individuals, device=device)
num = individuals_torch.shape[0]
Ac, Ag1, Ag2, Ag3, Av = [individuals_torch[:, i * period:(i + 1) * period] for i in range(5)]
# soc = torch.zeros((num, period), device=device)
# Pg1, Pg2, Pg3 = [torch.zeros((num, period), device=device) for _ in range(3)]
# Cb, Cg1, Cg2, Cg3, Cs, Cw, Rs, Cp, Pe, Ps, Ee, Es = [torch.zeros((num, period), device=device) for _ in range(12)]
soc = torch.clamp(prev_soc + 0.2 * Ac * 0.9, 0.2, 0.8)
Pg1 = torch.clamp(prev_Pg1 + 100 * Ag1, min=0, max=150)
Pg2 = torch.clamp(prev_Pg2 + 100 * Ag2, min=0, max=375)
Pg3 = torch.clamp(prev_Pg3 + 200 * Ag3, min=0, max=500)
Pso = torch.clamp((0.2 * irradiance + 0.05 * temperature - 9.25) * (1 + Av), min=0)
Pw = torch.where(
(wind_speed >= 3) & (wind_speed < 8),
wind_speed ** 3 * 172.2625 / 1000,
torch.where(
(wind_speed >= 8) & (wind_speed < 12),
64 * 172.2625 / 125,
torch.zeros_like(wind_speed)
)
)
P = Ac + Pg1 + Pg2 + Pg3 + Pso + Pw
Ee = torch.where(P >= load, P - load, torch.zeros_like(P))
Es = torch.where(P < load, load - P, torch.zeros_like(P))
Cb = 0.01 * Ac + 0.1 * soc
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 * price * Ee
Cp = price * Es
Pe = torch.where(Ee > 100, (Ee - 100) * 50, torch.zeros_like(Ee))
Ps = torch.where(Es > 100, (Es - 100) * 50, torch.zeros_like(Es))
total_cost = torch.sum(Cb + Cg1 + Cg2 + Cg3 + Cs + Cw + Pe + Ps - Rs + Cp, dim=1)
reward = -total_cost / 1000
return reward.cpu().numpy(), soc.cpu().numpy(), Pg1.cpu().numpy(), Pg2.cpu().numpy(), Pg3.cpu().numpy()
def save_decision_values(best_ind, period, index):
decisions = {
'Ac': best_ind[0],
'Ag1': best_ind[1],
'Ag2': best_ind[2],
'Ag3': best_ind[3],
'Av': best_ind[4]
}
with open(f'decision_values_{period}_index_{index}.json', 'w') as f:
json.dump(decisions, f)
def save_progress(population, period):
population_data = [ind.tolist() for ind in population]
with open(f'population_{period}.json', 'w') as f:
json.dump({'period': period, 'population': population_data}, f)
def load_progress():
if os.path.exists('population_gen_499.json'):
with open('population_gen_499.json', 'r') as f:
data = json.load(f)
return data['population'], data['period']
return None, 0
def check_bounds(func):
def wrapper(*args, **kwargs):
offspring = func(*args, **kwargs)
if offspring[0] is None or offspring[1] is None:
print("Error: One of the offspring is None", offspring)
raise ValueError("Offspring cannot be None.")
for child in offspring:
for i in range(len(child)):
if child[i] < -1:
child[i] = -1
elif child[i] > 1:
child[i] = 1
return offspring
return wrapper
def main():
period = 8760
NGEN = 500
CXPB, MUTPB = 0.7, 0.2
batch_size = 500
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
data = pd.read_csv('./data.csv')
price, load, temperature, irradiance, wind_speed = [data[col].values for col in
['price', 'load', 'temperature', 'irradiance', 'wind_speed']]
creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
creator.create("Individual", list, fitness=creator.FitnessMin)
toolbox = base.Toolbox()
toolbox.register("attr_float", np.random.uniform, -1, 1)
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_float, 5)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
toolbox.register("mate", check_bounds(tools.cxBlend), alpha=0.5)
toolbox.register("mutate", check_bounds(tools.mutGaussian), mu=0, sigma=0.1, indpb=0.2)
toolbox.register("select", tools.selTournament, tournsize=3)
toolbox.register("evaluate", fitness_torch)
population = load_progress()
if population is None:
population = toolbox.population(n=NGEN)
print("Initial population:", len(population), "and first individual:", population[0])
prev_soc = torch.tensor([0.4] * NGEN, device=device)
prev_Pg1 = torch.zeros(NGEN, device=device)
prev_Pg2 = torch.zeros(NGEN, device=device)
prev_Pg3 = torch.zeros(NGEN, device=device)
for index in range(period):
for gen in range(NGEN):
start_time = time.time()
offspring = algorithms.varAnd(population, toolbox, cxpb=CXPB, mutpb=MUTPB)
num_individuals = len(offspring)
with ThreadPoolExecutor() as executor:
futures = []
for i in range(0, num_individuals, batch_size):
batch = offspring[i:i + batch_size]
individuals = [ind[:] for ind in batch]
futures.append(
executor.submit(toolbox.evaluate, individuals, price[index], load[index], temperature[index],
irradiance[index], wind_speed[index], prev_soc, prev_Pg1, prev_Pg2, prev_Pg3,
device)
)
for future in futures:
fitnesses, socs, Pg1s, Pg2s, Pg3s = zip(*future.result())
for ind, fitness in zip(offspring, fitnesses):
ind.fitness.values = (fitness,)
prev_soc[:len(socs)] = torch.tensor(socs, device=device)
prev_Pg1[:len(Pg1s)] = torch.tensor(Pg1s, device=device)
prev_Pg2[:len(Pg2s)] = torch.tensor(Pg2s, device=device)
prev_Pg3[:len(Pg3s)] = torch.tensor(Pg3s, device=device)
population = toolbox.select(offspring, k=len(population))
print("Population after selection:", population[:5])
end_time = time.time()
print(f"{index + 1}小时完成花费 {end_time - start_time:.2f}")
best_ind = tools.selBest(population, 1)[0]
print('最佳个体:', best_ind)
print('适应度:', best_ind.fitness.values)
save_decision_values(best_ind, period, index)
save_progress(population, period)
prev_soc.fill_(0.4)
prev_Pg1.fill_(0)
prev_Pg2.fill_(0)
prev_Pg3.fill_(0)
prev_soc[:len(best_ind)] = torch.tensor(best_ind[:period], device=device)
prev_Pg1[:len(best_ind)] = torch.tensor(best_ind[period:2 * period], device=device)
prev_Pg2[:len(best_ind)] = torch.tensor(best_ind[2 * period:3 * period], device=device)
prev_Pg3[:len(best_ind)] = torch.tensor(best_ind[3 * period:4 * period], device=device)
if __name__ == "__main__":
main()