4

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
} 
4

3 に答える 3

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
于 2013-04-29T16:34:35.717 に答える
3

再帰関数を使用して、ゲームをシミュレートするもう 1 つの興味深い方法を次に示します。

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

sampleエレガントではありますが、@ Viktor によって提案されているように、 を 1 回呼び出す @Simonのソリューションの改良版ほど高速ではありません。

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

最終的な目標 (ゲーム全体で 1 人がリードする確率を見つける) については、より効率的かどうかについて議論の余地がありwhileます。リードはあるプレーヤーから別のプレーヤーに切り替わります。どちらのアプローチもテストする価値があります。

于 2013-04-29T17:40:13.447 に答える