Search code examples
pythonmatplotlibrandom-walk

Constraining a Random Walk in python, how to make it work?


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!


Solution

  • 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))