私はアルゴリズムの紹介を読んでいて、本の練習を終わらせようとしています。
演習 4.1-3 で
4.1-3 最大部分配列問題のブルート フォース アルゴリズムと再帰アルゴリズムの両方を自分のコンピューターに実装します。どの問題サイズ n0 が、再帰アルゴリズムがブルート フォース アルゴリズムに勝るクロスオーバー ポイントを与えるか? 次に、再帰アルゴリズムの基本ケースを変更して、問題のサイズが n0 未満の場合は常にブルート フォース アルゴリズムを使用します。それはクロスオーバーポイントを変更しますか?
本の疑似コードに従って、2 つのアルゴリズムを作成しました。ただし、Theta(n*lgn) になるように設計され、より高速に実行されるはずの 2 番目のコードは、常に最初の Theta(n**2) よりも遅く実行されるため、私のコードには何か問題があるはずです。私のコードを以下に示します。
def find_maximum_subarray_bf(a): ブルート フォースの #bf
p1 = 0
l = 0 # 左の l
r = 0 # r は右
最大合計 = 0
範囲内の p1 の場合 (len(a)-1):
サブ合計 = 0
範囲内の p2 の場合 (p1, len(a)):
sub_sum += a[p2]
sub_sum > max_sum の場合:
max_sum = sub_sum
l = p1
r = p2
l、r、max_sumを返す
def find_maximum_subarray_dc(a): 分割統治の #dc
# サブ機能
# 指定された配列と、配列を a[l:m] に分割できる 3 つの指標
# と a[m+1:r] の場合、l \leq i \less m \less j \leq r" である部分配列 a[i:j] を見つけます。
# 上記の定義によれば、対象の部分配列は
# 2 つの部分配列 a[i:m] と a[m+1:j] で結合
# 成長率: theta(n)
def find_crossing_max(a、l、r、m):
# 左側
# ls_r と ls_l は、左部分配列の右境界と左境界を示します。
# l_max_sum は左部分配列の最大合計を示します
# sub_sum は、現在計算中のサブ配列の合計を示します
ls_l = 0
ls_r = m-1
l_max_sum = なし
サブ合計 = 0
for j in range(m+1)[::-1]: # 要素を右から左に追加
sub_sum += a[j]
sub_sum > l_max_sum の場合:
l_max_sum = sub_sum
ls_l = j
# 右側
# rs_r と rs_l は、左部分配列の右境界と左境界を示します。
# r_max_sum は、左部分配列の最大合計を示します
# sub_sum は、現在計算中のサブ配列の合計を示します
rs_l = m+1
rs_r = 0
r_max_sum = なし
サブ合計 = 0
範囲内の j の場合 (m+1,len(a)):
sub_sum += a[j]
sub_sum > r_max_sum の場合:
r_max_sum = sub_sum
rs_r = j
#混ぜる
return (ls_l, rs_r, l_max_sum+r_max_sum)
# サブ機能
# 成長率: theta(nlgn) のはずですが、何か問題があります
def recursion(a,l,r): # T(n)
r == l の場合:
リターン (l,r,a[l])
そうしないと:
m = (l+r)//2 # シータ(1)
左 = 再帰 (a、l、m) # T(n/2)
右 = 再帰(a,m+1,r) # T(n/2)
交差 = find_crossing_max(a,l,r,m) # theta(n)
左[2]>=右[2]および左[2]>=交差[2]の場合:
左に戻る
elif right[2]>=left[2] and right[2]>=crossing[2]:
右に戻る
そうしないと:
帰りの交差点
#マスター機能に戻る
l = 0
r = len(a)-1
return recursion(a,l,r)
if __name__ == "__main__":
from time インポート時間
a = [100,-10,1,2,-1,4,-6,2,5]
*= 2**10
time0 = 時間()
find_maximum_subarray_bf(a)
time1 = 時間()
find_maximum_subarray_dc(a)
time2 = 時間()
印刷「機能1:」、time1-time0
print "関数 2:", time2-time1
print "ratio:", (time1-time0)/(time2-time1)