明日方舟4周年出往期限定的概率

原理:

library(openxlsx)
# 设置随机数种子,使结果具有可重复性
set.seed(42)
# 明日方舟四周年池中,抽出六星干员的概率总和为2%
total_six_star_rate <- 0.02
# 43个六星干员中,缪尔赛斯和霍尔海雅为当期概率提升,这两位干员共同占六星出率的70%(二者出率一样)
up_rate <- 0.7
muelsis_rate <- total_six_star_rate * up_rate / 2
holhiya_rate <- muelsis_rate
# 剩余干员中,浊心斯卡蒂、归溟幽灵鲨、耀骑士临光为往期限定(此三者出率一样),在剩余干员中,抽出概率分别为其余干员的五倍(其余干员出率一样)
remaining_six_star_rate <- total_six_star_rate * (1 - up_rate)
limited_operator_num <- 3
remaining_operator_num <- 43 - 2 - limited_operator_num
# 计算剩余干员的总概率
remaining_operator_rate <- remaining_six_star_rate / (limited_operator_num * 5 + remaining_operator_num)
# 计算浊心斯卡蒂、归溟幽灵鲨、耀骑士临光的抽出概率
limited_operator_rate <- remaining_operator_rate * 5
# 定义模拟次数
n_simulations <- 1000000
# 设置循环抽卡次数
draw_nums <- seq(from = 10, to = 600, by = 10)
# 初始化保存结果的data.frame
results <- data.frame(Draws = draw_nums, Probability = rep(0, length(draw_nums)), Count = rep(0, length(draw_nums)))
# 进行模拟
for (k in 1:length(draw_nums)) {
successes <- 0
total_skadi_draw_num <- 0
cat("开始进行 ", draw_nums[k], " 次抽卡的模拟...\n")
for (i in 1:n_simulations) {
six_star_rate <- 0.02
consecutive_no_six_star <- 0
skadi_draw_num <- Inf
for (j in 1:draw_nums[k]) {
draw_result <- runif(1)
# 检查是否抽到六星干员
if (draw_result <= six_star_rate) {
consecutive_no_six_star <- 0
six_star_rate <- 0.02
# 检查是否抽到浊心斯卡蒂
if (runif(1) <= limited_operator_rate / total_six_star_rate) {
skadi_draw_num <- j
successes <- successes + 1
}
} else {
consecutive_no_six_star <- consecutive_no_six_star + 1
# 更新保底机制
if (consecutive_no_six_star >=50)
{
six_star_rate <- min(six_star_rate + 0.02, 1)
}
}
}
#将每次模拟抽到的浊心斯卡蒂数量累加到总数中
total_skadi_draw_num <- total_skadi_draw_num + min(skadi_draw_num, draw_nums[k])
#每模拟 10000 次,输出一次当前的模拟进度
if (i %% 10000 == 0) {
cat("当前正在模拟第 ", i, " 次...\n")
}
}
#计算概率和平均次数
prob_skadi_in_draws <- successes / n_simulations
avg_skadi_draw_num <- total_skadi_draw_num / successes
#将结果保存到results中
results[k, "Probability"] <- prob_skadi_in_draws
results[k, "Count"] <- successes
#输出当前模拟的结果
cat("在 ", draw_nums[k], " 次抽卡内抽到浊心斯卡蒂的概率为:", prob_skadi_in_draws * 100, "%,抽到 ", successes, " 个,平均需要抽 ", round(avg_skadi_draw_num, digits = 2), " 次。\n")
}
#将结果保存到Excel文件中
write.xlsx(results, "prob_skadi.xlsx", sheetName = "Results", row.names = FALSE)
#输出结果
cat("结果已保存到prob_skadi.xlsx文件中。")