- Created summary.csv to store simulation results for various scenarios, protocols, and metrics. - Developed run.sh script to automate the simulation process, including dependency checks, simulation execution, and result analysis. - Ensured proper directory structure for results and reports. - Added error handling for Python and matplotlib dependencies.
206 lines
6.3 KiB
Python
206 lines
6.3 KiB
Python
"""
|
|
Module principal : Simulation complète des protocoles LEACH et LEACH-C
|
|
"""
|
|
|
|
import random
|
|
import json
|
|
from datetime import datetime
|
|
from node import Node
|
|
from leach import LEACH
|
|
from leach_c import LEACHC
|
|
from config import (
|
|
FIELD_WIDTH, FIELD_HEIGHT, INITIAL_ENERGY, BS_POSITION,
|
|
SCENARIOS, get_num_rounds_for_scenario, DEBUG
|
|
)
|
|
|
|
|
|
class Simulator:
|
|
"""
|
|
Contrôleur principal de la simulation.
|
|
Crée les nœuds, lance les protocoles, et collecte les résultats.
|
|
"""
|
|
|
|
def __init__(self, scenario):
|
|
"""
|
|
Initialise un simulateur pour un scénario donné.
|
|
|
|
Args:
|
|
scenario (dict): Configuration du scénario (l, p, n, name)
|
|
"""
|
|
self.scenario = scenario
|
|
self.packet_size = scenario["l"]
|
|
self.probability_ch = scenario["p"]
|
|
self.num_nodes = scenario["n"]
|
|
self.scenario_name = scenario["name"]
|
|
|
|
self.results = {}
|
|
self.nodes = []
|
|
|
|
def initialize_nodes(self):
|
|
"""Crée et initialise les nœuds."""
|
|
self.nodes = []
|
|
|
|
for i in range(self.num_nodes):
|
|
# Position aléatoire dans le champ
|
|
x = random.uniform(0, FIELD_WIDTH)
|
|
y = random.uniform(0, FIELD_HEIGHT)
|
|
|
|
node = Node(i, x, y, INITIAL_ENERGY)
|
|
self.nodes.append(node)
|
|
|
|
def run_protocol(self, protocol_name, protocol_class):
|
|
"""
|
|
Lance un protocole et collecte les résultats.
|
|
|
|
Args:
|
|
protocol_name (str): "LEACH" ou "LEACH-C"
|
|
protocol_class: Classe du protocole (LEACH ou LEACHC)
|
|
|
|
Returns:
|
|
dict: Métriques et données du protocole
|
|
"""
|
|
# Réinitialiser les nœuds
|
|
for node in self.nodes:
|
|
node.energy = INITIAL_ENERGY
|
|
node.is_alive = True
|
|
node.reset_for_round()
|
|
|
|
# Créer et lancer le protocole
|
|
protocol = protocol_class(self.nodes, self.probability_ch, self.packet_size)
|
|
num_rounds = get_num_rounds_for_scenario(self.num_nodes)
|
|
|
|
print(f" Exécution {protocol_name} pour {self.scenario_name}...")
|
|
print(f" - Packets: {self.packet_size} bits")
|
|
print(f" - Probabilité: {self.probability_ch}")
|
|
print(f" - Nœuds: {self.num_nodes}")
|
|
print(f" - Rounds à exécuter: {num_rounds}")
|
|
|
|
protocol.run_simulation(num_rounds)
|
|
|
|
metrics = protocol.get_metrics(num_rounds)
|
|
detailed = protocol.get_detailed_metrics()
|
|
|
|
print(f" OK - {protocol_name} terminé")
|
|
print(f" - Alive nodes: {metrics['final_alive_nodes']}")
|
|
print(f" - FDN: {metrics['first_dead_node_round']}")
|
|
print(f" - DLBI: {metrics['dlbi']:.4f}")
|
|
print(f" - RSPI: {metrics['rspi']:.4f}")
|
|
|
|
return {
|
|
"protocol": protocol_name,
|
|
"metrics": metrics,
|
|
"detailed": detailed,
|
|
}
|
|
|
|
def run_simulation(self):
|
|
"""
|
|
Lance la simulation complète (LEACH et LEACH-C).
|
|
"""
|
|
print(f"\n{'='*60}")
|
|
print(f"Simulation: {self.scenario_name}")
|
|
print(f"{'='*60}")
|
|
|
|
# Initialiser les nœuds
|
|
self.initialize_nodes()
|
|
|
|
# Lancer LEACH
|
|
leach_results = self.run_protocol("LEACH", LEACH)
|
|
self.results["LEACH"] = leach_results
|
|
|
|
# Lancer LEACH-C
|
|
leachc_results = self.run_protocol("LEACH-C", LEACHC)
|
|
self.results["LEACH-C"] = leachc_results
|
|
|
|
print(f"{'='*60}\n")
|
|
|
|
return self.results
|
|
|
|
def get_results(self):
|
|
"""Retourne les résultats de la simulation."""
|
|
return self.results
|
|
|
|
|
|
def run_all_scenarios():
|
|
"""
|
|
Lance les simulations pour tous les scénarios.
|
|
|
|
Returns:
|
|
dict: Résultats pour tous les scénarios
|
|
"""
|
|
all_results = {}
|
|
|
|
print(f"\n{'#'*60}")
|
|
print(f"# SIMULATION LEACH vs LEACH-C - RÉSEAUX DYNAMIQUES")
|
|
print(f"# Démarrage: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
|
print(f"{'#'*60}\n")
|
|
|
|
for scenario in SCENARIOS:
|
|
print(f"Scénario: {scenario['name']}")
|
|
|
|
simulator = Simulator(scenario)
|
|
results = simulator.run_simulation()
|
|
|
|
all_results[scenario["name"]] = results
|
|
|
|
print(f"\n{'#'*60}")
|
|
print(f"# SIMULATIONS TERMINÉES - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
|
print(f"{'#'*60}\n")
|
|
|
|
return all_results
|
|
|
|
|
|
def save_results(results, output_file):
|
|
"""
|
|
Sauvegarde les résultats en JSON.
|
|
|
|
Args:
|
|
results (dict): Résultats de toutes les simulations
|
|
output_file (str): Chemin du fichier de sortie
|
|
"""
|
|
# Convertir en format sérialisable JSON
|
|
json_results = {}
|
|
|
|
for scenario_name, scenario_data in results.items():
|
|
json_results[scenario_name] = {
|
|
"LEACH": {
|
|
"metrics": scenario_data["LEACH"]["metrics"],
|
|
"detailed_rounds": scenario_data["LEACH"]["detailed"][:20] # Premiers 20 rounds
|
|
},
|
|
"LEACH-C": {
|
|
"metrics": scenario_data["LEACH-C"]["metrics"],
|
|
"detailed_rounds": scenario_data["LEACH-C"]["detailed"][:20]
|
|
}
|
|
}
|
|
|
|
with open(output_file, 'w') as f:
|
|
json.dump(json_results, f, indent=2)
|
|
|
|
print(f"OK - Résultats sauvegardés: {output_file}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# Graine de randomisation pour reproductibilité
|
|
random.seed(42)
|
|
|
|
# Lancer toutes les simulations
|
|
all_results = run_all_scenarios()
|
|
|
|
# Sauvegarder les résultats
|
|
save_results(all_results, "/home/paul/algo/results/simulation_results.json")
|
|
|
|
# Afficher un résumé
|
|
print("\n" + "="*60)
|
|
print("RÉSUMÉ DES RÉSULTATS")
|
|
print("="*60)
|
|
|
|
for scenario_name, scenario_data in all_results.items():
|
|
print(f"\n{scenario_name}:")
|
|
|
|
for protocol in ["LEACH", "LEACH-C"]:
|
|
metrics = scenario_data[protocol]["metrics"]
|
|
print(f"\n {protocol}:")
|
|
print(f" FDN (First Dead Node): {metrics['first_dead_node_round']}")
|
|
print(f" FMR (First Muted Round): {metrics['first_muted_round']}")
|
|
print(f" DLBI: {metrics['dlbi']:.4f}")
|
|
print(f" RSPI: {metrics['rspi']:.4f}")
|