Моделирование модели типа "случайного блуждания" на основе переменных вероятностей в R - PullRequest
2 голосов
/ 16 июня 2020

Я относительно новичок в программировании на R. Я хочу смоделировать движение одного человека по сетке 5x5, учитывая, что сетка различается в зависимости от условий окружающей среды и что перемещение от одной ячейки к другой основано на условиях окружающей среды. их ближайшие соседи. Окончательный результат этой симуляции, который я хочу, - это местоположение человека после x временных шагов.

Сначала я сделал фрейм данных, содержащий координаты x, y сетки и их условия окружающей среды. Затем я рассчитал сопротивление движению и его обратное значение на основе моих случайных условий окружающей среды (v1, v2).

  env_cond<-data.frame(x=rep(1:5,5),y=rep(1:5,each=5),v1=rnorm(25),v2=rnorm(25))
  env_cond$resistance<- res_surf<- (env_cond [1,3] - env_cond [,3])^2 + (env_cond [1,4]- env_cond [,4])^2
  env_cond$inv_res <- 1/env_cond$resistance #where movement is based on inverse resistance 
  env_cond$cell_num <- 1:25

  head (env_cond)
  x y           v1         v2 resistance   inv_res cell_num
1 1 1  1.233266019  0.3554372  0.0000000       Inf        1
2 2 1  0.499331993  0.3780565  0.5391708 1.8546999        2
3 3 1  1.633103368  0.7464020  0.3127234 3.1977142        3
4 4 1 -0.583125893  0.6591043  3.3914933 0.2948554        4
5 5 1  0.929743728 -0.7338991  1.2787793 0.7819958        5
6 1 2  0.009317203  0.2060074  1.5203800 0.6577303        6
> 

Затем я создал матрицу соседей. Я предполагаю, что человек может переехать только к своим 4 ближайшим соседям и никуда больше в сети. Он показывает номера ячеек сетки, которые соответствуют 4 непосредственным соседям ячейки. Например, ячейка 1 (которая соответствует x = 1, y = 1) дает NA для севера, потому что она не может перемещаться над пространством сетки.

    north <- ifelse (env_cond$y==1, NA, env_cond$cell_num-5) #y+1
    south <- ifelse (env_cond$y==5, NA, env_cond$cell_num+5) #y-1
    west <- ifelse (env_cond$x==1, NA, env_cond$cell_num-1) #x-1
    east <- ifelse (env_cond$x==5, NA, env_cond$cell_num+1) #x+1
    neighbours <- data.frame(north, south, west, east)
head (neighbours)
  north south west east
1    NA     6   NA    2
2    NA     7    1    3
3    NA     8    2    4
4    NA     9    3    5
5    NA    10    4   NA
6     1    11   NA    7
> 

Я создал матрицу вероятностей, сначала присвоив значения обратного сопротивления соседей номерам ячеек. Я заменил числовые значения на 0, чтобы проиллюстрировать невозможность движения, и любые значения для бесконечности произвольно на 10. Затем я преобразовал значения в вероятность:

   prob_mat <- cbind (env_cond$inv_res [neighbours$north], env_cond$inv_res [neighbours$south],env_cond$inv_res [neighbours$west], env_cond$inv_res [neighbours$east])
    colnames(prob_mat) <- c("y+1", "y-1", "x-1", "x+1") #renamed the columns of prob matrix 
  #changing NA to O
    prob_mat[is.na(prob_mat)]<-0
  #changing inf to 10
    prob_mat [6, 1] <- 10
    prob_mat [2, 3] <- 10
    prob_mat1 <- matrix (nrow = nrow(prob_mat), ncol=4)
    for (i in 1:nrow (prob_mat)) {
     prob_mat1 [i,]<- prob_mat[i,]/sum(prob_mat[i,])
head (prob_mat1)
          [,1]       [,2]      [,3]       [,4]
[1,] 0.0000000 0.26179048 0.0000000 0.73820952
[2,] 0.0000000 0.01556767 0.7459112 0.23852109
[3,] 0.0000000 0.06208574 0.8092602 0.12865408
[4,] 0.0000000 0.10119069 0.7221972 0.17661214
[5,] 0.0000000 0.39156264 0.6084374 0.00000000
[6,] 0.9246218 0.05608074 0.0000000 0.01929748

Эта матрица вероятностей показывает для каждого номера ячейки вероятность перемещения в соседнюю ячейку (без отображения номеров этих отдельных соседей). Отсюда я как бы застрял. Я не знаю, как на самом деле смоделировать движение человека из ячейки 1 (учитывая, что каждый выбор делается независимо от предыдущего шага, что-то вроде цепи Маркова, и где существуют разные вероятности движения в зависимости от вашего текущий шаг). Я подозреваю, что это как-то связано с индексированием, но я еще не понял, как управлять различными вероятностями для каждой ячейки. Это моя первая публикация здесь, так что, надеюсь, это имеет смысл / воспроизводимо. Любая помощь приветствуется!

1 Ответ

1 голос
/ 16 июня 2020

Лучшим способом, вероятно, было бы написать код для преобразования вашей матрицы в матрицу перехода 25x25 и использовать библиотеку цепей Маркова, но достаточно просто использовать вашу настройку как есть:

rand_walk <- function(start,steps){
  walk = numeric(steps)
  walker = start
  for(i in 1:steps){
    walk[i] <- walker
    walker <- walker + sample(c(-5,5,-1,1),1,prob = prob_mat1[walker,])
  }
  walk
}

Основная идея c заключается в том, что перемещение вверх или вниз - это прибавление или вычитание 5 из текущего номера ячейки, а перемещение вправо или влево - это прибавление или вычитание 1, поэтому достаточно выполнить выборку из вектора c(-5,5,-1,1) с вероятностями эти 4 шага, заданные соответствующей строкой матрицы вероятности.

Типичный результат:

> rand_walk(1,100)
  [1]  1  2  1  6  1  2  1  2  1  2  1  2  1  6  1  2  1  2  1  6  1  6
 [23]  1  6  1  2  1  2  3  8  9  8 13 12  7  8  7  8  3  8  7  8  7  8
 [45]  7  8  7  8  7  8  7  8  7  8  7 12 17 22 21 22 17 12  7 12  7  8
 [67]  3  8 13  8  7 12  7  8  9  8  9  8  7  6  7  8  7  2  1  6  1  2
 [89]  1  6  1  2  1  2  1  2  1  2  1  6

В этом коде я дал полный обход (который полезен для целей отладки), но вы можете конечно, полностью сбросить накапливающую матрицу walk и просто вернуть окончательную walker. Также обратите внимание, что в этом коде я записал steps позиций, поэтому только steps - 1 переходов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...