Code/IA/analyze_graph.py
2025-05-19 13:38:30 +02:00

209 lines
7.9 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Script d'analyse de la structure du graphe DOT pour comprendre
comment intégrer l'ISG dans le générateur de template.
"""
import os
from pathlib import Path
from networkx.drawing.nx_agraph import read_dot
# Chemins
BASE_DIR = Path(__file__).resolve().parent
GRAPH_PATH = BASE_DIR / "graphe.dot"
def analyze_graph_structure(dot_path):
"""Analyse la structure du graphe et affiche ses caractéristiques."""
print(f"Analyse du fichier: {dot_path}")
# Lire le graphe
G = read_dot(dot_path)
# Informations de base
print(f"Nombre total de nœuds: {len(G.nodes())}")
print(f"Nombre total d'arêtes: {len(G.edges())}")
# Analyse des attributs des nœuds
node_attrs = {}
for node, attrs in G.nodes(data=True):
for key in attrs:
if key not in node_attrs:
node_attrs[key] = set()
node_attrs[key].add(attrs[key])
print("\nAttributs des nœuds:")
for attr, values in node_attrs.items():
print(f"- {attr}: {len(values)} valeurs différentes")
if len(values) < 20: # Afficher seulement si le nombre de valeurs est raisonnable
print(f" Valeurs: {', '.join(sorted(values))}")
# Analyse des niveaux (si l'attribut existe)
if 'level' in node_attrs:
print("\nAnalyse par niveau:")
levels = {}
for node, attrs in G.nodes(data=True):
if 'level' in attrs:
level = attrs['level']
if level not in levels:
levels[level] = []
levels[level].append(node)
for level, nodes in sorted(levels.items()):
print(f"- Niveau {level}: {len(nodes)} nœuds")
# Afficher quelques exemples
if len(nodes) < 5:
print(f" Exemples: {', '.join(nodes)}")
else:
print(f" Exemples: {', '.join(nodes[:3])}... (et {len(nodes)-3} autres)")
# Analyse des attributs ISG
print("\nRecherche des attributs ISG:")
isg_nodes = []
for node, attrs in G.nodes(data=True):
if 'isg' in attrs:
isg_nodes.append((node, attrs['isg']))
if isg_nodes:
print(f"- {len(isg_nodes)} nœuds avec attribut ISG")
print(" Exemples:")
for node, isg in isg_nodes[:5]:
print(f" - {node}: ISG = {isg}")
else:
print("- Aucun nœud avec attribut ISG trouvé")
# Analyse des connexions pour les nœuds critiques (IHH)
print("\nAnalyse des nœuds avec IHH:")
ihh_nodes = []
for node, attrs in G.nodes(data=True):
if 'ihh_pays' in attrs or 'ihh_acteurs' in attrs:
ihh_value_pays = attrs.get('ihh_pays', 'N/A')
ihh_value_acteurs = attrs.get('ihh_acteurs', 'N/A')
ihh_nodes.append((node, ihh_value_pays, ihh_value_acteurs))
if ihh_nodes:
print(f"- {len(ihh_nodes)} nœuds avec attributs IHH")
print(" Exemples:")
for node, ihh_pays, ihh_acteurs in ihh_nodes[:5]:
print(f" - {node}: IHH pays = {ihh_pays}, IHH acteurs = {ihh_acteurs}")
# Analyser les connexions de ce nœud
print(f" Connexions sortantes:")
out_edges = list(G.out_edges(node))
if out_edges:
for i, (_, target) in enumerate(out_edges[:3]):
print(f" - Vers {target}")
if len(out_edges) > 3:
print(f" - ... et {len(out_edges)-3} autres")
else:
print(" - Aucune connexion sortante")
print(f" Connexions entrantes:")
in_edges = list(G.in_edges(node))
if in_edges:
for i, (source, _) in enumerate(in_edges[:3]):
print(f" - Depuis {source}")
if len(in_edges) > 3:
print(f" - ... et {len(in_edges)-3} autres")
else:
print(" - Aucune connexion entrante")
else:
print("- Aucun nœud avec attributs IHH trouvé")
# Vérifier si un nœud a un attribut de niveau 99 (ISG supposé)
print("\nRecherche des nœuds de niveau 99 (ISG):")
level_99_nodes = []
for node, attrs in G.nodes(data=True):
if attrs.get('level') == '99':
level_99_nodes.append(node)
if level_99_nodes:
print(f"- {len(level_99_nodes)} nœuds de niveau 99")
print(" Exemples:")
for node in level_99_nodes[:5]:
print(f" - {node}")
# Analyser les connexions de ce nœud
print(f" Connexions entrantes:")
in_edges = list(G.in_edges(node))
if in_edges:
for i, (source, _) in enumerate(in_edges[:3]):
print(f" - Depuis {source}")
if len(in_edges) > 3:
print(f" - ... et {len(in_edges)-3} autres")
else:
print(" - Aucune connexion entrante")
else:
print("- Aucun nœud de niveau 99 trouvé")
def check_isg_paths(dot_path):
"""Vérifie les chemins entre les nœuds critiques (IHH) et les nœuds ISG."""
print("\nAnalyse des chemins entre nœuds IHH et nœuds ISG:")
# Lire le graphe
G = read_dot(dot_path)
# Identifier les nœuds avec IHH
ihh_nodes = []
for node, attrs in G.nodes(data=True):
ihh_pays = attrs.get('ihh_pays', 0)
ihh_acteurs = attrs.get('ihh_acteurs', 0)
try:
ihh_pays = float(ihh_pays)
ihh_acteurs = float(ihh_acteurs)
if ihh_pays > 25 or ihh_acteurs > 25: # Seuil critique
ihh_nodes.append(node)
except (ValueError, TypeError):
pass
if not ihh_nodes:
print("- Aucun nœud IHH critique trouvé")
return
print(f"- {len(ihh_nodes)} nœuds IHH critiques identifiés")
# Pour chaque nœud IHH critique, chercher des chemins vers des nœuds ISG
for node in ihh_nodes[:5]: # Limiter à 5 exemples
print(f"\n Analyse des chemins pour {node}:")
# Analyser les voisins directs
successors = list(G.successors(node))
print(f" - {len(successors)} successeurs directs")
if successors:
for succ in successors[:3]:
print(f" - Vers {succ}")
# Vérifier les attributs de ce successeur
succ_attrs = G.nodes[succ]
print(f" Attributs: {', '.join(f'{k}={v}' for k, v in succ_attrs.items() if k in ['level', 'isg'])}")
# Chercher les successeurs de niveau 2
succ2 = list(G.successors(succ))
print(f" {len(succ2)} successeurs de niveau 2")
if succ2:
for s2 in succ2[:2]:
print(f" - Vers {s2}")
s2_attrs = G.nodes[s2]
print(f" Attributs: {', '.join(f'{k}={v}' for k, v in s2_attrs.items() if k in ['level', 'isg'])}")
# Chercher encore plus loin si nécessaire
succ3 = list(G.successors(s2))
print(f" {len(succ3)} successeurs de niveau 3")
if succ3:
for s3 in succ3[:2]:
print(f" - Vers {s3}")
s3_attrs = G.nodes[s3]
print(f" Attributs: {', '.join(f'{k}={v}' for k, v in s3_attrs.items() if k in ['level', 'isg'])}")
def main():
"""Fonction principale."""
print("=== Analyse de la structure du graphe ===")
analyze_graph_structure(GRAPH_PATH)
print("\n=== Analyse des chemins entre nœuds critiques et ISG ===")
check_isg_paths(GRAPH_PATH)
if __name__ == "__main__":
main()