R中模拟游戏的功能
Function for simulation game in R
我有一个经典的骰子模拟问题,由于我是 R 语法的新手,所以我很难实现它。该函数(我称之为 simu)的工作原理如下:
- 从 0 分开始
- 模拟 n 次随机抽取三个六面骰子
- 每次开奖:
- 如果三个骰子的总和 >12 --> +1 点
- 如果三个骰子的总和 <6 --> -1 点
- 否则(即 6 和 12 之间的总和):
- 如果三个骰子点数相同 --> +5 分
- 否则 --> 0 分
- Return n 次模拟结束时获得的总点数
尝试了多种不同的方法后,我似乎非常接近:
simu <- function(n){
k <- 0
for(i in 1:n) {
a <- sample(y,1,replace=TRUE)
b <- sample(y,1,replace=TRUE)
c <- sample(y,1,replace=TRUE)
if ((a + b + c) > 12) {
k <- k+1
} else if ((a + b + c) < 6) {
k <- k-1
} else if ((a == b) & (b == c)) {
k <- k+5
} else k <- 0
}
return(k)
}
问题似乎是我无法为函数中的每个 "i" 迭代新的模拟(对于 a、b、c)。
我已经评论了我发现的唯一问题...最后一个 else
总是将 k
重新初始化为 0。相反,它应该是 k <- k + 0
但确实如此不更改任何内容以将其删除。
y <- seq(1,6) # 6-sided dice
simu <- function(n){
k <- 0
for(i in 1:n) {
a <- sample(y,1,replace=TRUE)
b <- sample(y,1,replace=TRUE)
c <- sample(y,1,replace=TRUE)
if ((a + b + c) > 12) {
k <- k+1
} else if ((a + b + c) < 6) {
k <- k-1
} else if ((a == b) & (b == c)) {
k <- k+5
} #else k <- 0
}
return(k)
}
结果看起来相当不错:
> simu(1000)
[1] 297
> simu(100)
[1] 38
我不确定这是否是您需要的,但您可以尝试类似的操作:
# Draw the dice(s) - returns vector of length == n_dices
draw <- function(sides = 6, dices = 3){
sample(1:sides, dices, replace = T)
}
# test simulation x and return -1, 0, 1, 1 or 5
test <- function(x){
(sum(x) > 12)*1 + (sum(x) < 6)*(-1) + (sum(x) >= 6 &
sum(x) <= 12 &
var(x) == 0)*5
}
# simulate n draws of x dices with y sides
simu <- function(sides = 6, dices = 3, n = 100){
sum(replicate(n, test(draw(sides, dices))))
}
# run simulations of 100 draws for 1, 2, ..., 11, 12-side dices (3 dices each simulation)
dt <- lapply(1:12, function(side) replicate(100, simu(side, 3, 100)))
# plot dicstribution of scores
par(mfrow = c(3,4))
lapply(1:length(dt), function(i) hist(dt[[i]],
main = sprintf("%i sides dice", i),
xlab = "Score"
)
)
如果您打算使用 R,那么您应该学习创建矢量化操作而不是 'for' 循环。这是对 100 万次掷骰子的模拟,计算时间不到 1 秒。我不确定 'for' 循环方法需要多长时间。
n <- 1000000 # trials
start <- proc.time() # time how long it takes
result <- matrix(0L, ncol = 6, nrow = n)
colnames(result) <- c('d1', 'd2', 'd3', 'sum', 'same', 'total')
# initial the roll of three dice
result[, 1:3] <- sample(6L, n * 3L, replace = TRUE)
# compute row sum
result[, 'sum'] <- as.integer(rowSums(result[, 1:3]))
# check for being the same
result[, 'same'] <- result[,1L] == result[, 2L] & result[, 2L] == result[, 3L]
result[, 'total'] <- ifelse(result[, 'sum'] > 12L,
1L,
ifelse(result[, 'sum'] < 6L,
-1L,
ifelse(result[, 'same'] == 1L,
5L,
0L
)
)
)
table(result[, 'total'])
-1 0 1 5
46384 680762 259083 13771
cat("simulation took:", proc.time() - start, '\n')
simulation took: 0.7 0.1 0.8 NA NA
我有一个经典的骰子模拟问题,由于我是 R 语法的新手,所以我很难实现它。该函数(我称之为 simu)的工作原理如下:
- 从 0 分开始
- 模拟 n 次随机抽取三个六面骰子
- 每次开奖:
- 如果三个骰子的总和 >12 --> +1 点
- 如果三个骰子的总和 <6 --> -1 点
- 否则(即 6 和 12 之间的总和):
- 如果三个骰子点数相同 --> +5 分
- 否则 --> 0 分
- Return n 次模拟结束时获得的总点数
尝试了多种不同的方法后,我似乎非常接近:
simu <- function(n){
k <- 0
for(i in 1:n) {
a <- sample(y,1,replace=TRUE)
b <- sample(y,1,replace=TRUE)
c <- sample(y,1,replace=TRUE)
if ((a + b + c) > 12) {
k <- k+1
} else if ((a + b + c) < 6) {
k <- k-1
} else if ((a == b) & (b == c)) {
k <- k+5
} else k <- 0
}
return(k)
}
问题似乎是我无法为函数中的每个 "i" 迭代新的模拟(对于 a、b、c)。
我已经评论了我发现的唯一问题...最后一个 else
总是将 k
重新初始化为 0。相反,它应该是 k <- k + 0
但确实如此不更改任何内容以将其删除。
y <- seq(1,6) # 6-sided dice
simu <- function(n){
k <- 0
for(i in 1:n) {
a <- sample(y,1,replace=TRUE)
b <- sample(y,1,replace=TRUE)
c <- sample(y,1,replace=TRUE)
if ((a + b + c) > 12) {
k <- k+1
} else if ((a + b + c) < 6) {
k <- k-1
} else if ((a == b) & (b == c)) {
k <- k+5
} #else k <- 0
}
return(k)
}
结果看起来相当不错:
> simu(1000)
[1] 297
> simu(100)
[1] 38
我不确定这是否是您需要的,但您可以尝试类似的操作:
# Draw the dice(s) - returns vector of length == n_dices
draw <- function(sides = 6, dices = 3){
sample(1:sides, dices, replace = T)
}
# test simulation x and return -1, 0, 1, 1 or 5
test <- function(x){
(sum(x) > 12)*1 + (sum(x) < 6)*(-1) + (sum(x) >= 6 &
sum(x) <= 12 &
var(x) == 0)*5
}
# simulate n draws of x dices with y sides
simu <- function(sides = 6, dices = 3, n = 100){
sum(replicate(n, test(draw(sides, dices))))
}
# run simulations of 100 draws for 1, 2, ..., 11, 12-side dices (3 dices each simulation)
dt <- lapply(1:12, function(side) replicate(100, simu(side, 3, 100)))
# plot dicstribution of scores
par(mfrow = c(3,4))
lapply(1:length(dt), function(i) hist(dt[[i]],
main = sprintf("%i sides dice", i),
xlab = "Score"
)
)
如果您打算使用 R,那么您应该学习创建矢量化操作而不是 'for' 循环。这是对 100 万次掷骰子的模拟,计算时间不到 1 秒。我不确定 'for' 循环方法需要多长时间。
n <- 1000000 # trials
start <- proc.time() # time how long it takes
result <- matrix(0L, ncol = 6, nrow = n)
colnames(result) <- c('d1', 'd2', 'd3', 'sum', 'same', 'total')
# initial the roll of three dice
result[, 1:3] <- sample(6L, n * 3L, replace = TRUE)
# compute row sum
result[, 'sum'] <- as.integer(rowSums(result[, 1:3]))
# check for being the same
result[, 'same'] <- result[,1L] == result[, 2L] & result[, 2L] == result[, 3L]
result[, 'total'] <- ifelse(result[, 'sum'] > 12L,
1L,
ifelse(result[, 'sum'] < 6L,
-1L,
ifelse(result[, 'same'] == 1L,
5L,
0L
)
)
)
table(result[, 'total'])
-1 0 1 5
46384 680762 259083 13771
cat("simulation took:", proc.time() - start, '\n')
simulation took: 0.7 0.1 0.8 NA NA