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)