File tree Expand file tree Collapse file tree 3 files changed +111
-0
lines changed Expand file tree Collapse file tree 3 files changed +111
-0
lines changed Original file line number Diff line number Diff line change 31
31
#+begin_src shell
32
32
raco test chapter1/exercise1-10.scm
33
33
#+end_src
34
+ * 笔记
35
+ ** chapter3
36
+ *** 蒙特卡罗模拟步骤来计算 π
37
+ 3.1 赋值与局部变量, 155 页
38
+ #+begin_quote
39
+ 举例来说,6/π^2 是随机选取的两个整数之间没有公因子(也就是说,它们的最大公因子是1)的概率。我们可以利用这一事实做出π的近似值。
40
+ #+end_quote
41
+
42
+ 完全读不懂这段话,没理解是怎么可以算出π的近似值的。
43
+
44
+ 查阅完资料都知道:
45
+
46
+ 随机选取两个正整数,它们互质(即最大公约数GCD为1)的概率是 $\frac{6}{\pi^2}$ , 所谓的 互质指两个数没有公共因子(如8和15互质,但8和12不互质,因为公约数为4)。
47
+
48
+ 而这一结论是源自数论中关于 **互质数的密度** 的研究,与黎曼ζ函数相关(难怪我看不懂了)。
49
+
50
+ 而用蒙特卡罗模拟步骤来计算 ${\pi}$:
51
+
52
+ 随机实验:重复多次随机选取两个整数,检查它们的GCD是否为1。
53
+
54
+ 例如:
55
+ - (3, 5) → GCD=1(计数+1)
56
+ - (4, 6) → GCD=2(不计数)
57
+
58
+ 统计概率:
59
+
60
+ 若总实验次数为 N,其中 k 次GCD=1,则互质概率的估计值为 $\frac{k}{N}$
61
+
62
+ 关联π:
63
+
64
+ 根据数论结论 $\frac{k}{N} \approx \frac{6}{\pi^2}$,解得 $\pi \approx \sqrt{\frac{6N}{k}}$。
65
+
66
+ 当直接计算π困难时,可通过概率实验间接逼近。
67
+
68
+ 这里利用了数论中的概率规律,将π与随机事件联系起来。(对于高数也只是低分飘过的我来说,不知道数论的东西也太正常了)
69
+
70
+ #+begin_src racket
71
+ #lang racket
72
+
73
+ (define (estimate-pi trials)
74
+ (sqrt (/ 6 (monte-carlo trials cesaro-test))))
75
+
76
+ (define (cesaro-test)
77
+ (= (gcd (rand) (rand)) 1))
78
+
79
+ (define (monte-carlo trials experiment)
80
+ (define (iter trials-remaining trial-passed)
81
+ (cond ((= trials-remaining 0)
82
+ (/ trials-passed trials))
83
+ ((experiment)
84
+ (iter (- trials-remaining 1) (+ trials-passed 1)))
85
+ (else
86
+ (iter (- trials-remaining 1) trials-passed))))
87
+ (iter trials 0))
88
+ #+end_src
89
+
90
+ 这里的蒙特卡罗实现真的是优雅
Original file line number Diff line number Diff line change
1
+ #lang racket
2
+ (require "rand.rkt " )
3
+ (define (estimate-pi trials)
4
+ (sqrt (/ 6 (monte-carlo trials cesaro-test))))
5
+
6
+ (define (cesaro-test)
7
+ (= (gcd (rand) (rand)) 1 ))
8
+
9
+ (define (monte-carlo trials experiment)
10
+ (define (iter trials-remaining trial-passed)
11
+ (cond ((= trials-remaining 0 )
12
+ (/ trial-passed trials))
13
+ ((experiment)
14
+ (iter (- trials-remaining 1 ) (+ trial-passed 1 )))
15
+ (else
16
+ (iter (- trials-remaining 1 ) trial-passed))))
17
+ (iter trials 0 ))
18
+
19
+ (module+ test
20
+ (require rackunit)
21
+ (require rackunit/text-ui)
22
+ (define (estimate-pi-close? trials tolerance)
23
+ (let ((pi-estimate (estimate-pi trials)))
24
+ (< (abs (- pi-estimate 3.14159 )) tolerance)))
25
+
26
+ (define module-test
27
+ (test-suite
28
+ "Tests for estimate-pi "
29
+ (check-true (estimate-pi-close? 10000 0.1 ))
30
+ (check-true (estimate-pi-close? 100000 0.01 ))
31
+ (check-true (estimate-pi-close? 10000000 0.001 ))
32
+ (check-exn exn:fail? (lambda () (estimate-pi 0 )) "Should throw exception for 0 trials " )
33
+ ))
34
+ (run-tests module-test))
Original file line number Diff line number Diff line change
1
+ #lang racket
2
+
3
+ ;; 线性同余生成器(Linear Congruential Generator, LCG)
4
+ ;; latex 公式: X_{n+1} = (a \cdot X_n + c) \pmod{m}
5
+ ;; https://en.wikipedia.org/wiki/Linear_congruential_generator
6
+ ;; 使用 C++11 minstd_rand 实现的参数
7
+ (define (rand-update x)
8
+ (let ((a 48271 )
9
+ (c 0 )
10
+ (m (- (expt 2 31 ) 1 )))
11
+ (modulo (+ (* a x) c) m)))
12
+
13
+ (define random-init 42 )
14
+ (define rand
15
+ (let ((x random-init))
16
+ (lambda ()
17
+ (set! x (rand-update x))
18
+ x)))
19
+
20
+ (provide rand)
You can’t perform that action at this time.
0 commit comments