我正在尝试模拟一个简单的游戏,你旋转一个标记为1-5的微调器,然后继续前进,直到你通过终点线(点50)。我对R有点新意,并且一直在寻找答案。当我运行下面的代码时,它不会按顺序添加数字,它会返回我的50个随机旋转及其值的列表。如何让它在彼此之上添加旋转,然后停止一次=> 50?
SpacesOnSpinner<-(seq(1,5,by=1))
N<-50
L1<-integer(N)
for (i in 1:N){
takeaspin<-sample(SpacesOnSpinner,1,replace=TRUE)
L1[i]<-L1[i]+takeaspin
}
答案 0 :(得分:4)
这是replicate
的一个很好的用例。我不确定你是否必须使用for
循环,但你可以这样做(replicate
也是循环):
SpacesOnSpinner<-(seq(1,5,by=1))
N<-10
cumsum( replicate( N , sample(SpacesOnSpinner,1,replace=TRUE) ) )
#[1] 5 10 14 19 22 25 27 29 30 33
但是,由于你有条件要break
开启,或许while
条件的其他答案正是你在这种情况下所需要的(人们会告诉你他们不好R,但它们有它们的用途)。使用这种方法,您可以看到之后通过一个简单的子集花了多少次旋转超过50(但您不会事先知道需要多少次旋转,但在大多数它将是50):
N<-50
x <- cumsum( replicate( N , sample(5,1) ) )
# Value of accumulator at each round until <= 50
x[ x < 50 ]
#[1] 5 6 7 8 12 16 21 24 25 29 33 34 36 38 39 41 42 44 45 49
# Number of spins before total <= 50
length(x[x < 50])
[1] 20
答案 1 :(得分:3)
这是使用递归函数模拟游戏的另一种有趣方式。
spin <- function(outcomes = 1:5, start = 0L, end = 50L)
if (start <= end)
c(got <- sample(outcomes, 1), Recall(outcomes, start + got, end))
spin()
# [1] 5 4 4 5 1 5 3 2 3 4 4 1 5 4 3
虽然很优雅,但它不会像@ Simon的解决方案一样快,只需拨打sample
,就像@Viktor所建议的那样:
spin <- function(outcomes = 1:5, end = 50L) {
max.spins <- ceiling(end / min(outcomes))
x <- sample(outcomes, max.spins, replace = TRUE)
head(x, match(TRUE, cumsum(x) >= end))
}
spin()
# [1] 3 5 2 3 5 2 2 5 1 2 1 5 5 5 2 4
为了你的最终目标(找到一个人在整个游戏中处于领先地位的概率),while
是否会更有效率是有争议的:一个while循环肯定是比较慢,但是当领先者从一个玩家切换到另一个玩家时,你可能会受益于早退出的可能性。这两种方法都值得测试。
答案 2 :(得分:2)
您可以使用while语句和变量 total 来跟踪总和:
total <- 0
while(total <= 50){
takeaspin<-sample(SpacesOnSpinner,1,replace=TRUE)
total <- takeaspin + total
}
print (total)