Solved – Stochastic Process: On a chessboard a single random knight performs a simple random walk

markov-processstochastic-processes

On a chessboard a single random knight performs a simple random walk. From any square, the knight chooses from among its permissible moves with equal probability. If the knight starts on a corner, how long, on average, will it take to return to that corner?


I understand the question. I know that from the corner the knight has two choices of squares. From the two squares the piece has 5 directions (for each location), etc.

The thing is, I want to create a transition matrix for this Markov Chain. But I can't think of how to do this without each square representing a separate state..which would make is 64×64 transition matrix.

I'm certain I'm over-complicating this problem but does anyone have some advice on how to move forward? If I can create the transition matrix then I can make the corner an absorbing state and I'll be golden to move forward.

Best Answer

Yes, you can simulate it using a big transition matrix and roll it, while observing the cumulative probability of jumping back to the corner, an absorbing state. This is a Markov traverse on a graph with 64 nodes and a lot of sides, each representing allowed move of a knight on a board.

The average is suprisingly high: 168. This many steps in average is the length of the cycle in this graph when you start in the corner.

Here's the solution in Python:

import numpy as np

def jump(i,j):
   "true if jump is allowed"
   ret = (abs(i) == 2 and abs(j) == 1) or (abs(i) == 1 and abs(j) == 2)
   return ret

# init state after 1st jump
s1 = np.zeros(64) # state after 1st jump

for i in range(8):
    for j in range(8):
        if jump(i,j):
            s1[i*8 + j] = 1
s1 = s1 / np.sum(s1)
# print(np.reshape(s1,(8,8)))           

p = np.zeros((64,64)) # transition matrix, where state num k = 8 * i + j

# init tx matrix
for ki in range(8):
    for kj in range(8):
        k = ki*8 + kj
        for i in range(8):
            for j in range(8):
                if jump(ki-i,kj-j):
                    p[k, i*8 + j] = 1
        p[k, :] = p[k, :] / np.sum(p[k, :])
        # print(ki,kj,np.reshape(p[k,:],(8,8)))
p[0,:] = np.zeros(64)
p[0,0] = 1
# print(0,0,np.reshape(p[0,:],(8,8)))

steps = 10000
cumps = np.zeros(steps) # cumulative probability of each cycle length

s = s1
for step in range(2,steps):
    s = np.matmul(s, p)
    cumps[step] = s[0]
#    print(step, ps[step])
ps = np.diff(cumps) # probability of a step
print("check add up to 1: ",cumps[steps-1])
print("mean steps: ",np.dot(range(1,steps),ps))

import matplotlib.pyplot as plt

# plt.plot(range(1,1001), ps[0:1000])
plt.plot(range(1,1001), cumps[1:1001])
plt.xlabel("cycle length")
plt.ylabel("probability")
plt.title("CDF")
plt.show()

enter image description here

Related Question