2017-10-15 98 views
0

我有一個經典的骰子模擬問題,我很努力實現,因爲我是新的R語法。函數(我稱之爲捷聯慣組)的工作原理如下:功能模擬遊戲在R

  1. 開始與0點
  2. 模擬n個隨機抽取的三頭六面的骰子
  3. 對於每個抽獎:
    • 如果總和的三個骰子> 12 - > 1點
    • 如果三個骰子總和< 6 - > -1點
    • 否則(即總和和6之間12):
      • 如果三個骰子具有相同數目的 - > 5點
      • 否則 - > 0分
  4. 返回以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)。

+1

它看起來並不有什麼不對的功能,你只是重置'k'爲零的大部分時間,因此,如果調用'捷聯慣組(N)'和'N> 1'賠率你會得到'k < - 0'。是不是「否則0點」意味着'否則添加零點? –

+0

你是對的 - 最後的陳述應該是k < - k + 0.謝謝。 – Macter

回答

1

我評論,我發現唯一的問題......最後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 
+1

此外,也許'樣本(6,1)'會做,在這種情況下,它是完全一樣的,更簡單和可讀。作爲獎勵,不需要額外的變量'y'。 –

0

我不知道這是你需要什麼,但你可以嘗試這樣的事情:

# 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

如果你將使用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