問題1.22のtimed-prime-test手続きをfast-prime?(Fermat法参照) を使うように変え,
その問題で見つけた12個の素数をテストせよ. FermatテストはΘ(log n)の増加なので,
1,000,000近くの素数をテストする時間を1000近くの素数をテストする時間と比べ, どの位と予想するか.
データはその予想を支持するか. 違いがあれば説明出来るか.
フェルマーの小定理を用いた素数性のテストをする手続きを定義します.
手続きrandomの引数の範囲に制限があるため, 少し小細工をしています.
(define (square x) (* x x))
(define (expmod base exp m)
(cond ((= exp 0) 1)
((even? exp)
(remainder (square (expmod base (/ exp 2) m))
m))
(else
(remainder (* base (expmod base (- exp 1) m))
m))))
(define (rnd n)
(remainder (* (random (remainder n 4294967087))
(random (remainder n 4294967087)))
n))
(define (fermat-test n)
(define (try-it a)
(= (expmod a n n) a))
(try-it (+ 1 (rnd (- n 1)))))
(define (fast-prime? n times)
(cond ((= times 0) #t)
((fermat-test n) (fast-prime? n (- times 1)))
(else #f)))
;; 素数を求めるために必要な時間を計測する
(define (timed-prime-test n)
(newline)
(display n)
(start-prime-test n (current-milliseconds)))
(define (start-prime-test n start-time)
(if (fast-prime? n 10000)
(report-prime (- (current-milliseconds) start-time))))
(define (report-prime elapsed-time)
(display " *** ")
(display elapsed-time))
(define (search-for-primes start end)
(cond ((< start end)
(timed-prime-test start)
(search-for-primes (+ start 1) end))
(else
(newline)
(display "end"))))
素数を求めてみます.
ようこそ DrRacket, バージョン 6.1 [3m]. 言語: Pretty Big; memory limit: 2048 MB. > (search-for-primes 100000000000000 100000000000100) 100000000000031 *** 325 100000000000067 *** 344 100000000000097 *** 312 end > (search-for-primes 1000000000000000 1000000000000200) 1000000000000037 *** 342 1000000000000091 *** 351 1000000000000159 *** 340 end > (search-for-primes 10000000000000000 10000000000000100) 10000000000000061 *** 390 10000000000000069 *** 375 10000000000000079 *** 366 end >
この程度のデータでは, 何も言えそうにありません.
0 件のコメント:
コメントを投稿