Monte Carlo 基于列和的替换模拟
Monte Carlo Simulation with Replacement Based On Sum of A Column
我正在尝试使用 Monte Carlo 模拟来模拟电子游戏中不太可能出现的情况。我对编码非常陌生,我认为模拟这将是一个有趣的情况。
有3个目标,他们被独立攻击了8次。我的问题是当有 8 次攻击时,如何处理其中一列不能被攻击超过 6 次的事实。
我想采取任何针对第 2 列的攻击 select 随机攻击其他 2 列之一,但 只有当第 2 列已经被攻击 6 次时.
例如,这是我尝试模拟 5000 次重复。
#determine number of repeats
trial <- 5000
#create matrix with a row for each trial
m <- matrix(0, nrow = trial, ncol = 3)
#The first for loop is for each row
#The second for loop runs each attack independently, sampling 1:3 at random, then adding one to that position of the row.
#The function that is called by ifelse() when m[trial, 2] > 6 = TRUE is the issue.
for (trial in 1:trial){
for (attack in 1:8) {
target <- sample(1:3, 1)
m[trial, target] <- m[trial, target] + 1
ifelse(m[trial, 2] > 6, #determines if the value of column 2 is greater than 6 after each attack
function(m){
m[trial, 2] <- m[trial, 2] - 1 #subtract the value from the second column to return it to 6
newtarget <- sample(c(1,3), 1) #select either column 1 or 3 as a new target at random
m[trial, newtarget] <- m[trial, newtarget] + 1 #add 1 to indicate the new target has been selected
m}, #return the matrix after modification
m) #do nothing if the value of the second column is <= 6
}
}
例如,如果我有下面的矩阵:
> matrix(c(2,1,5,7,1,0), nrow = 2, ncol = 3)
[,1] [,2] [,3]
[1,] 2 5 1
[2,] 1 7 0
我希望函数查看矩阵的第 2 行,从 7 中减去 1,然后将 1 添加到第 1 列或第 3 列以创建 c(2,6,0) 或 c(1, 6,1). 我想了解如何在循环中执行此操作,但也可以在之后执行此操作。
我认为我在使用 function(x)
或 ifelse
时犯了严重的根本性错误。
谢谢。
这是您的代码的改进版本:
set.seed(1)
trial <- 5000
#create matrix with a row for each trial
m <- matrix(0, nrow = trial, ncol = 3)
#The first for loop is for each row
#The second for loop runs each attack independently, sampling 1:3 at random, then adding one to that position of the row.
#The function that is called by ifelse() when m[trial, 2] > 6 = TRUE is the issue.
for (i in 1:trial){
for (attack in 1:8) {
target <- sample(1:3, 1)
m[i, target] <- m[i, target] + 1
#determines if the value of column 2 is greater than 6 after each attack
if(m[i, 2] > 6){
#subtract the value from the second column to return it to 6
m[i, 2] <- m[i, 2] - 1
#select either column 1 or 3 as a new target at random
newtarget <- sample(c(1,3), 1)
#add 1 to indicate the new target has been selected
m[i, newtarget] <- m[i, newtarget] + 1
}
}
}
# Notice the largest value in column 2 is no greater than 6.
apply(m, 2, max)
set.seed
用于使结果可重现(通常只用于测试)。 ifelse
函数与普通的 if-else 控制流有不同的用途。这是一个例子:
x = runif(100)
ifelse(x < 0.5, 0, x)
您会注意到 x
中小于 0.5
的任何元素现在都为零。我将您的代码更改为具有 if
块。请注意 m[i, 2] > 6
returns 单个 TRUE
或 FALSE
而在上面的小示例中, x < 0.5
返回逻辑向量。所以 ifelse
可以采用逻辑向量,但是 if
块要求只有一个逻辑向量。
您使用 function
的方法是正确的,但在本例中没有必要。通常,但并非总是如此,您将定义这样的函数:
f = function(x)
x^2
但是仅仅返回值并不意味着你想要的改变了:
x = 5
f(5) # 25
x # still 5
有关此的更多信息,请查找 R 中的函数作用域。
最后,我将循环更改为 i in 1:trial
而不是 trial in 1:trial
。您可能不会注意到您的情况有任何问题,但最好使用单独的变量而不是构成循环范围的变量。
希望这对您有所帮助。
P.S。 R 在循环时的速度并不真正出名。如果你想让事情进展得更快,你通常需要向量化你的代码。
我正在尝试使用 Monte Carlo 模拟来模拟电子游戏中不太可能出现的情况。我对编码非常陌生,我认为模拟这将是一个有趣的情况。
有3个目标,他们被独立攻击了8次。我的问题是当有 8 次攻击时,如何处理其中一列不能被攻击超过 6 次的事实。
我想采取任何针对第 2 列的攻击 select 随机攻击其他 2 列之一,但 只有当第 2 列已经被攻击 6 次时.
例如,这是我尝试模拟 5000 次重复。
#determine number of repeats
trial <- 5000
#create matrix with a row for each trial
m <- matrix(0, nrow = trial, ncol = 3)
#The first for loop is for each row
#The second for loop runs each attack independently, sampling 1:3 at random, then adding one to that position of the row.
#The function that is called by ifelse() when m[trial, 2] > 6 = TRUE is the issue.
for (trial in 1:trial){
for (attack in 1:8) {
target <- sample(1:3, 1)
m[trial, target] <- m[trial, target] + 1
ifelse(m[trial, 2] > 6, #determines if the value of column 2 is greater than 6 after each attack
function(m){
m[trial, 2] <- m[trial, 2] - 1 #subtract the value from the second column to return it to 6
newtarget <- sample(c(1,3), 1) #select either column 1 or 3 as a new target at random
m[trial, newtarget] <- m[trial, newtarget] + 1 #add 1 to indicate the new target has been selected
m}, #return the matrix after modification
m) #do nothing if the value of the second column is <= 6
}
}
例如,如果我有下面的矩阵:
> matrix(c(2,1,5,7,1,0), nrow = 2, ncol = 3)
[,1] [,2] [,3]
[1,] 2 5 1
[2,] 1 7 0
我希望函数查看矩阵的第 2 行,从 7 中减去 1,然后将 1 添加到第 1 列或第 3 列以创建 c(2,6,0) 或 c(1, 6,1). 我想了解如何在循环中执行此操作,但也可以在之后执行此操作。
我认为我在使用 function(x)
或 ifelse
时犯了严重的根本性错误。
谢谢。
这是您的代码的改进版本:
set.seed(1)
trial <- 5000
#create matrix with a row for each trial
m <- matrix(0, nrow = trial, ncol = 3)
#The first for loop is for each row
#The second for loop runs each attack independently, sampling 1:3 at random, then adding one to that position of the row.
#The function that is called by ifelse() when m[trial, 2] > 6 = TRUE is the issue.
for (i in 1:trial){
for (attack in 1:8) {
target <- sample(1:3, 1)
m[i, target] <- m[i, target] + 1
#determines if the value of column 2 is greater than 6 after each attack
if(m[i, 2] > 6){
#subtract the value from the second column to return it to 6
m[i, 2] <- m[i, 2] - 1
#select either column 1 or 3 as a new target at random
newtarget <- sample(c(1,3), 1)
#add 1 to indicate the new target has been selected
m[i, newtarget] <- m[i, newtarget] + 1
}
}
}
# Notice the largest value in column 2 is no greater than 6.
apply(m, 2, max)
set.seed
用于使结果可重现(通常只用于测试)。 ifelse
函数与普通的 if-else 控制流有不同的用途。这是一个例子:
x = runif(100)
ifelse(x < 0.5, 0, x)
您会注意到 x
中小于 0.5
的任何元素现在都为零。我将您的代码更改为具有 if
块。请注意 m[i, 2] > 6
returns 单个 TRUE
或 FALSE
而在上面的小示例中, x < 0.5
返回逻辑向量。所以 ifelse
可以采用逻辑向量,但是 if
块要求只有一个逻辑向量。
您使用 function
的方法是正确的,但在本例中没有必要。通常,但并非总是如此,您将定义这样的函数:
f = function(x)
x^2
但是仅仅返回值并不意味着你想要的改变了:
x = 5
f(5) # 25
x # still 5
有关此的更多信息,请查找 R 中的函数作用域。
最后,我将循环更改为 i in 1:trial
而不是 trial in 1:trial
。您可能不会注意到您的情况有任何问题,但最好使用单独的变量而不是构成循环范围的变量。
希望这对您有所帮助。
P.S。 R 在循环时的速度并不真正出名。如果你想让事情进展得更快,你通常需要向量化你的代码。