ρヒューリスティック
大きな数の因数を発見的に求めるρ法(Pollardのρヒューリスティック)をRubyで実装しました。
# 2個の素数の積を因数分解する def factor_two(given) start = Time.now one = rho(given) another = given / one elapsed = Time.now - start puts "#{given} = #{one} * #{another} (#{elapsed} sec)" end # 『アルゴリズムイントロダクション』第3巻p.196 # 「Pollardのρヒューリスティック」で因数を探す def rho(n) i = 1 x = rand(n) y = x k = 2 loop do i += 1 x = (x * x - 1) % n f = n.gcd(y - x) if f != 1 and f != n return f elsif i == k y = x k *= 2 puts "(i = #{i})" end end end secret = [ 8616460799, 1441149131980013567, 193410142322144802270868533101027, 134502404035572884331085302462570091, ].each do |n| factor_two n end
実行結果です。乱数の具合によって実行時間は大きく変わります。
(i = 2) (i = 4) (i = 8) (i = 16) (i = 32) (i = 64) (i = 128) 8616460799 = 96079 * 89681 (0.02 sec) (i = 2) (i = 4) (i = 8) (i = 16) (i = 32) (i = 64) (i = 128) (i = 256) (i = 512) (i = 1024) 1441149131980013567 = 524287 * 2748779069441 (0.561 sec) (i = 2) (i = 4) (i = 8) (i = 16) (i = 32) (i = 64) (i = 128) (i = 256) (i = 512) (i = 1024) (i = 2048) (i = 4096) 193410142322144802270868533101027 = 999907 * 193428131138340667952988161 (3.545 sec) (i = 2) (i = 4) (i = 8) (i = 16) (i = 32) (i = 64) (i = 128) (i = 256) (i = 512) (i = 1024) (i = 2048) (i = 4096) (i = 8192) (i = 16384) (i = 32768) (i = 65536) 134502404035572884331085302462570091 = 695361131 * 193428131138340667952988161 (76.339 sec)
- Based on: [PQ/P] 2005-03-19 Puzzle.0038