Je suis en train de lire l'introduction aux algorithmes et d'essayer de terminer l'exercice dans le livre.L'algorithme Thêta (n ** 2) et Thêta (n * lgn) ne fonctionnent pas correctement
Dans l'exercice 4.1-3
4.1-3 Mettre en œuvre à la fois la force brute et les algorithmes récursifs pour le problème maximal sur votre propre sous-tableau ordinateur. Quelle taille de problème n0 donne le point de croisement auquel l'algorithme récursif bat l'algorithme de force brute? Ensuite, changez le cas de base de l'algorithme récursif pour utiliser l'algorithme de force brute chaque fois que la taille du problème est inférieure à n0. Cela change-t-il le point de croisement?
j'ai écrit les deux algorithmes selon pseudo-code du livre. Cependant, il doit y avoir quelque chose qui ne va pas avec mon code parce que le second, qui est conçu pour être Theta (n * lgn) et supposé courir plus vite, est toujours plus lent que le premier Theta (n ** 2). Mes codes sont indiqués ci-dessous.
def find_maximum_subarray_bf(a): #bf for brute force p1 = 0 l = 0 # l for left r = 0 # r for right max_sum = 0 for p1 in range(len(a)-1): sub_sum = 0 for p2 in range(p1, len(a)): sub_sum += a[p2] if sub_sum > max_sum: max_sum = sub_sum l = p1 r = p2 return l, r, max_sum def find_maximum_subarray_dc(a): #dc for divide and conquer # subfunction # given an arrary and three indics which can split the array into a[l:m] # and a[m+1:r], find out a subarray a[i:j] where l \leq i \less m \less j \leq r". # according to the definition above, the target subarray must # be combined by two subarray, a[i:m] and a[m+1:j] # Growing Rate: theta(n) def find_crossing_max(a, l, r, m): # left side # ls_r and ls_l indicate the right and left bound of the left subarray. # l_max_sum indicates the max sum of the left subarray # sub_sum indicates the sum of the current computing subarray ls_l = 0 ls_r = m-1 l_max_sum = None sub_sum = 0 for j in range(m+1)[::-1]: # adding elements from right to left sub_sum += a[j] if sub_sum > l_max_sum: l_max_sum = sub_sum ls_l = j # right side # rs_r and rs_l indicate the right and left bound of the left subarray. # r_max_sum indicates the max sum of the left subarray # sub_sum indicates the sum of the current computing subarray rs_l = m+1 rs_r = 0 r_max_sum = None sub_sum = 0 for j in range(m+1,len(a)): sub_sum += a[j] if sub_sum > r_max_sum: r_max_sum = sub_sum rs_r = j #combine return (ls_l, rs_r, l_max_sum+r_max_sum) # subfunction # Growing Rate: should be theta(nlgn), but there is something wrong def recursion(a,l,r): # T(n) if r == l: return (l,r,a[l]) else: m = (l+r)//2 # theta(1) left = recursion(a,l,m) # T(n/2) right = recursion(a,m+1,r) # T(n/2) crossing = find_crossing_max(a,l,r,m) # theta(n) if left[2]>=right[2] and left[2]>=crossing[2]: return left elif right[2]>=left[2] and right[2]>=crossing[2]: return right else: return crossing #back to master function l = 0 r = len(a)-1 return recursion(a,l,r) if __name__ == "__main__": from time import time a = [100,-10,1,2,-1,4,-6,2,5] a *= 2**10 time0 = time() find_maximum_subarray_bf(a) time1 = time() find_maximum_subarray_dc(a) time2 = time() print "function 1:", time1-time0 print "function 2:", time2-time1 print "ratio:", (time1-time0)/(time2-time1)
+1 Très belle réponse et l'explication – amit
Votre réponse est grande! Merci beaucoup! – xwb1989