148 lines
5.8 KiB
Python
148 lines
5.8 KiB
Python
"""
|
|
|
|
Version 1.0
|
|
Date 27/03/2025
|
|
Auteur : Stéphan Peccini
|
|
|
|
Ce script met à jour les valeurs ihh en fonction des données
|
|
de part de marché des pays où des acteurs.
|
|
https://fr.wikipedia.org/wiki/Indice_de_Herfindahl-Hirschmann
|
|
|
|
Important :
|
|
-----------------------
|
|
Pour faciliter le travail, tout est fait avec un graphe NetworkX et ensuite sauvé
|
|
au format DOT sans aucune structure hiérarchique.
|
|
Il suffit alors de passer le fichier résultat dans beautify.py pour avoir un fichier
|
|
DOT conforme aux attentes.
|
|
|
|
"""
|
|
|
|
import networkx as nx
|
|
from networkx.drawing.nx_pydot import write_dot
|
|
import sys
|
|
import re
|
|
|
|
def calcul_ihh(graphe, depart, arrivee):
|
|
ihh = 0
|
|
print("Appel à calcul_ihh")
|
|
for noeud in arrivee:
|
|
print(f"nœud : {noeud}")
|
|
print(depart)
|
|
print(arrivee)
|
|
if depart in noeud: # Gestion simplifiée de l'intégration des Connexes
|
|
print("Départ dans le nœud")
|
|
if arrivee not in list(graphe.successors(depart)):
|
|
depart_2 = list(graphe.predecessors(noeud))[0]
|
|
relation = graphe.get_edge_data(depart_2, noeud)
|
|
else:
|
|
relation = graphe.get_edge_data(depart, noeud)
|
|
print(relation)
|
|
print(relation['label'])
|
|
ihh_inter = int(int(relation['label'].strip("%"))**2)
|
|
print(ihh_inter)
|
|
ihh += ihh_inter
|
|
print(ihh)
|
|
ihh = int(round(ihh/100))
|
|
return ihh
|
|
|
|
def mettre_a_jour_ihh(graph, noeuds):
|
|
for noeud in noeuds:
|
|
sous_graphe = nx.DiGraph()
|
|
try:
|
|
for chemin in nx.edge_bfs(graph, source=noeud):
|
|
sous_graphe.add_edge(*chemin)
|
|
|
|
# Ajouter les attributs des nœuds
|
|
for node in sous_graphe.nodes():
|
|
if node in graph.nodes():
|
|
sous_graphe.nodes[node].update(graph.nodes[node])
|
|
|
|
# Ajouter les attributs des arêtes
|
|
for edge in sous_graphe.edges():
|
|
if edge in graph.edges():
|
|
sous_graphe.edges[edge].update(graph.edges[edge])
|
|
|
|
niveaux_ihh = nx.get_node_attributes(sous_graphe, "niveau")
|
|
operation = noeud.split('_')[0]
|
|
|
|
# La hiérarchie Traitement est particulière. En effet, les acteurs du traitement se fournissent
|
|
# auprès des acteurs de l'extraction. Il y a une relations entre chaque acteur de traitement
|
|
# et les pays auprès desquels il se fournit en minerai.
|
|
if "Traitement" in operation:
|
|
noeuds_pays_ihh = [n for n, v in niveaux_ihh.items() if (v == "11" or v == "1011") and operation in n]
|
|
noeuds_acteurs_ihh = [n for n, v in niveaux_ihh.items() if (v == "12" or v == "1012") and operation in list(sous_graphe.predecessors(n))[0]]
|
|
|
|
else:
|
|
noeuds_pays_ihh = [n for n, v in niveaux_ihh.items() if (v == "11" or v == "1011")]
|
|
noeuds_acteurs_ihh = [n for n, v in niveaux_ihh.items() if (v == "12" or v == "1012")]
|
|
|
|
# Le calcul de l'indice de Herfindahl-Hirschmann se fait normalement au niveau d'une entreprise.
|
|
# Toutefois, il se fait au niveau des pays et au niveau des acteurs pour l'opération qui est menée.
|
|
ihh_pays = calcul_ihh(sous_graphe, noeud, noeuds_pays_ihh)
|
|
nx.set_node_attributes(graph, {noeud: {"ihh_pays": f"{ihh_pays}"}})
|
|
ihh_acteurs = calcul_ihh(sous_graphe, noeud, noeuds_acteurs_ihh)
|
|
nx.set_node_attributes(graph, {noeud: {"ihh_acteurs": f"{ihh_acteurs}"}})
|
|
|
|
except nx.NetworkXNoPath:
|
|
pass # Ignore les chemins inexistants
|
|
|
|
return graph
|
|
|
|
def mettre_a_jour_ihh_reserves(graph, noeuds):
|
|
for noeud in noeuds:
|
|
sous_graphe = nx.DiGraph()
|
|
try:
|
|
for chemin in nx.edge_bfs(graph, source=noeud):
|
|
sous_graphe.add_edge(*chemin)
|
|
|
|
# Ajouter les attributs des nœuds
|
|
for node in sous_graphe.nodes():
|
|
if node in graph.nodes():
|
|
sous_graphe.nodes[node].update(graph.nodes[node])
|
|
|
|
# Ajouter les attributs des arêtes
|
|
for edge in sous_graphe.edges():
|
|
if edge in graph.edges():
|
|
sous_graphe.edges[edge].update(graph.edges[edge])
|
|
|
|
niveaux_ihh = nx.get_node_attributes(sous_graphe, "niveau")
|
|
|
|
noeuds_pays_ihh = [n for n, v in niveaux_ihh.items() if (v == "11" or v == "1011")]
|
|
|
|
# Le calcul de l'indice de Herfindahl-Hirschmann se fait normalement au niveau d'une entreprise.
|
|
# Toutefois, il se fait au niveau des pays et au niveau des acteurs pour l'opération qui est menée.
|
|
ihh_pays = calcul_ihh(sous_graphe, noeud, noeuds_pays_ihh)
|
|
nx.set_node_attributes(graph, {noeud: {"ihh_pays": f"{ihh_pays}"}})
|
|
|
|
except nx.NetworkXNoPath:
|
|
pass # Ignore les chemins inexistants
|
|
|
|
return graph
|
|
|
|
def main():
|
|
""" Fonction principale pour interagir avec l'utilisateur. """
|
|
if len(sys.argv) != 3:
|
|
print("Usage: python ihh.py fichier_en_entree.dot fichier_en_sortie.dot")
|
|
return
|
|
|
|
fichier_en_entree = sys.argv[1]
|
|
fichier_en_sortie = sys.argv[2]
|
|
|
|
graph = nx.DiGraph(nx.nx_agraph.read_dot(fichier_en_entree))
|
|
niveaux = nx.get_node_attributes(graph, "niveau")
|
|
|
|
noeuds_niveau_10 = [n for n, v in niveaux.items() if (v == "10" or v == "1010") and not re.search(r'Reserves', n)]
|
|
noeuds_niveau_10.sort()
|
|
|
|
graphe = mettre_a_jour_ihh(graph, noeuds_niveau_10)
|
|
|
|
noeuds_niveau_10 = [n for n, v in niveaux.items() if (v == "10" or v == "1010") and re.search(r'Reserves', n)]
|
|
noeuds_niveau_10.sort()
|
|
|
|
graphe = mettre_a_jour_ihh_reserves(graphe, noeuds_niveau_10)
|
|
|
|
write_dot(graphe, fichier_en_sortie)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|