基于R语言实现动态更新概率的煎饼翻转模拟优化
R语言煎饼翻转模拟:添加现实化细节的实现
需求说明
基于已有的煎饼翻转模拟代码,需要新增两个贴近现实的规则:
- 连续未选中翻转的轮次每增加1,下一轮的选中概率降低0.01;一旦成功选中翻转,概率立即重置为初始值0.5
- 翻转时,煎饼落地朝向的概率与正反两面的累计煎制次数成比例:累计次数多的一侧更重,落地概率更高(例:累计heads=1、tails=3时,tails落地概率为3/(1+3)=0.75,heads为1/(1+3)=0.25)
修改后的完整代码
set.seed(123) # 总轮次 n <- 100 # 初始化变量 selected <- logical(n) current_result <- character(n) cumulative_heads <- integer(n) cumulative_tails <- integer(n) selection_prob <- 0.5 # 初始选中概率 unselected_streak <- 0 # 连续未选中次数 for (i in 1:n) { # 1. 决定是否选中翻转 selected[i] <- rbinom(1, 1, selection_prob) == 1 if (selected[i]) { # 选中翻转:重置选中概率和连续未选中次数 selection_prob <- 0.5 unselected_streak <- 0 # 2. 根据累计次数计算落地概率 total <- cumulative_heads[i-1] + cumulative_tails[i-1] # 处理初始累计为0的情况(第一轮选中的话,用0.5概率) if (total == 0) { heads_prob <- 0.5 } else { heads_prob <- cumulative_heads[i-1] / total } # 生成翻转结果 flip_result <- rbinom(1, 1, heads_prob) == 1 current_result[i] <- ifelse(flip_result, "heads", "tails") # 更新累计次数 cumulative_heads[i] <- cumulative_heads[i-1] + (flip_result == TRUE) cumulative_tails[i] <- cumulative_tails[i-1] + (flip_result == FALSE) } else { # 未选中翻转:更新选中概率和连续未选中次数 unselected_streak <- unselected_streak + 1 selection_prob <- max(0.5 - 0.01 * unselected_streak, 0) # 确保概率不低于0 # 保持当前朝向,累计对应次数 if (i == 1) { # 第一轮未选中,无历史朝向,标记为未选中 current_result[i] <- "not_selected" cumulative_heads[i] <- 0 cumulative_tails[i] <- 0 } else { # 沿用前一次的有效朝向 last_valid_idx <- max(which(current_result[1:(i-1)] != "not_selected")) last_valid_result <- current_result[last_valid_idx] current_result[i] <- "not_selected" cumulative_heads[i] <- cumulative_heads[i-1] + (last_valid_result == "heads") cumulative_tails[i] <- cumulative_tails[i-1] + (last_valid_result == "tails") } } } # 整理成数据框 df <- data.frame( turn_number = 1:n, selected = ifelse(selected, "yes", "no"), current_result = current_result, cumulative_heads = cumulative_heads, cumulative_tails = cumulative_tails ) # 补充前一次有效朝向列(与原代码结构对齐) df$most_recent_non_not_selected <- NA last_valid <- NA for (i in 1:n) { if (df$current_result[i] != "not_selected") { last_valid <- df$current_result[i] df$most_recent_non_not_selected[i] <- NA } else { df$most_recent_non_not_selected[i] <- last_valid } } df$merged_result <- ifelse(df$selected == "yes", df$current_result, df$most_recent_non_not_selected) # 查看前5行结果 head(df, 5)
关键功能实现说明
动态选中概率调整
- 用
unselected_streak跟踪连续未选中的轮次,每次未选中时,将selection_prob减去0.01,同时用max()确保概率不会低于0 - 一旦选中翻转,立即将
selection_prob重置为0.5,unselected_streak清零
- 用
比例化落地概率
- 选中翻转时,根据当前累计的heads和tails次数计算落地概率:
heads_prob = 累计heads / (累计heads + 累计tails) - 处理初始状态(累计次数均为0)的特殊情况,此时使用0.5的均等概率
- 用
rbinom()基于计算出的概率生成翻转结果
- 选中翻转时,根据当前累计的heads和tails次数计算落地概率:
示例输出
turn_number selected current_result cumulative_heads cumulative_tails most_recent_non_not_selected merged_result 1 1 no not_selected 0 0 <NA> <NA> 2 2 yes tails 0 1 <NA> tails 3 3 no not_selected 0 2 tails tails 4 4 yes heads 1 2 <NA> heads 5 5 yes tails 1 3 <NA> tails
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

