def equilibre_reccurEtendue(texte, n, ind): res=([],0) if longueur(texte)<=n: #si la longueur du texte est inférieur à la longueur de la ligne res=([texte],0,'infini',0) #alors pas besoin de le découper, et on ignore le déséquilibre MEMO.add_etendue(ind,res[0],res[1],res[2],res[3]) else : curr=0 s='infini' longtext=longueur(texte[0:1]) while longtext<=n: reccur=MEMO.get_etendue(ind+curr+1) if reccur==-1: reccur=equilibre_reccurEtendue(texte[curr+1:],n,ind+curr+1) MEMO.add_etendue(ind+1,reccur[0],reccur[1],reccur[2],reccur[3]) c=reccur[2] l=reccur[3] if min(longtext,c)==longtext: c=longtext if min(longtext,l)==l: l=longtext s1=l-c if min(s1,s)==s1: s=s1 res=([texte[0:curr+1]]+reccur[0],s,c,l) curr+=1 longtext=longueur(texte[0:curr+1]) return res
def equilibreEtendue(texte, n): global MEMO MEMO=Memo() for i in range (len(texte)-1,-1,-1): #Pour i allant de l'indice du dernier mot au premier if longueur(texte[i:])<=n: res=([texte[i:]],0,'infini',0) else: curr=0 deseq='infini' longtext=longueur(texte[i:i+1]) while longtext<=n: suite=MEMO.get_etendue(i+curr+1) c=suite[2] l=suite[3] if min(longtext,c)==longtext: c=longtext if min(longtext,l)==l: l=longtext deseq_bis=l-c if min(deseq,deseq_bis)==deseq_bis: #on notera que la fonction min a été surchargée pour #considérer 'infini' comme l'infini deseq=deseq_bis res=([texte[i:i+curr+1]]+suite[0],deseq,c,l) curr+=1 longtext=longueur(texte[i:i+curr+1]) MEMO.add_etendue(i,res[0],res[1],res[2],res[3]) return res
def equilibre_reccur(texte, n, ind): res=([],0) if longueur(texte)<=n: #si la longueur du texte est inférieur à la longueur de la ligne res=([texte],0) #alors pas besoin de le découper, et on ignore le déséquilibre MEMO.add(ind,res[0],res[1]) else : curr=0 s='infini' while longueur(texte[0:curr+1])<=n: reccur=MEMO.get(ind+curr+1) if reccur==-1: reccur=equilibre_reccur(texte[curr+1:],n,ind+curr+1) MEMO.add(ind+1,reccur[0],reccur[1]) s1=blancLigne(texte[0:curr+1],n)+reccur[1] if min(s1,s)==s1: s=s1 res=([texte[0:curr+1]]+reccur[0],s) curr+=1 return res
def equilibreVar(texte, n): global MEMO MEMO=Memo() for i in range (len(texte)-1,-1,-1): #Pour i allant de l'indice du dernier mot au premier if longueur(texte[i:])<=n: res=([texte[i:]],0) else: curr=0 deseq='infini' while longueur(texte[i:i+curr+1])<=n: suite=MEMO.get(i+curr+1) deseq_bis=variance([texte[i:i+curr+1]]+suite[0]) if min(deseq,deseq_bis)==deseq_bis: #on notera que la fonction min a été surchargée pour #considérer 'infini' comme l'infini deseq=deseq_bis res=([texte[i:i+curr+1]]+suite[0],deseq) curr+=1 MEMO.add(i,res[0],res[1]) return res
def fusionTextsMinMax(text1, text2, stringLength): #print "Try to fusion" fusionedString = text1[-1][:] + text2[0][:] if(possibleString(fusionedString, stringLength)): #print "Fusioned string: ", fusionedString #print "is possible" fusionedLength = longueur(fusionedString) #print "with length", fusionedLength if(len(text1)>0): text1.pop() if(len(text2)>0): text2.pop(0) resultText = text1 + [fusionedString] + text2 #print "minmax for fusioned text:", longShortDistance(resultText) return True, longShortDistance(resultText), resultText else: #print "Fusion impossible" return False,[0,0],[]
def equilibrium(words, stringLength): #O(n^4) wordsCount = len(words) #Initialise par maxInt #Les matrices qui contiennent la longueur de ligne de taille maximale/minimale dans le texte maxMatrix = [[sys.maxint for _ in xrange(wordsCount)] for _ in xrange(wordsCount)] minMatrix = [[0 for _ in xrange(wordsCount)] for _ in xrange(wordsCount)] #La matrice qui contient les sous-textes pour chaque pas de programmation dynamique #Initialisee par listes vides stringMatrix = [[[] for _ in xrange(wordsCount)] for _ in xrange(wordsCount)] #Le parcours des diagonales commenceant d'element [0][0] k = 0; m = wordsCount; for s in range(0, m): #O(n^2/2) for i in range(k, wordsCount): j = i-k #print "###########################" #print "## Working with case",i,j,"##" #print "###########################" #Remplissage des diagonales if(i==j): #Remplissage des diagonales principales par mots seuls et poids des lignes avec un seul mot # print "Filling main diagonal case" minMatrix[i][j] = longueur([words[i]]) maxMatrix[i][j] = longueur([words[i]]) stringMatrix[i][j] = [[words[i]]] # print "String in case", stringMatrix[i][j] # print "Min value", minMatrix[i][j] #print "Max value", maxMatrix[i][j] else: #Remplissage des autres diagonales #Essayons de construire une nouvelle partie de texte a partir des construites les plus optimales #On peut concatener soustextes ou fusionner la derniere ligne de premier soustexte et premier ligne de deuxieme soustexte #en les concatenant si c'est possible column = j+1 for row in range(j, i): #Concatenations des soustextes #print "Working with case ", row,j, "with text", stringMatrix[row][j], "difValue:", maxMatrix[row][j]-minMatrix[row][j] #print "and case", i, column," with text", stringMatrix[i][column], "difValue:", maxMatrix[row][j]-minMatrix[row][j] d = max([maxMatrix[row][j], maxMatrix[i][column]]) - min([minMatrix[row][j], minMatrix[i][column]]) #print "Max-Min for concatenation", d #print "Current value", maxMatrix[i][j]-minMatrix[i][j] if(d < maxMatrix[i][j] - minMatrix[i][j]): #print "Now Min = ", minMatrix[i][j] maxMatrix[i][j] = max([maxMatrix[row][j], maxMatrix[i][column]]) #print "Max = ", maxMatrix[i][j] stringMatrix[i][j] = stringMatrix[row][j] + stringMatrix[i][column] #print "New string = ", stringMatrix[i][j] #Essai de fusion des soustextes fusion = fusionTextsMinMax(stringMatrix[row][j][:], stringMatrix[i][column][:], stringLength) if(fusion[0] and fusion[1][0] - fusion[1][1] < maxMatrix[i][j] - minMatrix[i][j]): maxMatrix[i][j] = fusion[1][0] minMatrix[i][j] = fusion[1][1] stringMatrix[i][j] = fusion[2] #print "Placed string", fusion[2] column = column + 1 k = k+1; m = m-1; #print "Result string:", stringMatrix[wordsCount-1][0] #print "Result dif:", maxMatrix[wordsCount-1][0] - minMatrix[wordsCount-1][0] return stringMatrix[wordsCount-1][0], maxMatrix[wordsCount-1][0] - minMatrix[wordsCount-1][0]