Python: 実行時間の比較
Introduction to Algorithms の 1章の章末問題を Python で計算してみる。
・問題
各関数 f(n) と時間 t に対して、アルゴリズムが問題を解くのに f(n) マイクロ秒かかるとき、
t 時間で解くことができる最大の問題のサイズ n を求めよ。
関数 f(n): lg n √n n n lg n n2 n3 2n n!
時間 t : 1秒 1分 1時間 1日 1月 1年 1世紀
・コード
二分検索で解くコード。ただし、lg n に関しては n が大きくなりすぎるので直接 2t を求める。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | import math def binary_search(predicate, lower_bound, upper_bound, not_found = 0 ): """ Returns the least x for which predicate P(x) is true. Predicate P must be assumed: for all x in ordered set S, P(x) implies P(y) for all y > x @param predicate: unary function which returns true or false @param lower_bound: lower bound on the search @param upper_bound: upper bound on the search @param not_found: return value when all the predicates are false """ ret = not_found while lower_bound < upper_bound: mid = lower_bound + (upper_bound - lower_bound) / 2 if predicate(mid): ret = upper_bound = mid else : lower_bound = mid + 1 return ret def main(): # periods periods = [ None ] * 7 periods[ 0 ] = 1e6 # 1 second = 1,000,000 microsecond periods[ 1 ] = periods[ 0 ] * 60 # 1 minute = 60 seconds periods[ 2 ] = periods[ 1 ] * 60 # 1 hour = 60 minutes periods[ 3 ] = periods[ 2 ] * 24 # 1 day = 24 hours periods[ 5 ] = periods[ 3 ] * 365.2425 # 1 year = 365.2425 days periods[ 4 ] = periods[ 5 ] / 12.0 # 1 month = 1/12 year periods[ 6 ] = periods[ 5 ] * 100 # 1 century = 100 years # algorithms def find(func, t, max_n): return binary_search( lambda n: func(n) > t, 1 , max_n) - 1 algos = [ [ 'lg n' , None ], [ 'sqrt n' , lambda t: find(( lambda n: math.sqrt(n)) , t, 10 * * 32 ) ], [ 'n' , lambda t: find(( lambda n: n) , t, 10 * * 16 ) ], [ 'n lg n' , lambda t: find(( lambda n: n * math.log(n, 2 )), t, 10 * * 16 ) ], [ 'n ^ 2' , lambda t: find(( lambda n: pow (n, 2 )) , t, 10 * * 16 ) ], [ 'n ^ 3' , lambda t: find(( lambda n: pow (n, 3 )) , t, 10 * * 16 ) ], [ '2 ^ n' , lambda t: find(( lambda n: pow ( 2 , n)) , t, 100 ) ], [ 'n!' , lambda t: find(( lambda n: math.factorial(n)) , t, 100 ) ], ] # print results print '%-12s' % 'f(n)' , for i in ( 'second' , 'minute' , 'hour' , 'day' , 'month' , 'year' , 'century' ): print '%12s' % i, print print '-' * ( 13 * 8 - 1 ) for i, algo in enumerate (algos): print '%-12s' % algo[ 0 ], for t in periods: if i = = 0 : print '%12s' % ( '1e+(%.1e)' % (math.log( 10 , 2 ) * t)), else : val = algo[ 1 ](t) if (val < 1e12 ): print '%12d' % val, else : print '%12.1e' % val, print if __name__ = = '__main__' : main() |
・出力結果
1 2 3 4 5 6 7 8 9 10 | f(n) second minute hour day month year century ------------------------------------------------------------------------------------------------------- lg n 1e+(3.3e+06) 1e+(2.0e+08) 1e+(1.2e+10) 1e+(2.9e+11) 1e+(8.7e+12) 1e+(1.0e+14) 1e+(1.0e+16) sqrt n 1.0e+12 3.6e+15 1.3e+19 7.5e+21 6.9e+24 1.0e+27 1.0e+31 n 1000000 60000000 3600000000 86400000000 2.6e+12 3.2e+13 3.2e+15 n lg n 62746 2801417 133378058 2755147513 72876948666 798145165979 6.9e+13 n ^ 2 1000 7745 60000 293938 1621649 5617557 56175574 n ^ 3 100 391 1532 4420 13802 31600 146678 2 ^ n 19 25 31 36 41 44 51 n! 9 11 12 13 15 16 17 |
参考:
Introduction to Algorithms, Third Edition Supplemental Content
http://mitpress.mit.edu/algorithms/
Video Lectures – MIT Open Courceware
http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-046j-introduction-to-algorithms-sma-5503-fall-2005/video-lectures/
0 件のコメント:
コメントを投稿