2017-10-15 7 views
0

J'ai un problème de simulation de dés classique, que j'ai du mal à implémenter depuis que je suis nouveau avec la syntaxe R. La fonction (que j'ai appelé simu) fonctionne comme suit:Fonction pour le jeu de simulation en R

  1. Commencez avec 0 points
  2. Simuler n tirages au sort de trois dés à six faces
  3. Pour chaque tirage:
    • Si la somme de trois dés> 12 -> 1 points
    • Si la somme des trois dés < 6 -> -1 point
    • Dans le cas contraire (par exemple somme comprise entre 6 et 12):
      • Si trois dés ont même nombre -> +5 points
      • Sinon -> 0 points
  4. Retour Nombre total de points obtenus à la fin des simulations de n

Après avoir essayé un certain nombre de méthodes que je semble être assez proche avec:

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

Le problème semble être que je ne parviens pas à itérer de nouvelles simulations (pour a, b, c) pour chaque "i" de la fonction.

+1

Il ne semble pas qu'il y ait quelque chose de mal avec la fonction, vous êtes juste 'réinitialisez K' à zéro la plupart du temps, donc si vous appelez' simu (n) '' avec n> 1' les chances Est-ce que vous obtiendrez 'k <- 0'. N'est-ce pas que "Sinon 0 points" signifie "Sinon ajouter des points zéro"? –

+0

Vous avez raison - la dernière déclaration aurait dû être k <- k + 0. Merci. – Macter

Répondre

1

J'ai commenté la seule question que j'ai trouvé ... La dernière else qui a toujours Réinitialisez k à 0. Au contraire, il aurait dû être k <- k + 0 mais il ne change rien pour l'enlever.

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

Les résultats semblent assez bien:

> simu(1000) 
[1] 297 
> simu(100) 
[1] 38 
+1

Aussi, peut-être 'sample (6, 1)' fera-t-il, dans ce cas, c'est exactement le même et beaucoup plus simple et lisible. En prime, il n'y aurait pas besoin d'une variable supplémentaire «y». –

0

Je ne suis pas sûr que ce que vous avez besoin, mais vous pouvez essayer quelque chose comme ça:

# 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" 
            ) 
     ) 

enter image description here

1

Si vous allez utiliser R, alors vous devriez apprendre à créer des opérations vectorisées au lieu des boucles «for». Voici une simulation de 1 million de jets de dés qui ont pris moins d'une seconde à calculer. Je ne suis pas sûr combien de temps l'approche de la boucle «pour» aurait pris.

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