首页 > 解决方案 > For 循环,包括“if”和“while”,运行数小时

问题描述

我有一个 for 循环,包括为问题编写的“if”和“while”子句。它旨在在某些条件下进行 1000 次模拟。我认为这不是一个非常复杂的循环,但它已经运行了将近 16 个小时,没有显示结果或提示错误/警告(并且一直显示红色的小停止标志),我可以感觉到我的自从我开始运行循环以来,笔记本电脑的速度变慢了。

所以我想知道这是否真的会发生,或者我的代码或笔记本电脑是否有任何问题。任何帮助是极大的赞赏!!

请参阅下面的代码:

result.Vec <- NULL
for (trials in 1:1000) {
  sum <- 0
  sum2 <- 0
  n <- 0
  tmp1 <- sample(x=c(1, 2, 3, 4, 5, 6), size=1, replace=T, prob=c(1/6, 1/6, 1/6, 1/6, 1/6, 1/6)) 
  tmp2 <- sample(x=c(1, 2, 3, 4, 5, 6), size=1, replace=T, prob=c(1/6, 1/6, 1/6, 1/6, 1/6, 1/6)) 
  sum <- tmp1 + tmp2
  if (sum == 7 || sum == 11) {
    n <- 1
   } else if (sum == 2 || sum == 3 || sum == 12) {
    n <- 0
   } else {
     while (sum2 != sum || sum2 != 7) {
       tmp1 <- sample(x=c(1, 2, 3, 4, 5, 6), size=1, replace=T, prob=c(1/6, 1/6, 1/6, 1/6, 1/6, 1/6)) 
       tmp2 <- sample(x=c(1, 2, 3, 4, 5, 6), size=1, replace=T, prob=c(1/6, 1/6, 1/6, 1/6, 1/6, 1/6)) 
       sum2 <- tmp1 + tmp2
       if (sum2 == sum) {
         n <- 1
       } else if (sum2 == 7) {
         n <- 0
       }
     }
   }
  result.Vec <- c(result.Vec, n)
}

请参阅下面我的循环作为参考的问题(不是寻求解决此问题的方法): 骰子游戏掷骰子的玩法如下。玩家掷两个骰子,如果总和是 7 或 11,则她获胜。如果总和是二、三或十二,那么她就输了。如果总和是其他数字,那么她继续投掷,直到她再次投掷该数字(在这种情况下她赢)或她投掷 7(在这种情况下她输了)。根据 1000 次模拟计算玩家获胜的概率。

标签: rfor-loopif-statementwhile-loopsimulation

解决方案


首先,为了加快代码速度,您应该摆脱外部 for 循环。而是使用模拟一个游戏然后用于replicate运行游戏n时间的函数。

其次,用于break退出while循环。另外,请注意,命名变量是不明智的,sum因为已经有一个名为 的 R 函数sum

这是我的代码版本:

simulate_game <- function(){

  tmp1 <- sample(x = 1:6, size = 1) 
  tmp2 <- sample(x = 1:6, size = 1) 

  mysum <- tmp1 + tmp2

  if (mysum %in% c(7, 11)) {
    n <- 1
  } else if (mysum  %in% c(2, 3, 12)) {
    n <- 0
  } else {
    mysum2 <- 0

    while (! mysum2 %in% c(mysum, 7)) {
      tmp1 <- sample(x = 1:6, size = 1) 
      tmp2 <- sample(x = 1:6, size = 1) 

      mysum2 <- tmp1 + tmp2

      if (mysum2 == mysum) {
        n <- 1; break()
      } else if (mysum2 == 7) {
        n <- 0; break()
      }
    }
  }

  return(n)
}

现在您可以使用以下内容来模拟 1000 次运行:

set.seed(1)
table(replicate(1000, simulate_game()))
      0   1 
     530 470

请注意,我使用set.seed. 这使您的结果具有可重复性。


推荐阅读