From 698d1ff7ddeead21e7d80b211b79f5f0b569c72a Mon Sep 17 00:00:00 2001 From: KuMiShi Date: Sun, 18 Jan 2026 12:27:51 +0100 Subject: [PATCH] Main Modifications --- .gitignore | 9 +------- README.md | 2 ++ data/elec_prices.csv | 2 +- main.py | 54 ++++++++++++++++++++++++++++++++++++++++---- mopso.py | 5 ++-- pyproject.toml | 3 +++ uv.lock | 36 +++++++++++++++++++++++++++-- 7 files changed, 93 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index 351bb5e..1ba351f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,3 @@ -# Scripts -main.py - # UV Environment .python-version -.venv - -# Datasets -dataset.py -data/capacity.csv \ No newline at end of file +.venv \ No newline at end of file diff --git a/README.md b/README.md index 7f01b48..337737f 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ Pour les datasets, nous avons pris diverses sources pour concevoir notre propre ## Installation Le projet a été concu à l'aide du *Python packet manager* ***UV***, il est préférable d'utiliser celui-ci pour ca facilité d'utilisation. **UV** peut être installé via le [site internet officiel](https://docs.astral.sh/uv/getting-started/installation/#installing-uv). +POur télécharger le projet vous pouvez simplement utiliser la commande `git clone https://gitea.galaxynoliro.fr/KuMiShi/Optim_Metaheuristique.git` ou récupérer le fichier `.zip` du projet et l'extraire. + **Linux:** ```bash # Installation de UV diff --git a/data/elec_prices.csv b/data/elec_prices.csv index 80ebfd2..2eba689 100644 --- a/data/elec_prices.csv +++ b/data/elec_prices.csv @@ -14,7 +14,7 @@ Winter 2025; Summer 2025 12.54; 76.77 0.4; 63.01 60.01; 54.1 -1158; 69.52 +115.8; 69.52 93.49; 94.16 71.25; 30.5 79.76; 46.2 diff --git a/main.py b/main.py index 47d740b..09e2965 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,5 @@ import time +import pandas as pd import numpy as np import matplotlib.pyplot as plt import copy @@ -6,7 +7,6 @@ from mopso import MOPSO from surrogate_handler import SurrogateHandler # --- EXTENDED CLASS (Inheritance) --- - class SmartMOPSO(MOPSO): def __init__(self, model_type=None, **kwargs): super().__init__(**kwargs) @@ -66,14 +66,60 @@ class SmartMOPSO(MOPSO): self.update_archive() +def calculate_elec_prices(csv_file:str, sep:str=';'): + elec_df = pd.read_csv(filepath_or_buffer=csv_file, sep=sep) + + # Mean of Winter and Summer of 2025 electric prices (Euros/MWh) + elec_mean = (elec_df['Winter 2025'].mean() + elec_df['Summer 2025'].mean())/2 + + # Standard variation of Winter and Summer of 2025 electric prices (Euros/MWh) + elec_std = (elec_df['Winter 2025'].std() + elec_df['Summer 2025'].std())/2 + + print(f'Electricity prices:\n - Mean: ${elec_mean}€/Mwh\n - Std: ${elec_std}€/Mwh') + return elec_mean, elec_std + +def generate_capacities(csv_file:str, nb_vehicles:int, seed:int=42, sep:str=';'): + cap_df = pd.read_csv(filepath_or_buffer=csv_file, sep=sep) + + # Getting back all kind of battery capacities with unique values + all_capacities = cap_df['Battery Capacity kwh'].dropna().unique() + + # Extracting random values for generating the array of capacities + capacities = pd.Series(all_capacities).sample(n=nb_vehicles, random_state=seed) + + print(f'Capacities of vehicles (kwh): ${capacities}') + return capacities + # --- EXECUTION FUNCTION --- def run_scenario(scenario_name, model_type=None): + elec_price_csv = 'data/elec_prices.csv' + capacity_csv = 'data/vehicle_capacity.csv' + + # Simulation parameters + N = 20 # Number of vehicles + T = 30 # Number of iterations (for the particles) + W = 0.4 # Inertia (for exploration) + C1 = 0.3 # Individual trust + C2 = 0.2 # Social trust + ARC_SIZE = 10 # Archive size + + P_MEAN, P_STD = calculate_elec_prices(elec_price_csv) + CAPACITIES = generate_capacities(capacity_csv, N) + + NB_TICKS = 48 + DELTA = 60 + + A_MAX = 0 + X_MAX = 0 + X_MIN = 0 + + print(f"\n--- Launching Scenario: {scenario_name} ---") start_time = time.time() # Simulation parameters params = { - 'f_weights': [1,1,1], 'A_max': 500, 'price_mean': 0.15, 'price_std': 0.05, + 'A_max': 500, 'price_mean': 0.15, 'price_std': 0.05, 'capacities': [50]*10, 'n': 20, 't': 50, 'w': 0.4, 'c1': 2.0, 'c2': 2.0, 'nb_vehicles': 10, 'delta_t': 60, 'nb_of_ticks': 72 @@ -88,8 +134,8 @@ def run_scenario(scenario_name, model_type=None): end_time = time.time() duration = end_time - start_time - # Retrieve best f2 (e.g., from archive) - best_f2 = min([p.f_current[1] for p in optimizer.archive]) if optimizer.archive else 0 + # Retrieve best f2 (e.g. from archive) + best_f2 = min([p.f_best[1] for p in optimizer.archive]) if optimizer.archive else 0 print(f"Finished in {duration:.2f} seconds.") print(f"Best f2 found: {best_f2:.4f}") diff --git a/mopso.py b/mopso.py index 3aa17d1..ee9f0fc 100644 --- a/mopso.py +++ b/mopso.py @@ -3,7 +3,7 @@ from .particle import Particle import copy class MOPSO(): - def __init__(self, f_weights:list, A_max:float, price_mean:float, price_std:float, capacities:list, n:int, t:int, w:float, c1:float, c2:float, archive_size:int=10, nb_vehicles:int=10, delta_t:int=60, nb_of_ticks:int=72, x_min=-100, x_max=100, v_alpha=0.1, surrogate=False): + def __init__(self, A_max:float, price_mean:float, price_std:float, capacities:list, n:int, t:int, w:float, c1:float, c2:float, archive_size:int=10, nb_vehicles:int=10, delta_t:int=60, nb_of_ticks:int=72, x_min=-100, x_max=100, v_alpha=0.1, surrogate=False): # Constants self.n = n # Number of particles self.t = t # Number of simulation iterations @@ -11,7 +11,6 @@ class MOPSO(): self.c1 = c1 # Individual trust self.c2 = c2 # Social trust self.archive_size = archive_size # Archive size - self.f_weights = f_weights # Weigths for aggregation of all function objective self.surrogate = surrogate # Using AI calculation @@ -71,7 +70,7 @@ class MOPSO(): # Checking for best positions # Generation of arriving and leaving times for every vehicle - def generate_times(self, nb_vehicles, nb_of_ticks, delta_t): + def generate_times(self, nb_vehicles, nb_of_ticks): times = [] for _ in range(nb_vehicles): # Minumun, we have one tick of charging/discharging during simulation diff --git a/pyproject.toml b/pyproject.toml index 763bb55..2f89a05 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,5 +5,8 @@ description = "Metaheuristic Optimization Project" readme = "README.md" requires-python = ">=3.11" dependencies = [ + "matplotlib>=3.10.8", + "numpy>=2.4.1", "pandas>=2.3.3", + "scikit-learn>=1.8.0", ] diff --git a/uv.lock b/uv.lock index 74617ec..667706e 100644 --- a/uv.lock +++ b/uv.lock @@ -1,14 +1,46 @@ # This file was autogenerated by uv via the following command: # uv pip compile pyproject.toml -o uv.lock +contourpy==1.3.3 + # via matplotlib +cycler==0.12.1 + # via matplotlib +fonttools==4.61.1 + # via matplotlib +joblib==1.5.3 + # via scikit-learn +kiwisolver==1.4.9 + # via matplotlib +matplotlib==3.10.8 + # via optim-meta (pyproject.toml) numpy==2.4.1 - # via pandas + # via + # optim-meta (pyproject.toml) + # contourpy + # matplotlib + # pandas + # scikit-learn + # scipy +packaging==25.0 + # via matplotlib pandas==2.3.3 # via optim-meta (pyproject.toml) +pillow==12.1.0 + # via matplotlib +pyparsing==3.3.1 + # via matplotlib python-dateutil==2.9.0.post0 - # via pandas + # via + # matplotlib + # pandas pytz==2025.2 # via pandas +scikit-learn==1.8.0 + # via optim-meta (pyproject.toml) +scipy==1.17.0 + # via scikit-learn six==1.17.0 # via python-dateutil +threadpoolctl==3.6.0 + # via scikit-learn tzdata==2025.3 # via pandas