196 lines
5.6 KiB
Python
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)
|