Monday, September 23, 2019

Random Walks

A random walk is a path that has no clear direction but is determined by a series of random decisions, each of which is left entirely to chance. You might imagine a random walk as the path a confused ant would take if it took every step in a random direction. Random walks have practical applications in nature, physics, biology, chemistry, and economics. For example, a pollen grain floating on a drop of water moves across the surface of the water because it’s constantly pushed around by water molecules. Molecular motion in a water drop is random, so the path a pollen grain traces on the surface is a random walk.

In this post, we’ll use Python to generate data for a random walk, and then use Matplotlib to create a visually appealing representation of that data. We’ll create a RandomWalk class, which will make random decisions about which direction the walk should take. See the following code:

class RandomWalk:
   
    def __init__(self, num_points=5000):
        """Initialize attributes of a walk."""
        self.num_points = num_points
       
        """All walks start at (0,0)"""
        self.x_values = [0]
        self.y_values = [0]



def fill_walk(self):
        """Calculate all the points in the walk."""
       
        # Keep taking steps until the walk reaches the desired length.
        while len(self.x_values)<self.num_points :
            # Decide which direction to go and how far to go in that direction.
            x_direction = choice([1,-1])
            x_distance = choice([0, 1, 2, 3, 4])
            x_step = x_direction * x_distance
           
            y_direction = choice([1,-1])
            y_distance = choice([0, 1, 2, 3, 4])
            y_step = y_direction * y_distance
           
            # Reject moves that go nowhere.
            if x_step==0 and y_step ==0:
                continue
           
            # Calculate the new position.
            x=self.x_values[-1]+ x_step
            y=self.y_values[-1]+y_step
           
            self.x_values.append(x)
            self.y_values.append(y) 
  
       
The class needs three attributes: one variable to store the number of points in the walk and two lists to store the x- and y-coordinate values of each point in the walk. We require two methods for the RandomWalk class: the __init__() method and fill_walk(), which will calculate the points in the walk. To make random decisions, we’ll store possible moves in a list and use the choice() function, from the random module, to decide which move to make each time a step is taken. Thus we need to use the following import from random import choice.

To get the next x-value for the walk, we add the value in x_step to the last value stored in x_values and do the same for the y-values. When we have these values, we append them to x_values and y_values.


In the init() we set the default number of points in a walk to 5000, which is large enough to generate some interesting patterns but small enough to generate walks quickly. Then we make two lists to hold the x- and y-values, and we start each walk at the point (0, 0).

The fill_walk() method is used to fill our walk with points and determine the direction of each step. We set up a while loop that runs until the walk is filled with the correct number of points. The main part of the fill_walk() method tells Python how to simulate four random decisions: will the walk go right or left? How far will it go in that direction? Will it go up or down? How far will it go in that direction?

We use choice([1, -1]) to choose a value for x_direction, which returns either 1 for right movement or −1 for left. Next, choice([0, 1, 2, 3, 4]) tells Python how far to move in that direction (x_distance) by randomly selecting an integer between 0 and 4. (The inclusion of a 0 allows us to take steps along the y-axis as well as steps that have movement along both axes.)

Next we determine the length of each step in the x and y directions by multiplying the direction of movement by the distance chosen. A positive result for x_step means move right, a negative result means move left, and 0 means move vertically. A positive result for y_step means move up, negative means move down, and 0 means move horizontally. If the value of both x_step and y_step are 0, the walk doesn’t go anywhere, so we continue the loop to ignore this move.

Now we'll plot the random walk. See the program below:

import matplotlib.pyplot as plt
from randomwalk import RandomWalk

# Make a random walk.
rw = RandomWalk()
rw.fill_walk()

# Plot the points in the walk.
plt.style.use('classic')
fig, ax = plt.subplots()
ax.scatter(rw.x_values, rw.y_values, s=15)
plt.show()


We begin by importing pyplot and RandomWalk. We then create a random walk and store it in rw, making sure to call fill_walk(). Then we feed the walk’s x- and y-values to scatter() and choose an appropriate dot size.

Figure below shows the resulting plot with 5000 points:
 Now we'll generate multiple random walks. One way to use the preceding code to make multiple walks without having to run the program several times is to wrap it in a while loop, as shown in the following code:

import matplotlib.pyplot as plt
from randomwalk import RandomWalk

# Keep making new walks, as long as the program is active.
while True:
    # Make a random walk.
    rw = RandomWalk()
    rw.fill_walk()

    # Plot the points in the walk.
    plt.style.use('classic')
    fig, ax = plt.subplots()
    ax.scatter(rw.x_values, rw.y_values, s=15)
    plt.show()
   
    keep_running = input("Make another walk? (y/n): ")
    if keep_running == 'n':
        break

   
Our program generates a random walk, displays it in Matplotlib’s viewer, and pauses with the viewer open. When you close the viewer, you’ll be asked whether you want to generate another walk. Press y to generate walks that stay near the starting point, that wander off mostly in one direction, that have thin sections connecting larger groups of points, and so on. When you want to end the program, press n.

The following are the outputs we receive when we run the program:



The command window will look like:

Make another walk? (y/n): y
Make another walk? (y/n): y
Make another walk? (y/n): n

------------------
(program exited with code: 0)

Press any key to continue . . .

Here I am ending today's post. In the next post we’ll customize our plots to emphasize the important characteristics of each walk and de-emphasize distracting elements.






Share:

0 comments:

Post a Comment