• 三门问题-Swift测试


    三门问题(Monty Hall problem)亦称为蒙提霍尔问题、蒙特霍问题或蒙提霍尔悖论,大致出自美国的电视游戏节目Let's Make a Deal。问题名字来自该节目的主持人蒙提·霍尔(Monty Hall)。

    参赛者会看见三扇关闭了的门,其中一扇的后面有一辆汽车,选中后面有车的那扇门可赢得该汽车,另外两扇门后面则各藏有一只山羊。

    当参赛者选定了一扇门,但未去开启它的时候,节目主持人开启剩下两扇门的其中一扇,露出其中一只山羊。主持人其后会问参赛者要不要换另一扇仍然关上的门。

    问题是:换另一扇门是否会增加参赛者赢得汽车的机率?如果严格按照上述的条件,那么答案是会。不换门的话,赢得汽车的几率是1/3。换门的话,赢得汽车的几率是2/3。

    听着确实是挺反直觉的,但是自己写代码测试确实也是这样的。流言终结者也有一起视频做了证据。

    https://www.ixigua.com/7063739968274825735?id=7137582632111604231

    解释1:

    总共有三种可能的情况,全部都有相等的可能性(1/3):

    参赛者挑山羊一号(1/3),主持人挑山羊二号。转换将赢得汽车。

    参赛者挑山羊二号(1/3),主持人挑山羊一号。转换将赢得汽车。

    参赛者挑汽车(1/3),主持人挑羊一号。转换将失败。

    每种情况出现的概率都为1/3,所以切换策略最终赢得汽车的概率为2/3.

    还有一种思路,解释2:

    第一次选的空门(概率2/3),之后主持人开另一个空门,换门,得到汽车。

    第一次选的汽车(概率1/3),之后主持人开一个空门,换门,失败。

    1. import Foundation
    2. // 测试总次数
    3. let count = 100000
    4. func userPlayGame(strategy: Int) {
    5. var result: [(Int,Bool)] = []
    6. for i in 0 ..< count {
    7. let game = DoorGame()
    8. game.userStrategy = strategy
    9. let oneGameResult = game.startPlay()
    10. let item = (i,oneGameResult)
    11. result.append(item)
    12. }
    13. let winArray = result.filter { item in
    14. return item.1
    15. }
    16. let rate = Double(winArray.count) / Double(count)
    17. var str = ""
    18. if (strategy == 0) {
    19. str = "原选择"
    20. } else if (strategy == 1) {
    21. str = "切换"
    22. } else if (strategy == 2){
    23. str = "随机切换"
    24. }
    25. print("用户游玩\(count)次,使用\(str)策略,\(winArray.count)次胜利,胜率:\(rate)")
    26. // print("原始数据",result)
    27. }
    28. userPlayGame(strategy: 0)
    29. userPlayGame(strategy: 1)
    30. userPlayGame(strategy: 2)
    1. class DoorGame {
    2. // 用户策略
    3. // 0: 不改变选择
    4. // 1: 改变选择
    5. // 2: 50%改策略,50%不改
    6. var userStrategy = 0
    7. // 只是为了方便解释值的含义
    8. enum Strategy: Int {
    9. case notChange = 0 // 必定坚持原选择
    10. case change = 1 // 必定改变原选择
    11. case randomChange = 2 // 50%改变选择, 50%坚持原选择
    12. }
    13. enum DoorResult: Int {
    14. case sheepNotKnow = 0 // 门后是羊
    15. case car = 1 // 门后是车
    16. case sheepKnow = 2 // 主持人打开的门,必定是羊
    17. }
    18. func startPlay() -> Bool {
    19. // 生成3道门的数据
    20. var doorArray = self.buildRandomData()
    21. // 用户第一次选择
    22. var userSelect = self.userSelect()
    23. // 主持人排除一个错误答案, 剩余的结果
    24. doorArray = self.removeOneSheep(array: doorArray, userSelect: userSelect)
    25. // 根据用户策略决定是否转换
    26. if (self.userStrategy == 1) {
    27. userSelect = self.userChangeDoor(array: doorArray, userSelect: userSelect)
    28. } else if (self.userStrategy == 2) {
    29. let random = Int.random(in: 0 ..< 1000)
    30. if random % 2 == 0 {
    31. userSelect = self.userChangeDoor(array: doorArray, userSelect: userSelect)
    32. }
    33. }
    34. // 计算用户最终是否赢得车
    35. let result = self.showResult(array: doorArray, userSelect: userSelect)
    36. return result
    37. }
    38. /// 生成随机数据
    39. func buildRandomData() -> [Int] {
    40. var array = [0,0,0]
    41. let carIndex = Int.random(in: 0...2)
    42. array[carIndex] = 1
    43. return array
    44. }
    45. // 用户进行选择
    46. func userSelect() -> Int {
    47. let userSelect = Int.random(in: 0...2)
    48. return userSelect
    49. }
    50. // 主持人排除一个错误答案
    51. func removeOneSheep(array: [Int], userSelect: Int) -> [Int] {
    52. var result = array
    53. for (i,value) in array.enumerated() {
    54. if i == userSelect {
    55. continue
    56. } else {
    57. // 找到第一个是羊的门,变更成已知羊状态
    58. if value == 0 {
    59. result[i] = 2
    60. break
    61. }
    62. }
    63. }
    64. return result
    65. }
    66. // 用户改变自己的选择
    67. func userChangeDoor(array: [Int], userSelect: Int) -> Int {
    68. var result = -1
    69. // [2,1,0] 用户当前选中为1
    70. for (i,value) in array.enumerated() {
    71. if i == userSelect {
    72. continue
    73. } else {
    74. // 找到第一个是羊的门,移除这条数据
    75. if value == 2 {
    76. continue
    77. } else {
    78. result = i
    79. }
    80. }
    81. }
    82. assert(result != -1, "出错了")
    83. return result
    84. }
    85. /// 展示结果
    86. /// - Parameters:
    87. /// - Returns: true: 用户赢得车; false: 用户失败
    88. func showResult(array: [Int], userSelect: Int) -> Bool {
    89. let value = array[userSelect]
    90. if value == 1 {
    91. return true
    92. }
    93. return false
    94. }
    95. }

  • 相关阅读:
    基于Genio 700 (MT8390)芯片的AR智能眼镜方案
    【Mysql面试加分项】——Innodb的死锁检测机制【文末送书】
    算法常见知识点(持续更新)
    亚马逊,富士康,腾讯等大厂的3亿美元打水漂,Android之父公司宣布关闭
    Linux系统配置及服务管理-07-文件系统及RAID
    将本地代码提交到git新仓库
    uniapp 微信小程序 uni-file-picker上传图片报错 chooseAndUploadFile
    【Rust日报】2023-10-02 改进 Rust 宏中的自动完成功能
    打印不同商品价格(使用父类作为返回值实现打印不同类型商品价格)
    报错解决——AttributeError: ‘OpenpyxlWriter‘ object has no attribute ‘save‘
  • 原文地址:https://blog.csdn.net/u014600626/article/details/133236477