p[i]+coupeRecurs(p,n-i)
max(q,p[i]+coupeRecurs(p,n-i))
def coupeRecurs(n,p):
if n==0:
return 0
else:
q=-1
for i in range (1,n+1):
q=max(q,p[i]+coupeRecurs(n-i,p))
return q
def plancheMemo(n,p):
r=[None]*(n+1)
return plancheMemoRecurs(n,p,r)
def plancheMemoRecurs(n,p,r):
if r[n]!=None:
return r[n]
elif n==0:
r[n]=0
else:
for i in range(1,n+1):
r[n]=max(r[n],p[i]+plancheMemoRecurs(n-i,p,r))
return r[n]
def plancheDynaBU(n,p):
r=[0 for i in range(n+1)]
for i in range (1,n+1):
q=0
for j in range (1,i+1):
q=max(q,p[j]+r[i-j])
r[j]=q
return r[n]
print(renduRec(11,[100,50,10,5,2]))
>>> 4
def renduDyna1(somme,systeme):
f=[-1]*(somme+1)
return renduDynaMemo(somme,systeme,f)
def renduDynaMemo (somme,systeme,f):
if f[somme]!=-1:
return f[somme]
if somme==0:
return 0
else:
mini = 1000
for i in range(len(systeme)):
if systeme[i] <=somme:
f[somme] = 1 + renduDynaMemo(somme-systeme[i],systeme,f)
if f[somme] <mini:
mini = f[somme]
return f[somme]
m=1+min(plusGrdCarreBlancRecurs(x-1,y-1,img),plusGrdCarreBlancRecurs(x,y-1,img),plusGrdCarreBlancRecurs(x-1,y,img))
def plusGrdCarreBlancRecurs(x,y,img):
if img[x][y]==1:
return 0
elif x==0 or y==0:
return 1
else: m=1+min(plusGrdCarreBlancRecurs(x-1,y-1,img),plusGrdCarreBlancRecurs(x,y-1,img),plusGrdCarreBlancRecurs(x-1,y,img))
return m
max=0
for i in range (len(test[0])):
for j in range (len(test[0])):
print(i,j)
if plusGrdCarreBlancRecurs(i,j,test) > max:
max=plusGrdCarreBlancRecurs(i,j,test)
print('le max est ',max)
def plusGrdCarreBlancDyna1(x,y,img):
memo=[[None]*len(img[0])]*len(img[0])
return plusGrdCarreBlancMemo(x,y,img,memo)
def plusGrdCarreBlancMemo(x,y,img,memo):
if memo[x][y]!=None:
return memo[x][y]
if img[x][y]==1:
memo[x][y]=0
return memo[x][y]
elif x==0 or y==0:
memo[x][y]=1
return memo[x][y]
else:
memo[x][y] = 1+min(plusGrdCarreBlancMemo(x-1,y-1,img,memo),plusGrdCarreBlancMemo(x,y-1,img,memo),plusGrdCarreBlancMemo(x-1,y,img,memo))
return memo[x][y]
def pluscourtchemin(fi,data,i,j):
#si le tableau n'est pas déjà rempli
if fi[i][j]==0:
# premiere case
if i==0 and j==0:
return data[0][0]
# effets de bord
elif i==0:
return fi[i][j-1]+data[i][j]
elif j==0:
return fi[i-1][j]+data[i][j]
#choix entre les deux positions possibles
else:
deux=[0,0]
deux[0]=fi[i-1][j]+data[i][j]
deux[1]=fi[i][j-1]+data[i][j]
return min(deux)
# transfert de la matrice du fichier texte dans la liste liste
matrix =open('matrix.txt','r')
liste =[ ligne.split(",") for ligne in matrix ]
matrix.close()
for i in range (len(liste[0])):
for j in range (len(liste[0])):
liste[i][j]=int(liste[i][j])
# creation de la matrice phi remplie de zero
phi=[[0 for i in range(80)] for j in range (80)]
#remplissage de la matrice phi
for i in range(80):
for j in range(80):
phi[i][j]=pluscourtchemin(phi,liste,i,j)
#affichage de a derniere case de phi
print(phi[79][79])
d(i, j) = 1 + d(i, j-1)
d(i, j) = 1 + d(i-1, j)
d(i, j) = d(i-1, j-1)
d(i, j) = 1 + d(i-1, j-1)
Le cas général sera de renvoyer le minimum parmi ces 4 distances possibles.
Les cas de base sont atteints lorsque :
i == - 1
) : la distance par rapport à la sous-chaîne j est alors égale au nombre de caractères de cette dernière, soit j+1.j == - 1
) : on renvoie dans ce cas i+1.
def dist_lev_rec(i, j):
if i == -1:
return j+1
if j == -1:
return i+1
if ch1[i] == ch2[j]:
cout_sub = dist_lev_rec(i-1, j-1)
else:
cout_sub = 1 + dist_lev_rec(i-1, j-1)
cout_ajout = 1 + dist_lev_rec(i-1, j)
cout_supp = 1 + dist_lev_rec(i, j-1)
return min(cout_sub, cout_ajout, cout_supp)
On peut écrire plus succinctement :
def dist_lev_rec(i, j):
if i == -1:
return j+1
if j == -1:
return i+1
cout = 0 if ch1[i] == ch2[î] else 1 # opérateur ternaire
return min(1 + dist_lev_rec(i-1, j-1), 1 + dist_lev_rec(i, j-1), cout + dist_lev_rec(i-1, j-1))
def dist_lev_TB(i, j):
if (i, j) in dist:
return dist[(i, j)]
if i == -1:
return j+1
if j == -1:
return i+1
if ch1[i] == ch2[j]:
cout_sub = dist_lev_TB(i-1, j-1)
else:
cout_sub = 1 + dist_lev_TB(i-1, j-1)
cout_ajout = 1 + dist_lev_TB(i-1, j)
cout_supp = 1 + dist_lev_TB(i, j-1)
cout_total = min(cout_sub, cout_ajout, cout_supp)
dist[(i, j)] = cout_total
return cout_total
dist est un dictionnaire initialement vide. Pour tester si une valeur a déjà été calculée auparavant, il suffit de déterminer si le couple (i, j) correspondant est déjà présent dans le dictionnaire ( complexité en O(1) ).
On constate, pour i > 0
et j > 0
, que la distance d(i, j) est le minimum entre :
1 + d(i-1, j)
,1 + d(i, j-1)
,d(i-1, j-1)
si les caractères ch1[i-1] et ch2[j-1]sont identiques,1 + d(i-1, j-1)
sinon.Par exemple :
Pour i = 2 et j = 4 ( distance entre 'CH' et 'CHUT' ) :
→ les lettres ( 'H' et 'T' ) sont différentes, donc : d(2, 4) = min(1+1, 1+2, 1+3) = min(2, 3, 4) = 2
Pour i = 4 et j = 4 ( distance entre 'CHAT' et 'CHUT' ) :
→ les lettres ( 'T' et 'T' ) sont identiques, donc : d(4, 4) = min(1+2, 0+1, 1+2) = min(3, 1, 3) = 1
La distance entre les deux chaînes ch1 et ch2 se trouve alors dans la case tout en bas à droite du tableau.
def dist_lev_BU(ch1, ch2):
m = len(ch1)
n = len(ch2)
# Initialisation du tableau
dp = [[0 for j in range(n+1)] for i in range(m+1)]
# Remplissage de la première colonne et de la première ligne
for i in range(m+1):
dp[i][0] = i
for j in range(n+1):
dp[0][j] = j
# Remplissage du tableau avec le calcul des distance pour chaque case (i, j) :
for i in range(1, m+1):
for j in range(1, n+1):
if ch1[i-1] == ch2[j-1]: # attention au décalage d'index : i = 0 ou j = 0 correspondent à une chaîne vide, pas au premier caractère des chaînes ( = indice 1 )
d1 = dp[i - 1][j - 1]
else:
d1 = 1 + dp[i - 1][j - 1]
d2 = 1 + dp[i-1][j]
d3 = 1 + dp[i][j-1]
dp[i][j] = min(d1, d2, d3)
# Renvoi de la plus petite distance :
return dp[m][n] # ou dp[-1][-1]