V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
estk
V2EX  ›  程序员

今天听说一个玄学算法,写了一下,确实玄学?

  •  
  •   estk · 2022-10-03 00:55:35 +08:00 · 7633 次点击
    这是一个创建于 817 天前的主题,其中的信息可能已经有所发展或是发生改变。

    假设有 3 个门编号分别为 0 ,1 ,2 ,其中只有 1 个门后面有奖品 主持人先打开一个不存在奖品的门,剩下两个门你随机打开一个,中奖概率是多少? 答案不是 50% 算法写的也确实不是,是写得不对吗?

    (async ()=>{
      let gotTimes = 0
      let missTimes = 0
      let failTimes = 0
      let testTimes = 100000
      while( --testTimes > 0) {
        const targetGateNo = parseInt(Math.random()*10**10)%3 // 0/1/2
        let gates = []
        for (let i=0; i<2; i++) {
          gates.push(i===targetGateNo)
        }
        const randomNo = parseInt(Math.random()*10**10)%3 // 0/1/2
        if (gates[randomNo]) {
          failTimes++
          continue
        }
        let randomNo2 = parseInt(Math.random()*10**10)%3
        while(randomNo2===randomNo) {
          randomNo2 = parseInt(Math.random()*10**10)%3
        }
        if (gates[randomNo2]) {
          gotTimes ++
          continue
        }
        missTimes ++
      }
      console.log(gotTimes/(gotTimes+missTimes), gotTimes, missTimes)
    })()
    

    剩下两个选一个,下意识觉得概率应该 50%才对,但是执行后是 0.28 左右

    46 条回复    2022-10-05 13:57:44 +08:00
    0ZXYDDu796nVCFxq
        1
    0ZXYDDu796nVCFxq  
       2022-10-03 00:59:57 +08:00
    因为你代码写错了
    前面打开一个不存在奖品的们,和后面再打开一个,两者是独立事件
    edis0n0
        2
    edis0n0  
       2022-10-03 01:01:39 +08:00   ❤️ 2
    先打开一个不存在奖品的门,剩下两个门你随机打开一个
    剩下两个门你随机打开一个
    两个门你随机打开一个
    两个门 随机
    两个门
    parseInt(Math.random()*10**10)%3 // 0/1/2
    Math.random()*10**10)%3
    %3
    ???
    houshuu
        3
    houshuu  
       2022-10-03 01:03:59 +08:00
    三门问题应该是这个吧
    https://zhuanlan.zhihu.com/p/37669145
    xyfan
        4
    xyfan  
       2022-10-03 01:04:48 +08:00   ❤️ 6
    你这问题可能是听(记)错了。我听到的版本是,你先选择一扇门,之后主持人打开一扇没有奖品的门,如果你不换选择,中奖概率是 1/3 ,如果你换选择,中奖概率是 2/3 。
    arch9999
        5
    arch9999  
       2022-10-03 01:10:38 +08:00
    你设置的前提,只能是 50%
    estk
        6
    estk  
    OP
       2022-10-03 01:14:46 +08:00 via Android
    @xyfan #4
    直觉上不应该是 0.5 吗?
    2/3 数学上可证明?
    estk
        7
    estk  
    OP
       2022-10-03 01:15:28 +08:00 via Android
    @xyfan #4
    明白了
    跟我讲述的人讲玄了
    Tink
        8
    Tink  
       2022-10-03 01:27:29 +08:00 via Android
    本来就不是 50‘
    akira
        9
    akira  
       2022-10-03 01:34:08 +08:00
    3 门问题啊,你描述的有遗漏。
    而且这就是个概率问题
    crab
        10
    crab  
       2022-10-03 02:38:18 +08:00   ❤️ 1
    leafin
        11
    leafin  
       2022-10-03 03:14:34 +08:00 via Android
    其实不难理解,3 扇门分别是 abc ,1 真 2 假,先随机选定一扇门,假设是 a ,那么 a 是真门的概率是 33%没错吧,这时候主持人打开一定是假门的门 c ,剩下 ab ,1 真 1 假,然后再打开 b ,最后打开 a 。那么 a 是真门的概率是多少呢,当然是 33%,打开顺序不会影响概率,因为一开始就选定 a 了。那让我们回到剩下 ab 的时候,c 是真门的概率是 0%(主持人保证 c 一定是假门),而 a 是 33%,那么 b 一定是 67%。
    Chad0000
        12
    Chad0000  
       2022-10-03 04:32:04 +08:00 via iPhone   ❤️ 2
    @estk
    这个确实不容易打破直觉。

    简单描述就是 abc 选其中一个,如果你选的是 a ,那么如果你选择换其实相当于你同时选了 bc (主持人帮你过滤掉无效的)。a 命中和 bc 命中是 1/3 和 2/3 的关系。
    Chad0000
        13
    Chad0000  
       2022-10-03 04:38:53 +08:00 via iPhone
    @Chad0000
    再精简一下:
    abc 你选 a ,命中率 1/3 ;
    你换的话,bc 只要有一个中你就中,概率 1/3+1/3 ;
    goophy
        14
    goophy  
       2022-10-03 08:04:36 +08:00 via iPhone   ❤️ 4
    如果是 100 扇门,选一个,再排除 98 扇,这时候换不换,选中的概率不同,就容易理解了
    dlsflh
        15
    dlsflh  
       2022-10-03 08:48:39 +08:00 via Android
    3 门问题换成一百门问题容易理解。
    yehoshua
        16
    yehoshua  
       2022-10-03 08:51:29 +08:00 via Android
    这不是概率论问题吗?条件概率和独立事件。基础的概率论问题。
    yehoshua
        17
    yehoshua  
       2022-10-03 09:01:56 +08:00 via Android   ❤️ 1
    个人认为这是个典型的概率论问题。
    这个问题 OP 的设定(不管经典三门问题怎么设定,而是 OP 的设定)答案是 50%。

    经典的三门问题比这个复杂一些。不过我认为也是 50%。
    yehoshua
        18
    yehoshua  
       2022-10-03 09:09:03 +08:00 via Android
    @yehoshua 经典三门问题我并不了解,刚去检索了,三门问题的原始阐述,有个特殊的限制。这个限制存在让三门不是简单的 50%。67%才是对的。
    heavymetals
        19
    heavymetals  
       2022-10-03 10:48:03 +08:00
    我也用 python 写过这种算法,答案不对肯定就是理解错了,因为在写的过程应该就已经知道答案了....

    https://gist.githubusercontent.com/Cristina269/c89739f2c7885f306ec7fa6b28c10a4e/raw/f353e22c700653353529711dbc23c536163cb9b3/%25E4%25B8%2589%25E7%2590%2583%25E9%2597%25AE%25E9%25A2%2598_python
    heavymetals
        20
    heavymetals  
       2022-10-03 10:52:27 +08:00
    @heavymetals 链接格式好像贴的不太对...v2ex 不能连续发链接,就这样吧
    JohnBull
        21
    JohnBull  
       2022-10-03 10:53:51 +08:00
    条件概率问题,通常有点反直觉
    mongcici
        22
    mongcici  
       2022-10-03 11:31:47 +08:00
    @leafin 这个问题我一直是想不通。按你说的感觉是这样,但是假定,我事先没有去随机选择一扇门,这时候主持人打开一定是假门的门 C ,剩下 ab ,1 真 1 假,这个时候我去选择 a 是真门的概率是多少呢?我感觉应该是 50%。
    我感觉 abc 本来都是 67%,当主持人打开了一扇假门 c ,剩下的 ab 的概率应该都变到 50%。不管我事先有没有选择 A 。
    eason1874
        23
    eason1874  
       2022-10-03 11:33:50 +08:00   ❤️ 2
    @estk #6
    @yehoshua #17 三门问题数学可证,换门确实是三分之二,我也写过代码验证,次数少会有偏差,100 万次以上基本就稳定了

    @heavymetals #19 这个问题的代码其实几行就能写出来了

    if SelectNum === WinNum then 第一次选中+1
    else {
    // 如果第一次没选中,那么 WinNum 在剩下的两个选项中
    // 而这时主持人又给你排除掉一个错误选项,等于同时排除了两个错误选项
    // 此时换门必中,不需要再写去掉错误选项的代码,加一即可
    换门选中+1
    }

    通过代码就能理清其中逻辑:只要第一次选错了,那么换门必中,第一次选错的概率是三分之二,所以换门选中概率也就是三分之二
    msg7086
        24
    msg7086  
       2022-10-03 11:44:04 +08:00
    @mongcici 主持人不一定打开门 C ,也可能打开门 A 或者门 B 。
    你事先选择的一扇门限制了主持人只能打开假门,而不允许打开真门(因为违反游戏规则了)。
    如果主持人根本不知道哪扇门是真的假的,闭着眼睛随便去掉一扇,那么你说的就是对的。

    这里利用的就是主持人拥有你所不拥有的知识来造成概率的不同。
    dvsilch
        25
    dvsilch  
       2022-10-03 11:46:51 +08:00
    就跟抽签一样,知道前面抽的签没中,中的概率就被平均到剩余的签了
    msg7086
        26
    msg7086  
       2022-10-03 11:52:14 +08:00
    @mongcici 也可以换一个等价的游戏规则。
    你先选一扇门 A ,然后主持人随机去掉一个门 C ,并且不告诉你 C 是真门还是假门。
    但是告诉你,如果 B 是真门,那么你选 B 可以获奖;但如果 C 是真门,那么你选 B 也可以获奖。
    这样是不是就很容易看出换门 67%不换 33%了。
    wukangave
        27
    wukangave  
       2022-10-03 14:24:06 +08:00   ❤️ 1
    大哥你的代码写错了
    “for (let i=0; i<2; i++) {”
    循环条件应该是 i<=2
    因为你写错了,数组里只有两个元素,然后 js 又没有数组溢出检查,所以当随机生成的奖品在第三个门的时候,玩家永远是错的。
    你把循环条件改对,概率就是 50%了
    Kroos
        28
    Kroos  
       2022-10-03 15:27:51 +08:00
    先不考虑代码怎么写,按照你的描述只能是 50%的答案。

    因为已经打开一个没有奖品的门了,剩下二选一相当于一个条件概率。
    yehoshua
        29
    yehoshua  
       2022-10-03 15:48:37 +08:00
    @eason1874 三门这个问题甚至不需要用次数验证,数学可以直接算的,很简单的概率论问题。只不过描述上让人迷惑,换成数学描述就很简单了。最终还是回到了概率论-_-
    leafin
        30
    leafin  
       2022-10-03 16:02:48 +08:00
    @estk 我也懒得改你的代码了,我重新写了一份,包含原本的三门和主贴里描述的三门,你运行一下看吧

    (() => {
    const rand3 = () => Math.floor(Math.random()*3)%3
    const next = (cur) => (cur+1)%3

    let noswap_wins = 0 // 维持原始选择
    let swap_wins = 0 // 交换选择
    let reselect_wins = 0 // 重新随机选择(主贴所描述的三门)
    const loop = 100000

    for(let i=0; i<loop; i++){
    const goal_door = rand3() // 有奖品的门
    const selected_door = rand3() // 参赛者选择的门
    let opened_door, swap_door // 主持人打开的门,可以交换的门

    // 主持人在未选择的两扇门中打开一扇没有奖品的门,并设置另一扇门为交换门
    opened_door = next(selected_door)
    if(opened_door !== goal_door){
    swap_door = next(opened_door)
    }else{
    swap_door = opened_door
    opened_door = next(opened_door)
    }

    // 如果这时候在两扇未开的门中重新随机选择(主贴所描述的三门)
    let reselected_door = next(opened_door)
    if(Math.random() > 0.5)
    reselected_door = next(reselected_door)

    // 统计结果
    if(selected_door === goal_door)
    noswap_wins++
    if(swap_door === goal_door)
    swap_wins++
    if(reselected_door === goal_door)
    reselect_wins++
    }

    console.log("不交换:" + noswap_wins/loop + " / 交换:" + swap_wins/loop + " / 重新随机选:" + reselect_wins/loop)
    })()
    mm163
        31
    mm163  
       2022-10-03 16:03:18 +08:00
    其实就是一次机会 1/3 ,两次机会 2/3 ,该题实际给 2 次机会
    leafin
        32
    leafin  
       2022-10-03 16:03:42 +08:00
    @leafin 为什么我的空格没有了,这、
    Jooooooooo
        33
    Jooooooooo  
       2022-10-03 16:29:30 +08:00   ❤️ 1
    其实换门是等价于你直接一开始选两扇门, 那概率自然比不换选一扇门概率高.
    lifansama
        34
    lifansama  
       2022-10-03 19:51:54 +08:00 via Android
    主持人打开的门并不随机啊😂
    Leviathann
        35
    Leviathann  
       2022-10-03 20:16:46 +08:00
    开两次,对应 两种有+没有的情况 / 两种没有 + 有的情况 / 一种没有 + 没有的情况
    第一扇门开了没东西,其实消除了 两个 有 + 没有的情况,只剩下 没有 + 有 * 2 和 没有 + 没有 * 1
    也就是 2 / 3
    mongcici
        36
    mongcici  
       2022-10-03 23:11:43 +08:00
    @msg7086 谢谢耐心解答,我再好好想想看。
    Aloento
        37
    Aloento  
       2022-10-03 23:52:23 +08:00
    薛定饿了么 有讲这个概率问题
    Constantping
        38
    Constantping  
       2022-10-04 01:21:26 +08:00
    @mongcici 如果選擇不換,就只能選擇唯一正確的那扇( 1/3 )
    如果選擇換,就可以選擇錯誤的那兩扇門( 2/3 )
    callmesmc
        39
    callmesmc  
       2022-10-04 01:30:54 +08:00 via iPhone
    问题是主持人不是随机选的,是在剩下的门里面给排掉一个,如果换门,换的就是已经排掉一个的那一组,概率当然上升了
    nuk
        40
    nuk  
       2022-10-04 01:33:07 +08:00
    主持人的选择让另外那个门熵降低了,所以两个门的熵值显然不一样
    Allonsy
        41
    Allonsy  
       2022-10-04 07:02:22 +08:00
    基本概率论了,
    你选择了一门,然后主持人开了剩下两个门中无奖品的那个,你可以选择换或者不换门。
    这里重要的是第一个条件,你得先选一个门。
    如果你一开始不选,主持人帮你去掉了一个选项,那么你选择获胜的概率就是 1/2.
    如果你一开始选了,情况就不一样了,通俗一点来说,两个剩下的门打开一个,那么被打开的门的概率就塌缩到了剩下那个门,变成了 2/3.
    严谨的来说如下:
    你第一次选择的概率只有 1/3 ,但是当主持人打开一扇空门后,利用基本贝叶斯定理,能得出剩下那扇门的概率是 2/3.
    vAvyummyICE
        42
    vAvyummyICE  
       2022-10-04 08:13:11 +08:00 via Android
    对于观众来说,看到的是一个随机事件。也是抽奖先后顺序公平与否的问题(随机事件,主持人不知道哪一个是无奖门哪一个是有奖门)
    主持人概率:1/3
    你的概率(条件概率)是:2/3(有机会去选门的概率或者说主持人选到无奖的概率) 乘以 1/2(两个门选一个选对的概率) = 1/3


    但是对于你和主持人两个人来说,实际是独立事件
    因为规定主持人先选择且选无奖门,剩下的对于你而言也就是个随机事件了
    主持人选中有奖的概率是 0 ,无奖概率是 1
    你选中有奖的概率是自身的概率也就是在两个门中选一个的概率,即:1/2


    直白点就是 三个选项里只有一个正确答案,人为去除一个错误答案,剩下两个选项,那么你答对的概率就是 1/2 。

    第一个人点击在无奖门里随机一个,比如 0 ,1 是无奖门,随机一个数 0 或 1 ,然后排除这个留下一个。第二个人点击在剩下的两个数字里随机一个。
    无论第二个人点击结果是什么,第三个人也不用选了,直接给出剩下的结果。


    高中概率论
    qdwang
        43
    qdwang  
       2022-10-04 08:17:28 +08:00
    @Chad0000 你的解释最直观,感谢
    onevcat
        44
    onevcat  
       2022-10-04 08:50:34 +08:00
    ??条件概率不是必修课么..贝叶斯公式都还给老师了么 😂
    oldmyth
        45
    oldmyth  
       2022-10-04 16:58:56 +08:00
    @estk 三个可能你想不通,如果是一万个呢,给你一万个箱子,让你随机选了一个,然后主持人把其他不是的 9998 个都打开,最后一个问你换不换
    avenger
        46
    avenger  
       2022-10-05 13:57:44 +08:00
    原因很簡單 若一開始選到羊 再換則必得車 而一開始選到羊的機率是 2/3
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2800 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 03:17 · PVG 11:17 · LAX 19:17 · JFK 22:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.