You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写R函数模拟硬币翻转游戏,计算10万次模拟的期望收益

问题描述

游戏规则为:反复抛掷公平硬币,直到正面(heads)与反面(tails)的数量差达到3时停止;最终可获得8美元,但每次抛掷需支付1美元。需要通过100000次模拟计算期望收益。现有单局游戏的R代码,但运行10万次时效率极低,需改写为高效计算10万次游戏期望收益的函数。

原单局代码:

# 单局游戏示例
# 游戏次数
n_games <- 1 
bias <- 0.5
game_payoff <- c()

for (i in seq_len(n_games)) {
  
  cost <- 0
  flip_record <- c()
  payoff <- c()
  
  repeat{
    cost <- cost + 1
    flip <- rbinom(1, 1, prob = bias)
    flip_record <- c(flip_record, flip)
    # 反面(0)的数量
    n_tails <- length(flip_record) - sum(flip_record) 
    # 正面(1)的数量
    n_heads <- sum(flip_record) 
    
    if (abs(n_tails - n_heads) == 3) {
      # 记录本局收益
      game_payoff <- c(game_payoff, 8 - cost)
      # 打印本局收益
      print(paste0("单局收益: ", 8 - cost)) 
      break
    }
  }
}
优化后的高效模拟函数
simulate_game <- function(n_games, bias = 0.5) {
  # 预分配收益结果向量,避免动态扩容的性能损耗
  payoffs <- numeric(n_games)
  
  for (i in seq_len(n_games)) {
    # 跟踪正反面数量差:正面+1,反面-1
    diff <- 0
    cost <- 0
    
    repeat {
      cost <- cost + 1
      # 单次抛掷,直接更新差值
      diff <- diff + sample(c(1, -1), 1, prob = c(bias, 1 - bias))
      
      # 差值达到±3时停止本局
      if (abs(diff) == 3) {
        payoffs[i] <- 8 - cost
        break
      }
    }
  }
  
  # 返回所有游戏的期望收益
  mean(payoffs)
}

# 执行10万次模拟
expected_payoff <- simulate_game(100000)
cat("模拟得到的期望收益为:", expected_payoff, "美元\n")
核心优化说明
  • 预分配内存:原代码中game_payoff <- c(game_payoff, ...)每次都会重新分配并复制向量,10万次操作会产生巨大的性能开销。优化后直接创建固定长度的numeric(n_games),内存使用更高效。
  • 简化状态跟踪:原代码保存所有抛掷记录并反复计算正反面数量,完全没必要。直接跟踪正反面的数量差diff,每次抛掷后更新差值,大幅减少计算量。
  • 简化抛掷逻辑:用sample(c(1,-1))直接表示正面(+1)和反面(-1),一步到位更新差值,比rbinom生成0/1后再计算差值的流程更简洁高效。
  • 移除冗余操作:原代码的打印操作在10万次模拟中会严重拖慢速度,优化后仅在最后输出最终的期望收益结果。

内容的提问来源于stack exchange,提问作者user14428298

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 12:20:33