Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1#!/usr/bin/env python3
2from matplotlib import pyplot as plt
3import networkx as nx
4import numpy
5from numpy import zeros
6import copy
7# pour copier le dictionnaire de données afin de le modifier sans modifier le
8# dictionnaire initial
10import json
12def lire_entree_json() -> dict:
13 """
14 Cette fonction lit un fichier json en entrée et renvoie le dictionnaire
15 associé.
17 La fonction ne prends pas d'argument en entrée et renvoie un dictionnaire
18 """
19 with open('data_exemple.json', 'r') as fichier:
20 donnees = fichier.read()
22 exemple_graphe = json.loads(donnees)
23 return exemple_graphe
26def associer_eleves_numeros(dictionnaire: dict) -> dict:
27 """
28 Cette fonction prend en entrée un dictionnaire et renvoie un dictionnaire
29 associant les élèves à un numero d'ordre.
31 Cette fonction permet de «numéroter» les élèves pour un accès plus facile.
32 La fonction repose fondamentalement sur une propriété de Python 3.7 : les
33 dictionnaires sont désormais ordonnés par défaut.
34 """
35 dict_eleves_numero = {}
36 for k1,v1 in enumerate(dictionnaire):
37 dict_eleves_numero[v1] = k1
38 return dict_eleves_numero
41def graphe_numerique(dictionnaire: dict,dict_eleves_numero: dict) -> dict:
42 """
43 Cette fonction prend en entrée un dictionnaire (le graphe) et renvoie un
44 dictionnaire (le graphe) purement numérique.
46 La fonction permet de réécrire le dictionnaire suivant le modèle adopté par
47 le reste des fonctions du projet.
48 >>> graphe_numerique({'Alice': {'Bob': 1, 'Eve': 2}}, {'Alice':0, 'Bob': 2, 'Eve':1})
49 {0: {2: 1, 1: 2}}
50 """
51 dict_amis_numeros = dict((dict_eleves_numero[key], value) for (key, value) in dictionnaire.items())
52 for v in dict_amis_numeros.items():
53 dict_amis_numeros[v[0]] = dict((dict_eleves_numero[key], value) for (key, value) in v[1].items())
54 return dict_amis_numeros
57def cree_dict_classe_liste(dictionnaire: dict) -> dict:
58 """
59 Transforme un dictionnaire de dictionnaire en dictonnaire de liste (où les
60 clefs sont les indices dans la liste)
62 - Precondition dictionnaire est du type dict_amis_numeros:
63 {0: {20: 2, 15: 1}, 1: {18: 2, 13: 1}, 2: {17: 2, 7: 1} etc...}
64 - Post condition : Cette fonction cree un dictionnaire ou les cles sont les
65 numeros des eleves et les valeurs des listes de leurs amis
66 Exemple : {0: [20, 15], 1: [18, 13], 2: [17, 7],etc...}
67 >>> cree_dict_classe_liste({0: {20: 2, 15: 1}, 1: {18: 2, 13: 1}, 2: {17: 2, 7: 1}})
68 {0: [20, 15], 1: [18, 13], 2: [17, 7]}
69 """
70 dictionnaire_liste={}
71 for sommet in dictionnaire:
72 dictionnaire_liste[sommet]=list(dictionnaire[sommet].keys())
73 return dictionnaire_liste
75def cree_graphe_nx(dictionnaire: dict) -> nx.DiGraph:
76 """
77 Cette fonction premet de transformer une représentation en dictionnaire en
78 une représentation «complexe» d'un objet graphe orienté.
80 - Précondition : l'entrée est un dictionnaire
81 - Postcondition : la sortie est un graphe de Networkx
82 """
83 G = nx.DiGraph() # au lieu de G=nx.Graph()
84 for sommets in dictionnaire.keys():
85 G.add_node(sommets)
86 for sommet in dictionnaire:
87 for sommets_adjacents in dictionnaire[sommet]:
88 G.add_edge(sommet, sommets_adjacents)
89 return G
92def afficher_graphe(dictionnaire,fichier):
93 """
94 Cette fonction permet de créer un fichier png correspondant au graphe passé
95 en argument.
97 Prends un dictionnaire en entrée, représentant un graphe et affiche un
98 graphe.
99 Son code de retour est None
100 """
101 G = cree_graphe_nx(dictionnaire)
102 plt.clf()
103 #pos = nx.spring_layout(G)
104 #nx.draw_networkx_nodes(G, pos, node_color='b', node_size=60)
105 #nx.draw_networkx_edges(G, pos, width=1.0, alpha=0.5)
106 #nx.draw_networkx_labels(G, pos, font_size=10)
107 #plt.axis('off')
108 nx.draw_circular(G,with_labels=True) # Cela me semble mieux
109 plt.show()
110 plt.savefig(fichier)
111 return None
115def chemin_long_3(dictionnaire: dict, start: int) -> list:
116 """
117 Cette fonction retourne une liste de toutes les listes de chemins de
118 longueur 3 partant du sommet start
120 Precondition : dictionnaire est du type : {0: [20, 15], 1: [18, 13],etc}
121 Ce dictionnaire est cree par la fonction cree_dict_classe_liste(dict_amis_numeros)
122 Postcondition : retourne une liste de listes de chemins
123 Par exemple : pour le sommet 0 et le dictionnaire complet, on obtient:
124 [[0, 20, 25, 18], [0, 20, 25, 20], [0, 20, 18, 25], [0, 20, 18, 23], [0, 15, 19, 5], [0, 15, 19, 14], [0, 15, 5, 19], [0, 15, 5, 14]]
125 Test :
126 >>> chemin_long_3({0: [20, 15], 1: [18, 13], 2: [17, 7], 3: [24, 7], \
127 4: [18, 11], 5: [19, 14], 6: [4, 13], 7: [24, 3], 8: [26, 23], 9: [25, 20], \
128 10: [22, 23], 11: [13, 22], 12: [4, 13], 13: [16, 12], 14: [17, 4], \
129 15: [19, 5], 16: [18, 13], 17: [4, 15], 18: [25, 23], 19: [5, 14], \
130 20: [25, 18], 21: [25, 18], 22: [13, 23], 23: [8, 18], 24: [3, 7], \
131 25: [18, 20], 26: [13, 23]}, 0)
132 [[0, 20, 25, 18], [0, 20, 25, 20], [0, 20, 18, 25], [0, 20, 18, 23], [0, 15, 19, 5], [0, 15, 19, 14], [0, 15, 5, 19], [0, 15, 5, 14]]
133 """
134 liste=[[] for i in range(8)]
135 # 1 sommet des chemins
136 for i in range(8):
137 liste[i].append(start)
138 # 2 sommets des chemins
139 for i in range(4):
140 liste[i].append(dictionnaire[liste[i][-1]][0])
141 for i in range(4,8):
142 liste[i].append(dictionnaire[liste[i][-1]][1])
143 # 3 sommets des chemins
144 i=0
145 j=0
146 liste[i].append(dictionnaire[liste[i][-1]][j])
147 i=1
148 j=0
149 liste[i].append(dictionnaire[liste[i][-1]][j])
150 while i<6:
151 i=i+1
152 j=(j+1)%2
153 liste[i].append(dictionnaire[liste[i][-1]][j])
154 i=i+1
155 liste[i].append(dictionnaire[liste[i][-1]][j])
156 # 4 sommets des chemins
157 for i in range(8):
158 j=i%2
159 liste[i].append(dictionnaire[liste[i][-1]][j])
160 return liste
163def tous_les_chemins_long_3(dictionnaire: dict) -> list:
164 """
165 Afficher tous les chemins de longueur 3, indépendament de leur point de
166 départ
168 - Precondition : dictionnaire est du type : {0: [20, 15], 1: [18, 13],etc}
169 Ce dictionnaire est cree par la fonction cree_dict_classe_liste(dict_amis_numeros)
170 - Postcondition : Exemple de liste retournée :
171 [[[0, 20, 25, 18], [0, 20, 25, 20], [0, 20, 18, 25], [0, 20, 18, 23], [0, 15, 19, 5], [0, 15, 19, 14], [0, 15, 5, 19], [0, 15, 5, 20]],
172 [[1, 18, 25, 18], [1, 18, 25, 20], [1, 18, 23, 8], etc...
173 >>> tous_les_chemins_long_3({0: [20, 15], 1: [18, 13], 2: [17, 7], 3: [24, 7], \
174 4: [18, 11], 5: [19, 14], 6: [4, 13], 7: [24, 3], 8: [26, 23], 9: [25, 20], \
175 10: [22, 23], 11: [13, 22], 12: [4, 13], 13: [16, 12], 14: [17, 4], \
176 15: [19, 5], 16: [18, 13], 17: [4, 15], 18: [25, 23], 19: [5, 14], \
177 20: [25, 18], 21: [25, 18], 22: [13, 23], 23: [8, 18], 24: [3, 7], \
178 25: [18, 20], 26: [13, 23]})
179 [[[0, 20, 25, 18], [0, 20, 25, 20], [0, 20, 18, 25], [0, 20, 18, 23], [0, 15, 19, 5], [0, 15, 19, 14], [0, 15, 5, 19], [0, 15, 5, 14]], [[1, 18, 25, 18], [1, 18, 25, 20], [1, 18, 23, 8], [1, 18, 23, 18], [1, 13, 16, 18], [1, 13, 16, 13], [1, 13, 12, 4], [1, 13, 12, 13]], [[2, 17, 4, 18], [2, 17, 4, 11], [2, 17, 15, 19], [2, 17, 15, 5], [2, 7, 24, 3], [2, 7, 24, 7], [2, 7, 3, 24], [2, 7, 3, 7]], [[3, 24, 3, 24], [3, 24, 3, 7], [3, 24, 7, 24], [3, 24, 7, 3], [3, 7, 24, 3], [3, 7, 24, 7], [3, 7, 3, 24], [3, 7, 3, 7]], [[4, 18, 25, 18], [4, 18, 25, 20], [4, 18, 23, 8], [4, 18, 23, 18], [4, 11, 13, 16], [4, 11, 13, 12], [4, 11, 22, 13], [4, 11, 22, 23]], [[5, 19, 5, 19], [5, 19, 5, 14], [5, 19, 14, 17], [5, 19, 14, 4], [5, 14, 17, 4], [5, 14, 17, 15], [5, 14, 4, 18], [5, 14, 4, 11]], [[6, 4, 18, 25], [6, 4, 18, 23], [6, 4, 11, 13], [6, 4, 11, 22], [6, 13, 16, 18], [6, 13, 16, 13], [6, 13, 12, 4], [6, 13, 12, 13]], [[7, 24, 3, 24], [7, 24, 3, 7], [7, 24, 7, 24], [7, 24, 7, 3], [7, 3, 24, 3], [7, 3, 24, 7], [7, 3, 7, 24], [7, 3, 7, 3]], [[8, 26, 13, 16], [8, 26, 13, 12], [8, 26, 23, 8], [8, 26, 23, 18], [8, 23, 8, 26], [8, 23, 8, 23], [8, 23, 18, 25], [8, 23, 18, 23]], [[9, 25, 18, 25], [9, 25, 18, 23], [9, 25, 20, 25], [9, 25, 20, 18], [9, 20, 25, 18], [9, 20, 25, 20], [9, 20, 18, 25], [9, 20, 18, 23]], [[10, 22, 13, 16], [10, 22, 13, 12], [10, 22, 23, 8], [10, 22, 23, 18], [10, 23, 8, 26], [10, 23, 8, 23], [10, 23, 18, 25], [10, 23, 18, 23]], [[11, 13, 16, 18], [11, 13, 16, 13], [11, 13, 12, 4], [11, 13, 12, 13], [11, 22, 13, 16], [11, 22, 13, 12], [11, 22, 23, 8], [11, 22, 23, 18]], [[12, 4, 18, 25], [12, 4, 18, 23], [12, 4, 11, 13], [12, 4, 11, 22], [12, 13, 16, 18], [12, 13, 16, 13], [12, 13, 12, 4], [12, 13, 12, 13]], [[13, 16, 18, 25], [13, 16, 18, 23], [13, 16, 13, 16], [13, 16, 13, 12], [13, 12, 4, 18], [13, 12, 4, 11], [13, 12, 13, 16], [13, 12, 13, 12]], [[14, 17, 4, 18], [14, 17, 4, 11], [14, 17, 15, 19], [14, 17, 15, 5], [14, 4, 18, 25], [14, 4, 18, 23], [14, 4, 11, 13], [14, 4, 11, 22]], [[15, 19, 5, 19], [15, 19, 5, 14], [15, 19, 14, 17], [15, 19, 14, 4], [15, 5, 19, 5], [15, 5, 19, 14], [15, 5, 14, 17], [15, 5, 14, 4]], [[16, 18, 25, 18], [16, 18, 25, 20], [16, 18, 23, 8], [16, 18, 23, 18], [16, 13, 16, 18], [16, 13, 16, 13], [16, 13, 12, 4], [16, 13, 12, 13]], [[17, 4, 18, 25], [17, 4, 18, 23], [17, 4, 11, 13], [17, 4, 11, 22], [17, 15, 19, 5], [17, 15, 19, 14], [17, 15, 5, 19], [17, 15, 5, 14]], [[18, 25, 18, 25], [18, 25, 18, 23], [18, 25, 20, 25], [18, 25, 20, 18], [18, 23, 8, 26], [18, 23, 8, 23], [18, 23, 18, 25], [18, 23, 18, 23]], [[19, 5, 19, 5], [19, 5, 19, 14], [19, 5, 14, 17], [19, 5, 14, 4], [19, 14, 17, 4], [19, 14, 17, 15], [19, 14, 4, 18], [19, 14, 4, 11]], [[20, 25, 18, 25], [20, 25, 18, 23], [20, 25, 20, 25], [20, 25, 20, 18], [20, 18, 25, 18], [20, 18, 25, 20], [20, 18, 23, 8], [20, 18, 23, 18]], [[21, 25, 18, 25], [21, 25, 18, 23], [21, 25, 20, 25], [21, 25, 20, 18], [21, 18, 25, 18], [21, 18, 25, 20], [21, 18, 23, 8], [21, 18, 23, 18]], [[22, 13, 16, 18], [22, 13, 16, 13], [22, 13, 12, 4], [22, 13, 12, 13], [22, 23, 8, 26], [22, 23, 8, 23], [22, 23, 18, 25], [22, 23, 18, 23]], [[23, 8, 26, 13], [23, 8, 26, 23], [23, 8, 23, 8], [23, 8, 23, 18], [23, 18, 25, 18], [23, 18, 25, 20], [23, 18, 23, 8], [23, 18, 23, 18]], [[24, 3, 24, 3], [24, 3, 24, 7], [24, 3, 7, 24], [24, 3, 7, 3], [24, 7, 24, 3], [24, 7, 24, 7], [24, 7, 3, 24], [24, 7, 3, 7]], [[25, 18, 25, 18], [25, 18, 25, 20], [25, 18, 23, 8], [25, 18, 23, 18], [25, 20, 25, 18], [25, 20, 25, 20], [25, 20, 18, 25], [25, 20, 18, 23]], [[26, 13, 16, 18], [26, 13, 16, 13], [26, 13, 12, 4], [26, 13, 12, 13], [26, 23, 8, 26], [26, 23, 8, 23], [26, 23, 18, 25], [26, 23, 18, 23]]]
180 """
181 liste=[]
182 for sommet in dictionnaire:
183 liste.append(chemin_long_3(dictionnaire, sommet))
184 return liste
187def dedoublonner(liste: list) -> list:
188 """
189 Une fonction pour retirer les éventuels doublons, l'ordre ne comptant pas.
191 Precondition : une liste de liste, contenant éventuellement des doublons
192 Postcondition : une liste de liste, sans doublon
193 La fonction permet de retirer les doublons d'une liste
194 >>> dedoublonner([[1,2],[2,1]])
195 [{1, 2}]
196 """
197 retval = []
198 for elem in liste:
199 if set(elem) not in [set(s) for s in retval]:
200 retval.append(set(elem))
201 return retval
204def cycles_longueur_3(liste_chemins: list) -> list:
205 """
206 Retourne les chemins qui sont des cycles
208 - Pre-condition : liste_chemin est du type retourne par la fonction tous_les_chemins_long_3(dictionnaire)
209 - Post-condition : retourne la liste de tous les chemins de longueur 3
210 qui sont des cycles.
211 >>> cycles_longueur_3([[[0, 20, 25, 18], [0, 20, 25, 20], [0, 20, 18, 25], [0, 20, 18, 23], [0, 15, 19, 5], [0, 15, 19, 14], [0, 15, 5, 19], [0, 15, 5, 14]], [[1, 18, 25, 18], [1, 18, 25, 20], [1, 18, 23, 8], [1, 18, 23, 18], [1, 13, 16, 18], [1, 13, 16, 13], [1, 13, 12, 4], [1, 13, 12, 13]], [[2, 17, 4, 18], [2, 17, 4, 11], [2, 17, 15, 19], [2, 17, 15, 5], [2, 7, 24, 3], [2, 7, 24, 7], [2, 7, 3, 24], [2, 7, 3, 7]], [[3, 24, 3, 24], [3, 24, 3, 7], [3, 24, 7, 24], [3, 24, 7, 3], [3, 7, 24, 3], [3, 7, 24, 7], [3, 7, 3, 24], [3, 7, 3, 7]], [[4, 18, 25, 18], [4, 18, 25, 20], [4, 18, 23, 8], [4, 18, 23, 18], [4, 11, 13, 16], [4, 11, 13, 12], [4, 11, 22, 13], [4, 11, 22, 23]], [[5, 19, 5, 19], [5, 19, 5, 14], [5, 19, 14, 17], [5, 19, 14, 4], [5, 14, 17, 4], [5, 14, 17, 15], [5, 14, 4, 18], [5, 14, 4, 11]], [[6, 4, 18, 25], [6, 4, 18, 23], [6, 4, 11, 13], [6, 4, 11, 22], [6, 13, 16, 18], [6, 13, 16, 13], [6, 13, 12, 4], [6, 13, 12, 13]], [[7, 24, 3, 24], [7, 24, 3, 7], [7, 24, 7, 24], [7, 24, 7, 3], [7, 3, 24, 3], [7, 3, 24, 7], [7, 3, 7, 24], [7, 3, 7, 3]], [[8, 26, 13, 16], [8, 26, 13, 12], [8, 26, 23, 8], [8, 26, 23, 18], [8, 23, 8, 26], [8, 23, 8, 23], [8, 23, 18, 25], [8, 23, 18, 23]], [[9, 25, 18, 25], [9, 25, 18, 23], [9, 25, 20, 25], [9, 25, 20, 18], [9, 20, 25, 18], [9, 20, 25, 20], [9, 20, 18, 25], [9, 20, 18, 23]], [[10, 22, 13, 16], [10, 22, 13, 12], [10, 22, 23, 8], [10, 22, 23, 18], [10, 23, 8, 26], [10, 23, 8, 23], [10, 23, 18, 25], [10, 23, 18, 23]], [[11, 13, 16, 18], [11, 13, 16, 13], [11, 13, 12, 4], [11, 13, 12, 13], [11, 22, 13, 16], [11, 22, 13, 12], [11, 22, 23, 8], [11, 22, 23, 18]], [[12, 4, 18, 25], [12, 4, 18, 23], [12, 4, 11, 13], [12, 4, 11, 22], [12, 13, 16, 18], [12, 13, 16, 13], [12, 13, 12, 4], [12, 13, 12, 13]], [[13, 16, 18, 25], [13, 16, 18, 23], [13, 16, 13, 16], [13, 16, 13, 12], [13, 12, 4, 18], [13, 12, 4, 11], [13, 12, 13, 16], [13, 12, 13, 12]], [[14, 17, 4, 18], [14, 17, 4, 11], [14, 17, 15, 19], [14, 17, 15, 5], [14, 4, 18, 25], [14, 4, 18, 23], [14, 4, 11, 13], [14, 4, 11, 22]], [[15, 19, 5, 19], [15, 19, 5, 14], [15, 19, 14, 17], [15, 19, 14, 4], [15, 5, 19, 5], [15, 5, 19, 14], [15, 5, 14, 17], [15, 5, 14, 4]], [[16, 18, 25, 18], [16, 18, 25, 20], [16, 18, 23, 8], [16, 18, 23, 18], [16, 13, 16, 18], [16, 13, 16, 13], [16, 13, 12, 4], [16, 13, 12, 13]], [[17, 4, 18, 25], [17, 4, 18, 23], [17, 4, 11, 13], [17, 4, 11, 22], [17, 15, 19, 5], [17, 15, 19, 14], [17, 15, 5, 19], [17, 15, 5, 14]], [[18, 25, 18, 25], [18, 25, 18, 23], [18, 25, 20, 25], [18, 25, 20, 18], [18, 23, 8, 26], [18, 23, 8, 23], [18, 23, 18, 25], [18, 23, 18, 23]], [[19, 5, 19, 5], [19, 5, 19, 14], [19, 5, 14, 17], [19, 5, 14, 4], [19, 14, 17, 4], [19, 14, 17, 15], [19, 14, 4, 18], [19, 14, 4, 11]], [[20, 25, 18, 25], [20, 25, 18, 23], [20, 25, 20, 25], [20, 25, 20, 18], [20, 18, 25, 18], [20, 18, 25, 20], [20, 18, 23, 8], [20, 18, 23, 18]], [[21, 25, 18, 25], [21, 25, 18, 23], [21, 25, 20, 25], [21, 25, 20, 18], [21, 18, 25, 18], [21, 18, 25, 20], [21, 18, 23, 8], [21, 18, 23, 18]], [[22, 13, 16, 18], [22, 13, 16, 13], [22, 13, 12, 4], [22, 13, 12, 13], [22, 23, 8, 26], [22, 23, 8, 23], [22, 23, 18, 25], [22, 23, 18, 23]], [[23, 8, 26, 13], [23, 8, 26, 23], [23, 8, 23, 8], [23, 8, 23, 18], [23, 18, 25, 18], [23, 18, 25, 20], [23, 18, 23, 8], [23, 18, 23, 18]], [[24, 3, 24, 3], [24, 3, 24, 7], [24, 3, 7, 24], [24, 3, 7, 3], [24, 7, 24, 3], [24, 7, 24, 7], [24, 7, 3, 24], [24, 7, 3, 7]], [[25, 18, 25, 18], [25, 18, 25, 20], [25, 18, 23, 8], [25, 18, 23, 18], [25, 20, 25, 18], [25, 20, 25, 20], [25, 20, 18, 25], [25, 20, 18, 23]], [[26, 13, 16, 18], [26, 13, 16, 13], [26, 13, 12, 4], [26, 13, 12, 13], [26, 23, 8, 26], [26, 23, 8, 23], [26, 23, 18, 25], [26, 23, 18, 23]]])
212 [{24, 3, 7}, {8, 26, 23}, {25, 18, 20}]
213 """
214 liste_cycles=[]
215 for liste in liste_chemins:
216 for chemin in liste:
217 if chemin[0]==chemin[3]:
218 liste_cycles.append(chemin)
219 return dedoublonner(liste_cycles)
222def trinomes_parfaits(liste_cycles: list) -> list:
223 """
224 Retourne la listes des set de groupes de 3 (cycles du graphe initial)
226 Pre-condition : liste_cycles est retournée par cycles_longueur_3(liste_chemins)
227 Post-condition : retourne une liste d ensembles
228 >>> trinomes_parfaits([{24, 3, 7}, {8, 26, 23}, {25, 18, 20}])
229 [{24, 3, 7}, {8, 26, 23}, {25, 18, 20}]
230 """
231 grou_3=[]
232 for chemin in liste_cycles:
233 set_chemin=set(chemin)
234 grou_3.append(set_chemin)
235 #Suppression des doublons :
236 groupes_3=[]
237 for element in grou_3:
238 if element not in groupes_3:
239 groupes_3.append(element)
240 return groupes_3
243def dict_reduit(dictionnaire: dict, trios: list) -> dict:
244 """
245 Affiche le dictionnaire initial, réduit des trios composés
247 - Pre-condition : dictionnaire est retourne par la fonction
248 def cree_dict_classe_liste(dict_amis_numeros)
249 trios est retourne par la fonction
250 def trinomes_parfaits(cycles_longueur_3(liste_chemins))
251 - Post-condition : Retourne un dictionnaire ou les sommets et aretes faisant
252 intervenir un eleve d un trio sont supprimes.
253 Par exemple (dans notre cas) :
254 {0: [15], 1: [13], 2: [17], 4: [11], 5: [19, 14], 6: [4, 13],
255 9: [20], 10: [22], 11: [13, 22], 12: [4, 13], 13: [16, 12], 14: [17, 4],
256 15: [19, 5], 16: [13], 17: [4, 15], 19: [5, 14], 21: [18], 22: [13]}
257 >>> dict_reduit(cree_dict_classe_liste(dict_amis_numeros), [{24, 3, 7}, {8, 26, 23}, {25, 18, 20}])
258 {0: [11, 9], 1: [2, 4], 2: [1, 6], 4: [1, 22], 5: [25], 6: [22, 13], 9: [10], 10: [9], 11: [12, 6], 12: [11, 6], 13: [14, 1], 14: [1], 15: [22], 16: [22], 17: [12, 15], 19: [1], 21: [19], 22: [20]}
259 """
260 sommets_trios=set()
261 for groupe in trios:
262 for element in groupe:
263 sommets_trios.add(element)
264 dictionnaire_sans_cycle=copy.deepcopy(dictionnaire) # Pour que le dictionnaire
265 #d origine ne soit pas modifie
266 for eleve in sommets_trios: # liste des eleves se trouvant
267 # dans un cycle de longueur 3
268 del dictionnaire_sans_cycle[eleve] #supprime la cle correspondante
269 # c est a dire le sommet
270 for liste in dictionnaire_sans_cycle.values(): # Supprime les arretes
271 # menant a un eleve dans un trio
272 for element in liste:
273 if element in sommets_trios:
274 liste.remove(element)
275 return dictionnaire_sans_cycle
278# La fonction ci-dessous est devenue inutile il me semble
279#Il suffit d utiliser def trinomes_parfaits(liste_cycles):
280def sommets_cycles_3(matrice: numpy.ndarray) -> list:
281 """
282 Retourne la liste des sommets appartenant a un cycle de longueur 3
283 """
284 n = len(matrice)
285 matrice_chemins_3 = matrice @ matrice @ matrice
286 liste_sommets_appartenant_cycles = []
287 for i in range(n):
288 if matrice_chemins_3[i][i] != 0:
289 liste_sommets_appartenant_cycles.append(i)
290 return liste_sommets_appartenant_cycles
293def creation_matrice_adj(graphe: dict) -> numpy.ndarray:
294 """
295 Retourne la matrice d adjacence de grphe.
297 Precondition : graphe est de type dictionnaire.
298 C est le dictionnaire du graphe des amis, ou les prenoms sont remplaces par
299 des numeros (ici entre 0 et 26)
300 Il n y a aucun prenom dans ce dictionnaire.
301 Ce graphe se trouve dans le fichier donnees_Projet
302 Post condition : cette fonction retourne un objet ndarray de numpy.
303 """
304 n = len(graphe)
305 matrice = zeros((n, n))
306 for sommet_ligne in graphe.keys():
307 i = sommet_ligne # Pour plus de clarte a la lecture
308 for sommet_colonne in graphe.keys():
309 j = sommet_colonne # Pour plus de clarte a la lecture
310 if sommet_colonne in graphe[sommet_ligne]:
311 matrice[i][j] = 1 # Notation habituelle en Maths
312 return matrice
315def eleves_sans_amis(dictionnaire: dict) -> list:
316 """
317 Cette fonction renvoie la liste des points isolés à partir d'un graphe
319 Entrée : un dictionnaire représentant un graphe
320 Sortie : Une liste de sommets de degré nul ? (voir la terminologie)
321 >>> eleves_sans_amis(dict_amis_numeros)
322 [0, 3, 7, 16, 17, 18, 23]
323 """
324 s = set()
325 for k in dict_amis_numeros.values():
326 for e in k.keys():
327 s.add(e)
328 dep = set()
329 for k in dict_amis_numeros.keys():
330 dep.add(k)
331 dep -= s
332 liste_eleves_sans_amis = list(dep)
333 return liste_eleves_sans_amis
335def recherche_binomes(matrice):
336 """
337 Cette fonction retourne la liste des listes d eleves s etant mutuellement
338 choisis par deux
340 Precondition : matrice est la matrice d adjacence complete du graphe de la
341 classe matrice est de type : ndarray de numpy
342 Postcondition : type retourné : liste de listes de deux numeros d eleves
343 triees
344 """
345 liste_binomes = []
346 for i in range(len(matrice)):
347 for j in range(len(matrice)):
348 if matrice[i][j] == 1 and matrice[j][i] == 1:
349 liste_binomes.append([i, j])
350 for binome in liste_binomes: # Classer les numeros par ordre croissant
351 binome.sort()
352 # Ce qui suit sert a supprimer les doublons car toutes les listes
353 # sont trouvees deux fois.
354 new_binomes = []
355 for binome in liste_binomes:
356 if binome not in new_binomes:
357 new_binomes.append(binome)
358 return new_binomes
360# La fonction ci-dessous est a peu pres realisee avec
361# def cycles_longueur_3(liste_chemins):
362def renvoyer_cycles(G: nx.classes.digraph.DiGraph) -> set: # Fonction a creer
363 """
364 Le but de cette fonction est de faire une proposition sur les cycles non
365 connectés au graphe.
367 Voir le test correspondant.
368 """
369 s = set() # Ensemble vide
370 return s
372def score_popularite(graphe: dict) -> list:
373 """
374 Renvoie un tableau de listes contenant le score de popularité et
375 d'inimitié de chacun.
377 - L'entrée est un graphe (au sens des dictionnaires)
378 - La sortie est une liste
379 >>> score_popularite({'Alice': {'Bob': 2, 'Eve': -1, 'Donald': 1}, \
380 'Bob': {'Alice': 2, 'Eve': -1, 'Donald': 1}, \
381 'Eve': {'Alice': 2, 'Bob': 1, 'Donald': -1}, \
382 'Donald': {'Bob': 2, 'Alice': 1, 'Eve': -1}})
383 [5, 5, -3, 1]
384 """
385 d = dict()
386 for nom in graphe:
387 d[nom] = 0
388 for nom in graphe.values():
389 for score in nom:
390 d[score] += nom[score]
391 return list(d.values())
393exemple_graphe = lire_entree_json()
394dict_eleves_numero = associer_eleves_numeros(exemple_graphe)
395dict_amis_numeros = graphe_numerique(exemple_graphe, dict_eleves_numero)
397dictionnaire=cree_dict_classe_liste(dict_amis_numeros)
398liste_chemins=tous_les_chemins_long_3(dictionnaire)
399trios=trinomes_parfaits(cycles_longueur_3(liste_chemins))
400G_petit=cree_graphe_nx(dict_reduit(dictionnaire,trios))
402def run():
403 """
404 La fonction qui éxécute le code
405 >>> run()
406 """
407 afficher_graphe(exemple_graphe,'graphe_initial.png')
408 afficher_graphe(dict_reduit(dictionnaire,trios),'graphe_petit.png')
410 with open('resultat.txt','w') as fichier:
411 fichier.write(f"{sommets_cycles_3(creation_matrice_adj(dict_amis_numeros))} \n \
412 {liste_chemins} \n \
413 tous les cycles de longueur 3 {cycles_longueur_3(liste_chemins)} \n \
414 trios {trios} \n \
415 dictionnaire reduit: {dict_reduit(dictionnaire,trios)}"
416 )
417 return None
419if __name__ == '__main__':
420 run()