FAOD-DUI5/FOAD-bloc5-corrige.py

196 lines
5.6 KiB
Python

import matplotlib.pyplot as plt
from random import randint
from time import time
### Images de "tests" ####################################################################################
t1 = [
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 1],
[1, 0, 0, 0, 0],
[0, 0, 1, 1, 0],
[0, 1, 0, 0, 1],
]
t2 = [
[0, 0, 0, 1, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 1, 1, 1, 1, 1, 1, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 1, 0],
[1, 1, 1, 1, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 1, 0, 1, 1, 1, 1, 1],
[0, 0, 0, 1, 0, 0, 1, 0, 1, 0],
[0, 0, 0, 1, 0, 0, 1, 0, 1, 0],
]
##########################################################################################################
def aff(t):
plt.imshow(t, cmap="binary")
# plt.xticks( [i for i in range(len(t[0]))] )
# plt.yticks( [i for i in range(len(t))] )
plt.show()
def marque_carre(t, lig, col, taille):
for y in range(taille):
for x in range(taille):
t[lig - y][col - x] = 0.25
t[lig][col] = 0.30
def genere_tab_alea(n, ratio_noir):
t = []
for lig in range(n):
t.append([])
for col in range(n):
alea = randint(0, 100)
(t[lig]).append(1 if alea <= ratio_noir else 0)
return t
def PlusGrandCarreBlanc_Rec(t, lig, col):
global compteur_naif
compteur_naif += 1
if t[lig][col] == 1:
return 0
elif (lig == 0) or (col == 0):
return 1
else:
# Petit truc pour éviter de calculer toutes les valeurs dans le min si une des trois est déjà à 0 (au min)
h = PlusGrandCarreBlanc_Rec(t, lig - 1, col)
if h == 0:
return 1
g = PlusGrandCarreBlanc_Rec(t, lig, col - 1)
if g == 0:
return 1
gh = PlusGrandCarreBlanc_Rec(t, lig - 1, col - 1)
if gh == 0:
return 1
return min(g, h, gh) + 1
# return min(PlusGrandCarreBlanc_Rec(t, lig - 1, col), PlusGrandCarreBlanc_Rec(t, lig - 1, col - 1), PlusGrandCarreBlanc_Rec(t, lig, col - 1)) + 1
def PlusGrandCarreBlanc_memo(t, lig, col):
global compteur_memo
compteur_memo += 1
if t_memo[lig][col] != -1:
return t_memo[lig][col]
if t[lig][col] == 1:
t_memo[lig][col] = 0
return 0
elif (lig == 0) or (col == 0):
t_memo[lig][col] = 1
return 1
else:
res = (
min(
PlusGrandCarreBlanc_memo(t, lig - 1, col),
PlusGrandCarreBlanc_memo(t, lig, col - 1),
PlusGrandCarreBlanc_memo(t, lig - 1, col - 1),
)
+ 1
)
t_memo[lig][col] = res
return res
def RechercheCarreBlanc_naif(t):
l, c = 0, 0
tmax = 0
nb_lig, nb_col = len(t), len(t[0])
for lig in range(nb_lig): # On parcourt les lignes
for col in range(nb_col): # on parcourt les colonnes
taille = PlusGrandCarreBlanc_Rec(
t, lig, col
) # (le tableau est carré donc toutes les lignes ont la même longueur)
if taille >= tmax: # Si taille est > à tmax
l, c = lig, col # on a lig,col qui sont les coordonnées voulues
tmax = taille # on met à jour le tmax
return l, c, tmax
def RechercheCarreBlanc_memo(t):
l, c, tmax = 0, 0, 0
nb_lig, nb_col = len(t), len(t[0])
for lig in range(nb_lig):
for col in range(nb_col):
taille = PlusGrandCarreBlanc_memo(
t, lig, col
) # On utilise PlusGrandCarreBlanc_memo()
if taille >= tmax:
l, c = lig, col
tmax = taille
return l, c, tmax
def PlusGrandCarreBlanc_BU(t):
nb_lig, nb_col = len(t), len(t[0])
res = [[-1 for _ in range(nb_col)] for _ in range(nb_lig)]
for lig in range(nb_lig):
for col in range(nb_col):
if t[lig][col] == 1: # sous-problème de taille "0"
res[lig][col] = 0
elif lig == 0 or col == 0: # sous-problème de taille "1"
res[lig][col] = 1
else:
res[lig][col] = 1 + min(
res[lig - 1][col], res[lig][col - 1], res[lig - 1][col - 1]
)
return res
def RechercheCarreBlanc_BU(t):
l, c, tmax = 0, 0, 0
nb_lig, nb_col = len(t), len(t[0])
res = PlusGrandCarreBlanc_BU(t) # Avec l'algorithme BOTTOM UP
for lig in range(nb_lig):
for col in range(nb_col):
taille = res[lig][
col
] # On utilise le tableau fournit par PlusGrandCarreBlanc_BU()
if taille >= tmax:
l, c = lig, col
tmax = taille
return l, c, tmax
#############################################
# Programme principal
#############################################
compteur_naif = 0
compteur_memo = 0
n = 40
ratio = 50
t_memo = [[-1 for i in range(n)] for j in range(n)]
t3 = genere_tab_alea(n, ratio)
s = time()
res = RechercheCarreBlanc_naif(t3)
e = time()
print("Durée de l'algo naif : ", e - s, "nombre d'appels récursifs : ", compteur_naif)
s = time()
res = RechercheCarreBlanc_memo(t3)
e = time()
print(
"Durée de l'algo avec memoïsation : ",
e - s,
"nombre d'appels récursifs : ",
compteur_memo,
)
s = time()
res = RechercheCarreBlanc_BU(t3)
e = time()
print("Durée de l'algo avec BOTTOM UP : ", e - s)
marque_carre(t3, res[0], res[1], res[2])
aff(t3)