pauld
pauld

Reputation: 421

Probability of returning to the origin for a 3 dimensional random walk

Here is my code simulating a code in python simulating a random walk in 3 dimensions. It returns a percentage of times the walk returns to the origin. Polya's constant was ~ 34% probability for a walk to return to the origin in 3 dimensions. My percentage is only 11-12%. If I multiply by three (as a guess) the answer becomes fairly close to Polya's constant but it looks closer to 36% most of the time. Please let me know what the error in my math, logic or coding for this problem is. Thanks in advance.

def r3walk(T):
x = np.zeros((T))
y = np.zeros((T))
z = np.zeros((T))
count = 0
for t in range(1,T):
    walk = random.uniform(0.0,1.0)
    if 0 < walk < 1/float(6):
        x[t] = x[t-1] + 1
    elif 1/float(6) < walk < 2/float(6):
        x[t] = x[t-1] - 1
    elif 2/float(6) < walk < 3/float(6):
        y[t] = y[t-1] + 1
    elif 3/float(6) < walk < 4/float(6):
        y[t] = y[t-1] - 1
    elif 4/float(6) < walk < 5/float(6):
        z[t] = z[t-1] + 1
    else: 
        z[t] = z[t-1] - 1
for t in range(1,T):
    if [x[t],y[t],z[t]] == [0,0,0]:
        count += 1
return count/float(T)

Edited Code:

def r32walk(T):
x = np.zeros((T))
y = np.zeros((T))
z = np.zeros((T))
count = 0
for t in range(1,T):
    walk1 = random.uniform(0.0,1.0)
    if walk1 > 0.5:
        x[t] = x[t-1] + 1
    else:
        x[t] = x[t-1] - 1
for t in range(1,T):
    walk2 = random.uniform(0.0,1.0)
    if walk2 > 0.5:
        y[t] = y[t-1] + 1
    else:
        y[t] = y[t-1] - 1
for t in range(1,T):
    walk3 = random.uniform(0.0,1.0)
    if walk3 > 0.5:
        z[t] = z[t-1] + 1
    else:
        z[t] = z[t-1] - 1
for t in range(1,T):
    if [x[t],y[t],z[t]] == [0,0,0]:
        count += 1
#return x,y,z
return count/float(T) * 100

Upvotes: 0

Views: 1541

Answers (1)

jonrsharpe
jonrsharpe

Reputation: 122061

I approached this as a Monte Carlo simulation problem; make a large number of random walks, and see what proportion return to the origin within some large number of steps. The easiest implementation is one function to do a single walk, and a second to do the repetition.

import random

def simulation(dimensions, repeats, steps):
    """Simulate probability of returning to the origin."""
    return sum(random_walk(dimensions, steps) 
               for _ in range(repeats)) / float(repeats)

def random_walk(n, s):
    """Whether an n-D random walk returns to the origin within s steps."""
    coords = [0 for _ in range(n)]
    for _ in range(s):
        coords[random.randrange(n)] += random.choice((1, -1))
        if not any(coords):
            return True
    return False

print [simulation(3, 100, 1000) for _ in range(10)]

The larger steps and repeats become (i.e. the closer we get to the "real" situation, all possible walks with an infinite number of steps), the less variability in the output I'd expect. For the numbers shown, I get:

[0.33, 0.36, 0.34, 0.35, 0.34, 0.29, 0.34, 0.28, 0.31, 0.36]

Upvotes: 2

Related Questions