免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: win_hate
打印 上一主题 下一主题

SICP 习题参考答案 1.2  关闭 [复制链接]

论坛徽章:
0
31 [报告]
发表于 2008-09-13 11:00 |只看该作者

Exercise 1.23. 答案

理论估计和实际测试的结果都支持工作量减半的说法。

我把 smallest-divisor 改为


  1. (define (smallest-divisor n)
  2.   (define (f m)
  3.     (cond ((> (square m) n) n)
  4.           ((divides? m n) m)
  5.           (else (f (+ m 2)))))
  6.   (if (even? n) 2 (f 3)))
复制代码


在改动之前,(prime-test-prof 100003 10000) 输出为 2319
在改动之后,输出为 1149.

论坛徽章:
0
32 [报告]
发表于 2008-09-13 11:21 |只看该作者

Exercise 1.24.

Exercise 1.24.  Modify the timed-prime-test procedure of exercise 1.22 to use fast-prime? (the Fermat method), and test each of the 12 primes you found in that exercise. Since the Fermat test has (log n) growth, how would you expect the time to test primes near 1,000,000 to compare with the time needed to test primes near 1000? Do your data bear this out? Can you explain any discrepancy you find?

论坛徽章:
0
33 [报告]
发表于 2008-09-13 11:36 |只看该作者

Exercise 1.24. 答案

实际测试与 tha(log n) 的估计并不能很好地吻合。这里的 log (n) 与用 smallest-divisor 时的 sqrt(n) 估计不同。后者是一个很精确的估计,几乎就是实际的工作量;而前者是一个比较粗放的估计,只是一个边界。tha(log n) 是说,存在一组满足 log n 关系的上界,也存在一组满足 log n 关系的下界,实际的工作时间在两者之间。

[ 本帖最后由 win_hate 于 2008-9-13 11:52 编辑 ]

论坛徽章:
0
34 [报告]
发表于 2008-09-13 11:38 |只看该作者

Exercise 1.25.

Exercise 1.25.  Alyssa P. Hacker complains that we went to a lot of extra work in writing expmod. After all, she says, since we already know how to compute exponentials, we could have simply written

(define (expmod base exp m)
  (remainder (fast-expt base exp) m))

Is she correct? Would this procedure serve as well for our fast prime tester? Explain.

论坛徽章:
0
35 [报告]
发表于 2008-09-13 11:43 |只看该作者

Exercise 1.25. 答案

从纯数学的角度看,这个做法是完全正确的。在计算 a^n (mod m) 时,可以在中间过程中通过不断取模来限制对象的规模;也可以先计算出 a^n,最后取一次模。Alyssa P. Hacker 采用的就是后面的方法。从实现的角度看,这个做法是完全不可取的。

论坛徽章:
0
36 [报告]
发表于 2008-09-13 11:45 |只看该作者

Exercise 1.26.

Exercise 1.26.  Louis Reasoner is having great difficulty doing exercise 1.24. His fast-prime? test seems to run more slowly than his prime? test. Louis calls his friend Eva Lu Ator over to help. When they examine Louis's code, they find that he has rewritten the expmod procedure to use an explicit multiplication, rather than calling square:

(define (expmod base exp m)
  (cond ((= exp 0) 1)
        ((even? exp)
         (remainder (* (expmod base (/ exp 2) m)
                       (expmod base (/ exp 2) m))
                    m))
        (else
         (remainder (* base (expmod base (- exp 1) m))
                    m))))

``I don't see what difference that could make,'' says Louis. ``I do.'' says Eva. ``By writing the procedure like that, you have transformed the (log n) process into a (n) process.'' Explain.

论坛徽章:
0
37 [报告]
发表于 2008-09-13 11:47 |只看该作者

Exercise 1.26. 答案


  1. (expmod base exp m)-> (remainder (* (expmod base (/ exp 2) m)
  2.                                                             (expmod base (/ exp 2) m))
复制代码


这变成树型递归了,回忆经典的 fib 递归。

论坛徽章:
0
38 [报告]
发表于 2008-09-14 10:29 |只看该作者

Exercise 1.27.

Exercise 1.27.  Demonstrate that the Carmichael numbers listed in footnote 47 really do fool the Fermat test. That is, write a procedure that takes an integer n and tests whether a^n is congruent to a modulo n for every a<n, and try your procedure on the given Carmichael numbers.

论坛徽章:
0
39 [报告]
发表于 2008-09-14 10:57 |只看该作者

Exercise 1.27. 答案


  1. (define (fermat-liar? n)
  2.   (define (test a)
  3.     (cond ((= a n) #t)
  4.           ((= (powmod a n n) a) #t)
  5.           (else (test (+ a 1)))))

  6.   (test 2))
复制代码


注意,上面的代码要求 n 为合数。如果 n 是素的,则上述函数总返回 #t.

按书上注释 [47],开始的几个 carmichael 数为: 561, 1105, 1729, 2465, 2821, 和 6601,用上面的过程测一下:


  1. > (map fermat-liar? '(561 1105 1729 2465 2821 6601))
  2. (#t #t #t #t #t #t)
复制代码






======================================================================


理论分析

Carmichael 数 n 总具有如下特点
  • square free
  • 若 n=p1 p2 ... pm, 则  pi-1 | n-1, 其中  0<i < m+1.


容易证明,对于任意  pi, 总有 pi^(n-1) =1 (mod n/pi)。这样就得到了 pi^n=pi (mod n)。

于是,对 [0,n) 中的任意一个素数,f:x->x^n (mod n) 是个单位映射。由于 f 是完全积性的,所以对 [0, n) 中的每个数,f 都是单位映射。

关于 Carmichael 数的一般性介绍,可以参考维基百科的词条 [Carmichael Number]

[ 本帖最后由 win_hate 于 2008-9-14 11:20 编辑 ]

论坛徽章:
0
40 [报告]
发表于 2008-09-15 09:53 |只看该作者

Exercise 1.28.

Exercise 1.28.  One variant of the Fermat test that cannot be fooled is called the Miller-Rabin test (Miller 1976; Rabin 1980). This starts from an alternate form of Fermat's Little Theorem, which states that if n is a prime number and a is any positive integer less than n, then a raised to the (n - 1)st power is congruent to 1 modulo n. To test the primality of a number n by the Miller-Rabin test, we pick a random number a<n and raise a to the (n - 1)st power modulo n using the expmod procedure. However, whenever we perform the squaring step in expmod, we check to see if we have discovered a ``nontrivial square root of 1 modulo n,'' that is, a number not equal to 1 or n - 1 whose square is equal to 1 modulo n. It is possible to prove that if such a nontrivial square root of 1 exists, then n is not prime. It is also possible to prove that if n is an odd number that is not prime, then, for at least half the numbers a<n, computing a^(n-1) in this way will reveal a nontrivial square root of 1 modulo n. (This is why the Miller-Rabin test cannot be fooled.) Modify the expmod procedure to signal if it discovers a nontrivial square root of 1, and use this to implement the Miller-Rabin test with a procedure analogous to fermat-test. Check your procedure by testing various known primes and non-primes. Hint: One convenient way to make expmod signal is to have it return 0.

[ 本帖最后由 win_hate 于 2008-9-15 09:54 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP