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 を求める。
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()
・出力結果
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 件のコメント:
コメントを投稿