Для цикла, включающего «if» и «while», работающего час - PullRequest
0 голосов
/ 16 мая 2019

У меня есть цикл 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)
}

Пожалуйста, см. Ниже вопрос, для которого мой цикл используется в качестве справочного (не ища решения этой проблемы): Игра в кости в кости играется следующим образом. Игрок бросает две кости, и если сумма составляет семь или одиннадцать, она выигрывает. Если сумма равна двум, трем или двенадцати, то она проигрывает. Если сумма является чем-то еще, то она продолжает бросать, пока она или бросает это число снова (в этом случае она выигрывает), или она бросает семерку (в этом случае она проигрывает). Рассчитайте вероятность того, что игрок выиграет, основываясь на 1000 симуляциях.

Ответы [ 3 ]

2 голосов
/ 16 мая 2019

сначала, чтобы ускорить код, вы должны избавиться от внешнего цикла 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. Это делает ваши результаты воспроизводимыми.

0 голосов
/ 16 мая 2019

Как я уже упоминал в комментарии, проблема заключается только в условии цикла while.Это должно быть AND вместо OR, иначе цикл while будет всегда терпеть неудачу.Я проверил это, и это работает:

result.Vec <- NULL
for (trials in 1:1000) {
  print(trials)
  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)
}
0 голосов
/ 16 мая 2019

Цикл while застревает:

while (sum2 != sum || sum2 != 7)

Если сумма! = 7 (то есть почти для любого возможного значения), это всегда будет иметь значение ИСТИНА.

...