利用(伪)随机数解决数学问题 ── 蒙特卡罗方法

风行水上 @ 2010-06-26 10:48:03
标签:

    从现象中规纳出数学规律,从而方便计算,是科学的重要目的之一。而规律的发现,往往源于对现象的观察。

    有些情况下,我们也许不知道规律是什么,也不知道如何推导,这时也许可以考虑直接通过多次实验来归纳结果。

    蒙特卡罗方法 (Monte-Carlo Method) 就是这样一种方法。下面举两个例子。

    23个人中生日相同的概率接近 50%

    不管你相信不相信,怕是都不容易通过计算来证明。那么,一个绕开计算的办法就是“暴力”来模拟。用程序随机给23个人分配生日并检查是否有重复,通过多次试验,从而得出概率。程序如下:

    proc test_random { {n_all 1000} } {
      set n_succ 0
      for {set n 0} { $n < $n_all} {incr n} {
        array set rvlut ""
        array unset rvlut "*"
    
        set same 0
        for {set i 0} {$i < 23} {incr i} {
           set d [expr int(rand()*365)]
    
           if ![info exists rvlut($d)] { set rvlut($d) 0 }
           incr rvlut($d)
    
           if {$rvlut($d) >= 2} { set same 1 }
        }
    
        if {$same > 0} { incr n_succ }
      }
    
      puts [format "%d/%d = %f" $n_succ $n_all [expr $n_succ*1.0/$n_all]]
    }
    
    test_random 10
    test_random 100
    test_random 1000
    test_random 10000
    
    ## 运行结果如下,可见概率确实在50%左右
    6/10 = 0.600000
    48/100 = 0.480000
    479/1000 = 0.479000
    5114/10000 = 0.511400
    
    标签:

      分享到:
      comments powered by Disqus

      18/20ms