神奇的三门问题,到底换不换门

熬夜无聊刷b站的时候刷到了一个有趣的视频,讲的是一个概率论问题【三门问题】,感觉很有意思,就记了下来。
这是原视频链接:神奇的三门问题

简单介绍下三门问题:现在有三扇门,两扇门后是山羊,一扇门后是跑车,随机选择一道门,如果门后是跑车,就中奖,否则就是没中奖。首先随机选择一道门,则此时中奖的概率是三分之一即33.33%;然后从剩下的两扇门中打开一道后面是山羊的门,此时就只剩下最后一扇既没有打开也没有被选择的门。这时你有一次换门的机会,可以重新选择最后一道门,也可以选择不换。

那么应该是选择换门呢,还是仍然选择之前选中的那扇门?在一般人的思维,换或不换中奖的概率都是一样的,都是二分之一50%,换门其实上没有多大的意义;然而正确的选择却超乎常人的想象,此时应该换门,换门中奖的概率高达66.6%,不换门中奖的概率只有33.3%,换门赢的概率几乎是不换门赢的概率的两倍。

首先是不换门赢的概率,很简单就是最开始的三选一33.3%,后面的打开一扇是山羊的门的操作对赢的概率没有任何影响,并不是打开之后的二选一,因为之后排除掉一个错误选项并不会影响之前的选择的概率。

然后是换门赢的概率,这个的逻辑有点绕,理解起来要从反面来思考。首先什么时候是必赢的呢?当然就是第三扇门就是正确的选择的时候,此时换门就赢;这也就意味着第一次选择的门必定是错误的时候换门必赢,因为第二扇错误的门已经被打开了,也就是说换门赢的概率取决于第一次选择时选错的概率,而第一次选择时选错的概率是多少呢?66.6%。

总结来说,换门不换门赢的概率取决于第一次选择选对或者选错的概率,不换门 -> 第一次选对 -> 33.3%,换门 -> 第一次选错 -> 66.6%。

口说无凭,代码来证,换门赢的概率确实大约是66.6%。

object ThreeDoor {
    private val doors: List<Int> = listOf(0, 1, 2)

    private var winAfterNoExchange: Int = 0

    private var winAfterExchange: Int = 0

    private const val gameTimes: Int = 100000

    fun run() {
        for (i in 0 until gameTimes) {
            runOnce()
        }
        println("total times: $gameTimes, win no exchange times: $winAfterNoExchange, winning probability: ${ (winAfterNoExchange.toFloat() / gameTimes) * 100}")
        println("total times: $gameTimes, win exchange times: $winAfterExchange, winning probability: ${ (winAfterExchange.toFloat() / gameTimes) * 100}")

    }

    private fun runOnce() {
        val correct = doors.random()
        val select = doors.random()
        val openSheep = doors.getSheep(correct, select)
        if (isWinNoExchange(correct, select, openSheep)) {
            winAfterNoExchange += 1
        }
        if (isWinExchange(correct, select, openSheep)) {
            winAfterExchange += 1
        }
    }

    private fun isWinNoExchange(correct: Int, select: Int, openSheep: Int): Boolean {
        return select == correct
    }

    private fun isWinExchange(correct: Int, select: Int, openSheep: Int): Boolean {
        val selectAfterExchange = doors.first {
            (it != select) && (it != openSheep)
        }
        return selectAfterExchange == correct
    }

    private fun List<Int>.getSheep(correct: Int, select: Int): Int {
        return this.filter {  (it != correct) && (it != select) }.random()
    }
}

在这里插入图片描述

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值