4

Here is the code for a random walk I made which I attempted to constrain where -5 < y < 5:

import random
import numpy as np
import matplotlib.pyplot as plt
import math
import decimal

def dirs(x):
  return np.array( [math.cos(x), math.sin(x)] )

def constrainedRandomWalk(x):
  numSteps = x
  locations = np.zeros( (numSteps, 2) ) 
  for i in range(1, numSteps):
    r = random.randrange(628318)/100000  
    move = dirs(r)        
    locations[i] = locations[i-1] + move
    if -5<locations[i][1]<5:
      continue
  #return locations

  plt.figure(figsize=(8,8))
  plt.plot( locations[:,0], locations[:,1], alpha=0.7 );
  plt.xlim([-20,20])
  plt.ylim([-20,20])

I attempted to constrain the "walking character" by setting a condition on the loop that

 if -5<locations[i][1]<5:
      continue

However, as you can see here, the character leaves the -5<y<5 region: Plot Generated From Random Walk

Can anyone let me know how to actually constrain the random walk and why this method doesn't work? Thank you!

Henry Ecker
  • 34,399
  • 18
  • 41
  • 57
BoyAcc
  • 193
  • 7
  • Well, your "if" statement does nothing. If the value is out of range, you continue the loop. Otherwise, you fall through and continue the loop. What do you want to happen if the walk goes out of bounds? You need to check the range BEFORE you add it to the points list. In that case, assigning `locations[i]` won't work, because you'll want to skip that point. So, make locations a list `locations = []` and then, only if the point passes your criteria `if -5 <= (locations[i-1]+move)[1] < 5:` do you add the new location to the list. – Tim Roberts Apr 26 '21 at 03:20

1 Answers1

3

You're updating locations before you test if the move is valid:

import math
import random

import matplotlib.pyplot as plt
import numpy as np


def dirs(x):
    return np.array([math.cos(x), math.sin(x)])


def constrained_random_walk(num_steps):
    # Specify Start Point
    locations = [np.array([0, 0])]
    # Go Until locations is long enough
    while len(locations) < num_steps:
        r = random.randrange(628318) / 100000
        move = dirs(r)
        # Test if the new move is in bounds first
        new_location = locations[-1] + move
        if -5 < new_location[1] < 5:
            locations.append(new_location)

    locations = np.array(locations)
    plt.figure(figsize=(8, 8))
    plt.plot(locations[:, 0], locations[:, 1], alpha=0.7)
    plt.xlim([-20, 20])
    plt.ylim([-20, 20])

Sample Output on:

constrained_random_walk(2000)

Sample Constrained Random Walk


Edit: Updated so all skipped values are not (0,0) but every value in locations is populated by a generated move. Except for the first, which is specified as the start point. (Currently (0,0))

Henry Ecker
  • 34,399
  • 18
  • 41
  • 57