Home > other >  How to break a random walk at destination with R
How to break a random walk at destination with R

Time:12-03

I have to generate a random walk for a sequence of positions in 2D. The person doing the random walk starts at (0,0). At every move, she goes left, right, up or down. The random walk stops if she comes back to (0,0), or until she made a 1000 steps. *I am using the R language

I have done this so far, but I am having trouble figuring out how to stop the random walk when she reaches (0,0) again. I only get two vectors back. Any help would be very appreciated. Thank you!

step.max<-1000
destination<-rbind(c(0,0))

Random.walk <- function(n=step.max){
  steps <- matrix(c(0,0,-1,1,0,-1,1,0),nrow = 4)
  walk <- steps[sample(1:5,n,replace = TRUE)] 
  walk.1 <-rbind(walk)
  ifelse(destination,break,apply(walk.1,2,cumsum))
  }
Random.walk(n)

CodePudding user response:

Here is a fully vectorized function that will return a matrix of positions in the random walk. The matrix will have n 1 rows (it includes the original position at the origin) unless the walk returns to the origin.

walk2d <- function(n) {
  n1 <- n   1L
  m <- matrix(0L, n1, 2)
  m[2:n1   sample(c(0L, n1), n, 1)] <- sample(c(-1L, 1L), n, 1)
  m[,1] <- cumsum(m[,1])
  m[,2] <- cumsum(m[,2])
  i <- which.min(rowSums(abs(m[-1,])))
  if (i == 1L) m else m[1:(i   1L),]
}

A walk that returns to the origin on the 14th step:

set.seed(123)
walk2d(20L)
#>       [,1] [,2]
#>  [1,]    0    0
#>  [2,]   -1    0
#>  [3,]   -1   -1
#>  [4,]   -2   -1
#>  [5,]   -1   -1
#>  [6,]   -2   -1
#>  [7,]   -1   -1
#>  [8,]   -1    0
#>  [9,]   -1    1
#> [10,]   -2    1
#> [11,]   -2    0
#> [12,]   -1    0
#> [13,]   -1    1
#> [14,]    0    1
#> [15,]    0    0

A walk that does not return to the origin within n steps

set.seed(94)
walk2d(20L)
#>       [,1] [,2]
#>  [1,]    0    0
#>  [2,]    1    0
#>  [3,]    2    0
#>  [4,]    2    1
#>  [5,]    3    1
#>  [6,]    3    2
#>  [7,]    4    2
#>  [8,]    4    1
#>  [9,]    3    1
#> [10,]    2    1
#> [11,]    3    1
#> [12,]    4    1
#> [13,]    4    0
#> [14,]    4    1
#> [15,]    3    1
#> [16,]    4    1
#> [17,]    5    1
#> [18,]    6    1
#> [19,]    5    1
#> [20,]    4    1
#> [21,]    3    1

CodePudding user response:

If you want to stop when you reach the origin, you will have to use a loop. Alternatively you can generate a random walk of 1000 steps very quickly and identify when the origin was reached:

steps <- matrix(c(1, 0, -1, 0, 0, 1, 0, -1), nrow = 4, byrow=TRUE)
steps
#      [,1] [,2]
# [1,]    1    0  # Right
# [2,]   -1    0  # Left
# [3,]    0    1  # Up
# [4,]    0   -1  # Down

Now generate a random walk with 1000 steps:

set.seed(42)  # To create a reproducible example
rand <- sample.int(4, 1000, replace=TRUE)
moves <- steps[rand, ]         # 1000 random moves
position <- rbind(c(0, 0), apply(moves, 2, cumsum))  # Position after each move
home <- which(position[, 1] == 0 & position[, 2] == 0)  # When is position c(0, 0)?
home
# [1] 1   # We never revisit the origin in this random walk.

Now illustrate the results:

plot(position, type="l")
points(0, 0, cex=2, col="red")
points(position[1001, 1], position[1001, 2], cex=2, col="blue")

Random Walk

If you want break out of the walk when the position returns to c(0, 0), you will need a loop. Something like this:

steps <- matrix(c(1, 0, -1, 0, 0, 1, 0, -1), nrow = 4, byrow=TRUE)
position <- rbind(c(0, 0))
move <- 0
for (move in 2:1001) {  
    step <- steps[sample.int(4, 1), ]
    position <- rbind(position,  position[move-1, ]   step)
    if (position[move, 1] == 0 & position[move, 2] == 0) break
}
cat("move=", move, "position=", position[move, ], "\n")

The position variable will contain all of the locations visited during the walk.

  • Related