三扇门选车的问题

风行水上 @ 2013-11-11 11:00:32
标签:

    经典的概率问题。其中的一个情景表述如下:

    一个抽奖活动中,有三扇门,其中一扇门后面是一辆车,其他的则是空的。

    你选择其中一扇门。然后主持人从剩下两扇门中打开一扇后面没有东西的门。

    问题:你这是是否愿意改变你的选择。

    背后的数学问题是概率问题。据说最初很多大学教授也不能正确回答这个问题。

    概率问题的背后是什么是“正确的问题是什么”:

    • 一个二选一的问题
    • 一个三选二的问题

    正确的答案是“这是一个三选二的问题”。(能问出正确的问题不是一件容易的事情)。

    用蒙特卡罗方法进行验证。

    #!/usr/bin/tclsh
     
    #
    # Given 3 doors, 1 of them has a car behind.
    # You choose 1 door from the 3.
    # Then from the left 2 doors, one which has no car behind will be open for you.
    # Now question is: Do you want to change your choice?
    #
    # Is it a half to half possibility?
    #
     
    package require Tcl 8.5
     
    proc test_win {N} {
     
      for {set i $N } {$i > 0} {incr i -1} {
        set doors [list 0 0 0]
        lset doors [expr int(floor(rand()*3))] 1   ;# random place the car behind one door
     
        set idx [expr int(floor(rand()*3))]
        set door_pick [lindex $doors $idx]         ;# random pick one door
        set left_doors [lreplace $doors $idx $idx]
     
        # random remove one door has no car in the left 2 doors
        while {1} {
          set idx [expr int(floor(rand()*2))]
          if {[lindex $left_doors $idx] == 0} break
        }
     
        set last_doors [lreplace $left_doors $idx $idx]
        set door_left  [lindex $last_doors 0]
     
        # if swap
        if {$door_left == 1} {
          incr counter(swap.succ)
        } else {
          incr counter(swap.fail)
        }
     
        # if not swap
        if {$door_pick == 1} {
          incr counter(keep.succ)
        } else {
          incr counter(keep.fail)
        }
      }
     
      puts [format "%6d | %6d %6.2f%% | %6d %6.2f%%" $N           \
        $counter(swap.succ) [expr {$counter(swap.succ)*100.0/$N}] \
        $counter(keep.succ) [expr {$counter(keep.succ)*100.0/$N}] \
      ]
    }
     
    #------------------------------------------------------
    # main
    #------------------------------------------------------
     
    puts [string repeat "-" 48]
    puts [format "%6s | %14s | %14s" "" "If Swap" "If Keep"]
    puts [format "%6s | %6s %7s | %6s %7s" "N" "#succ" "succ%" "#succ" "succ%"]
    puts [string repeat "-" 48]
    foreach N {10 100 1000 10000 100000} {
      test_win $N
    }
     
    exit
     
    #------------------------------------------------------
    # Output
    #------------------------------------------------------
     
    ------------------------------------------------
           |        If Swap |        If Keep
         N |  #succ   succ% |  #succ   succ%
    ------------------------------------------------
        10 |      6  60.00% |      4  40.00%
       100 |     63  63.00% |     37  37.00%
      1000 |    683  68.30% |    317  31.70%
     10000 |   6747  67.47% |   3253  32.53%
    100000 |  66411  66.41% |  33589  33.59%
    
    标签:

      分享到:
      comments powered by Disqus

      21/23ms