23 KiB
23 KiB
In [ ]:
import networkx as nx
import matplotlib.pyplot as plt
# --- Les personnes -----------------------------------------------------
personnes = [
"Paula", "Ray", "Bonnie", "Jess", "Sam", "Nancy", # malades
"Walter", "Curtis", "Beatrice", "Wendell",
"Doris", "Martha", "George",
"Marjorie", "Harold", "Irene", "Agnes",
]
malades = ["Paula", "Ray", "Bonnie", "Jess", "Sam", "Nancy"]
# --- Les repas ---------------------------------------------------------
repas = ["R1988", "R1989", "R1990", "R1992", "R1995", "M1991"]
# --- Le registre des participations ------------------------------------
# Chaque couple (personne, repas) signifie : cette personne etait a ce repas.
participations = [
("Paula", "R1988"), ("Ray", "R1988"), ("Bonnie", "R1988"),
("Jess", "R1988"), ("Sam", "R1988"), ("Nancy", "R1988"),
("Walter", "R1988"), ("Doris", "R1988"), ("Martha", "R1988"),
("Curtis", "R1988"), ("Wendell", "R1988"),
("Paula", "R1989"), ("Ray", "R1989"), ("Bonnie", "R1989"),
("Jess", "R1989"), ("Walter", "R1989"), ("Curtis", "R1989"),
("Beatrice", "R1989"), ("Wendell", "R1989"),
("Paula", "R1990"), ("Ray", "R1990"), ("Sam", "R1990"),
("Nancy", "R1990"), ("Walter", "R1990"), ("Curtis", "R1990"),
("Wendell", "R1990"), ("George", "R1990"),
("Ray", "R1992"), ("Bonnie", "R1992"), ("Jess", "R1992"),
("Sam", "R1992"), ("Nancy", "R1992"), ("Beatrice", "R1992"),
("Wendell", "R1992"),
("Walter", "R1995"), ("Curtis", "R1995"),
("Beatrice", "R1995"), ("Wendell", "R1995"),
("Marjorie", "M1991"), ("Harold", "M1991"), ("Irene", "M1991"),
]
print("Nombre de personnes :", len(personnes))
print("Nombre de repas :", len(repas))
print("Nombre de participations :", len(participations))In [ ]:
B = nx.Graph()
# On declare les deux "cotes" du reseau
B.add_nodes_from(personnes, bipartite=0) # cote personnes
B.add_nodes_from(repas, bipartite=1) # cote repas
# Puis les liens de participation
B.add_edges_from(participations)
print("Le graphe est-il biparti ?", nx.is_bipartite(B))
print("Nombre total de noeuds :", B.number_of_nodes())
print("Nombre de liens :", B.number_of_edges())In [ ]:
# Positions : personnes a gauche, repas a droite
pos = {}
for i, p in enumerate(personnes):
pos[p] = (0, -i)
for j, r in enumerate(repas):
pos[r] = (2, -j * (len(personnes) - 1) / (len(repas) - 1))
plt.figure(figsize=(9, 8))
nx.draw_networkx_edges(B, pos, alpha=0.35)
nx.draw_networkx_nodes(B, pos, nodelist=personnes,
node_color="lightblue", node_size=900)
nx.draw_networkx_nodes(B, pos, nodelist=repas,
node_color="lightsalmon", node_shape="s", node_size=1200)
nx.draw_networkx_labels(B, pos, font_size=9)
plt.title("Reseau d'affiliation : personnes (bleu) x repas (orange)")
plt.axis("off")
plt.show()In [ ]:
from networkx.algorithms import bipartite
# --- CELLULE FOURNIE ---------------------------------------------------
# projected_graph(B, noeuds) construit un nouveau graphe dont les noeuds sont
# ceux passes en second argument, et ou deux noeuds sont relies s'ils avaient
# au moins un voisin commun dans le graphe biparti B.
# Ici : deux personnes sont reliees si elles ont partage au moins un repas.
G = bipartite.projected_graph(B, personnes)
# -----------------------------------------------------------------------
print("Reseau des personnes")
print(" noeuds :", G.number_of_nodes())
print(" liens :", G.number_of_edges())In [ ]:
couleurs = ["lightcoral" if p in malades else "lightblue" for p in G.nodes()]
plt.figure(figsize=(9, 7))
pos_g = nx.spring_layout(G, seed=4)
nx.draw(G, pos_g, with_labels=True, node_color=couleurs,
node_size=1100, font_size=9, edge_color="gray")
plt.title("Reseau unimode : 'a partage au moins un repas avec'\n(rouge = malade)")
plt.show()In [ ]:
composantes = list(nx.connected_components(G))
print("Nombre de composantes connexes :", len(composantes))
print()
for i, comp in enumerate(sorted(composantes, key=len, reverse=True), start=1):
nb_malades = len(set(comp) & set(malades))
print(f"Composante {i} ({len(comp)} personnes, {nb_malades} malade(s)) :")
print(" ", sorted(comp))
print()In [ ]:
cas_index = "Paula"
distances = nx.single_source_shortest_path_length(B, cas_index)
print(f"Distances depuis le cas index ({cas_index}) dans le reseau d'affiliation")
print()
for d in sorted(set(distances.values())):
noms = sorted(n for n, dist in distances.items() if dist == d)
print(f" distance {d} : {noms}")
print()
non_atteints = sorted(set(B.nodes()) - set(distances))
print("Noeuds non atteints :", non_atteints if non_atteints else "aucun")In [ ]:
# Meme chose sur le reseau unimode, pour comparaison
dist_uni = nx.single_source_shortest_path_length(G, cas_index)
print(f"Distances depuis {cas_index} dans le reseau unimode")
print()
for personne in sorted(dist_uni, key=lambda p: (dist_uni[p], p)):
marque = " (malade)" if personne in malades else ""
print(f" {personne:<10} : {dist_uni[personne]}{marque}")