parent
556af55e7e
commit
bcd864a06b
@ -1,2 +1,7 @@
|
|||||||
# sae-2.02-algorithmique
|
# sae-2.02-algorithmique
|
||||||
|
|
||||||
|
Snippets de code pour la SAÉ 2.02 mettant en avant:
|
||||||
|
- L'analyse d'algorithme
|
||||||
|
- Le calcul de complexité
|
||||||
|
- La visualisation d'algorithme via des graphes et des arbres
|
||||||
|
- L'optimisation d'algorithme
|
@ -0,0 +1,210 @@
|
|||||||
|
import random
|
||||||
|
import time
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import networkx as nx
|
||||||
|
from scipy.special import factorial
|
||||||
|
from sympy.ntheory import factorint
|
||||||
|
import cProfile
|
||||||
|
|
||||||
|
|
||||||
|
def triBulles(T):
|
||||||
|
for i in range(len(T)-1, 0, -1):
|
||||||
|
for j in range(i):
|
||||||
|
if T[j+1] < T[j]:
|
||||||
|
tmp = T[j]
|
||||||
|
T[j] = T[j+1]
|
||||||
|
T[j+1] = tmp
|
||||||
|
|
||||||
|
def triInsertion(T):
|
||||||
|
for i in range(1, len(T)):
|
||||||
|
valeurInsertion = T[i]
|
||||||
|
j = i - 1
|
||||||
|
while j >= 0 and valeurInsertion < T[j]:
|
||||||
|
T[j + 1] = T[j]
|
||||||
|
j -= 1
|
||||||
|
T[j + 1] = valeurInsertion
|
||||||
|
|
||||||
|
def fusion(T1, T2):
|
||||||
|
T = []
|
||||||
|
i, j = 0, 0
|
||||||
|
while i + j < len(T1) + len(T2):
|
||||||
|
if j == len(T2) or (i < len(T1) and T1[i] < T2[j]):
|
||||||
|
T.append(T1[i])
|
||||||
|
i += 1
|
||||||
|
else:
|
||||||
|
T.append(T2[j])
|
||||||
|
j += 1
|
||||||
|
return T
|
||||||
|
|
||||||
|
def triFusion(T):
|
||||||
|
n = len(T)
|
||||||
|
if n < 2:
|
||||||
|
return T.copy()
|
||||||
|
milieu = n // 2
|
||||||
|
T1 = list(T[:milieu])
|
||||||
|
T2 = list(T[milieu:])
|
||||||
|
T1 = triFusion(T1)
|
||||||
|
T2 = triFusion(T2)
|
||||||
|
return fusion(T1, T2)
|
||||||
|
|
||||||
|
def recherche_sequentielle_qcq(T, val):
|
||||||
|
for i in range(len(T)):
|
||||||
|
if T[i] == val:
|
||||||
|
return i
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def recherche_sequentielle_si_trie(T, val):
|
||||||
|
for i in range(len(T)):
|
||||||
|
if T[i] == val:
|
||||||
|
return i
|
||||||
|
elif T[i] > val:
|
||||||
|
return -1
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def EchelonnageGauss(M):
|
||||||
|
for i in range(len(M)):
|
||||||
|
for i2 in range(i + 1, len(M)):
|
||||||
|
c = M[i2][i] / M[i][i]
|
||||||
|
for j in range(i, len(M[i])):
|
||||||
|
M[i2][j] -= c * M[i][j]
|
||||||
|
return M
|
||||||
|
|
||||||
|
def algo_prim(G, s):
|
||||||
|
sommetsT = [s]
|
||||||
|
aretesT = []
|
||||||
|
while len(G.nodes) != len(sommetsT):
|
||||||
|
aretesDeTversPasT = [a for a in G.edges if (a[0] in sommetsT and a[1] not in sommetsT) or (a[1] in sommetsT and a[0] not in sommetsT)]
|
||||||
|
aPetit = min(aretesDeTversPasT, key=lambda a: G[a[0]][a[1]]['weight'])
|
||||||
|
aretesT.append(aPetit)
|
||||||
|
if aPetit[0] not in sommetsT:
|
||||||
|
sommetsT.append(aPetit[0])
|
||||||
|
else:
|
||||||
|
sommetsT.append(aPetit[1])
|
||||||
|
return aretesT
|
||||||
|
|
||||||
|
def algo_kruskal(G):
|
||||||
|
aretes_prises = []
|
||||||
|
partition_sommets = {v: i for i, v in enumerate(G.nodes)}
|
||||||
|
nombre_parties = len(G.nodes)
|
||||||
|
while nombre_parties > 1:
|
||||||
|
aretes_possibles = [e for e in G.edges if partition_sommets[e[0]] != partition_sommets[e[1]]]
|
||||||
|
arete_min = min(aretes_possibles, key=lambda e: G[e[0]][e[1]]['weight'])
|
||||||
|
aretes_prises.append(arete_min)
|
||||||
|
partie_supprimee = partition_sommets[arete_min[0]]
|
||||||
|
nouvelle_partie = partition_sommets[arete_min[1]]
|
||||||
|
for v in G.nodes:
|
||||||
|
if partition_sommets[v] == partie_supprimee:
|
||||||
|
partition_sommets[v] = nouvelle_partie
|
||||||
|
nombre_parties -= 1
|
||||||
|
return aretes_prises
|
||||||
|
|
||||||
|
def parcours(G, s):
|
||||||
|
visites = [s]
|
||||||
|
F = [s]
|
||||||
|
while F:
|
||||||
|
v = F.pop(0)
|
||||||
|
for u in G.neighbors(v):
|
||||||
|
if u not in visites:
|
||||||
|
visites.append(u)
|
||||||
|
F.append(u)
|
||||||
|
return visites
|
||||||
|
|
||||||
|
def est_frontiere_vide(F):
|
||||||
|
return len(F) == 0
|
||||||
|
|
||||||
|
def ajouter_frontiere(F, v):
|
||||||
|
F.append(v)
|
||||||
|
|
||||||
|
def enlever_frontiere(F):
|
||||||
|
if not est_frontiere_vide(F):
|
||||||
|
del F[0]
|
||||||
|
|
||||||
|
def valeur_frontiere(F):
|
||||||
|
if not est_frontiere_vide(F):
|
||||||
|
return F[0]
|
||||||
|
|
||||||
|
def closest_factorial(n):
|
||||||
|
k = 1
|
||||||
|
fact = 1
|
||||||
|
while fact < n:
|
||||||
|
k += 1
|
||||||
|
fact *= k
|
||||||
|
return k
|
||||||
|
|
||||||
|
def longest_prime_decomp(L):
|
||||||
|
n_max = L[0]
|
||||||
|
factor_max = factorint(n_max)
|
||||||
|
for n in L[1:]:
|
||||||
|
factors = factorint(n)
|
||||||
|
if len(factors) > len(factor_max):
|
||||||
|
n_max = n
|
||||||
|
factor_max = factors
|
||||||
|
return n_max, factor_max
|
||||||
|
|
||||||
|
def no_overlap(L1, L2):
|
||||||
|
set_L2 = set(L2)
|
||||||
|
for a in L1:
|
||||||
|
if a in set_L2:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def taille_max(liste_noms):
|
||||||
|
if len(liste_noms) < 3:
|
||||||
|
return sum(len(nom) for nom in liste_noms)
|
||||||
|
liste_tailles = sorted([len(nom) for nom in liste_noms], reverse=True)
|
||||||
|
return liste_tailles[0] + liste_tailles[1] + liste_tailles[2]
|
||||||
|
|
||||||
|
def algo_prim_bis(G, s):
|
||||||
|
sommetsT = [s]
|
||||||
|
aretesT = []
|
||||||
|
aretesDeTversPasT = list(G.edges(s))
|
||||||
|
while len(G.nodes()) != len(sommetsT):
|
||||||
|
aPetit = min(aretesDeTversPasT, key=lambda a: G.get_edge_data(*a)["weight"])
|
||||||
|
aretesT.append(aPetit)
|
||||||
|
sommet = aPetit[0] if aPetit[0] not in sommetsT else aPetit[1]
|
||||||
|
sommetsT.append(sommet)
|
||||||
|
for a in list(G.edges(sommet)):
|
||||||
|
if (a[1], a[0]) in aretesDeTversPasT:
|
||||||
|
aretesDeTversPasT.remove((a[1], a[0]))
|
||||||
|
else:
|
||||||
|
aretesDeTversPasT.append(a)
|
||||||
|
return aretesT
|
||||||
|
|
||||||
|
|
||||||
|
def recherche_dichoto(T, val):
|
||||||
|
deb = 0
|
||||||
|
fin = len(T) - 1 #! Correction: fin doit être len(T) - 1
|
||||||
|
while deb <= fin:
|
||||||
|
m = (deb + fin) // 2
|
||||||
|
vM = T[m]
|
||||||
|
if val == vM:
|
||||||
|
return m
|
||||||
|
elif val < vM:
|
||||||
|
fin = m - 1
|
||||||
|
else:
|
||||||
|
deb = m + 1
|
||||||
|
return -1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def mesure_temps_execution(algo, tailles):
|
||||||
|
temps = []
|
||||||
|
for taille in tailles:
|
||||||
|
data = [random.randint(1, 1000) for _ in range(taille)]
|
||||||
|
debut = time.time()
|
||||||
|
algo(data)
|
||||||
|
fin = time.time()
|
||||||
|
temps.append(fin - debut)
|
||||||
|
return temps
|
||||||
|
|
||||||
|
tailles = [100, 500, 1000, 5000, 10000]
|
||||||
|
temps_tri_bulles = mesure_temps_execution(triBulles, tailles)
|
||||||
|
|
||||||
|
plt.plot(tailles, temps_tri_bulles, label='Tri à bulles')
|
||||||
|
plt.xlabel('Taille des données')
|
||||||
|
plt.ylabel('Temps d\'exécution (s)')
|
||||||
|
plt.title('Temps d\'exécution du tri à bulles')
|
||||||
|
plt.legend()
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
cProfile.run('triBulles([random.randint(1, 1000) for _ in range(10000)])')
|
Loading…
Reference in new issue