An Efficient Algorithm for the Knight's Tour Problem Chessboard


An Efficient Algorithm for the Knight's Tour Problem Chessboard
http://community.topcoder.com/stat?c=problem_statement&pm=3509&rd=6528

Given the size of the chess board and initial position of the knight, what is the probability that after k moves the knight will be inside the chess board.
Note:-
1) The knight makes its all 8 possible moves with equal probability.
2) Once the knight is outside the chess board it cannot come back inside.
knight_moves
https://www.quora.com/Given-the-position-x-y-of-a-knight-on-an-8X8-chess-board-what-is-the-probability-that-it-stays-within-the-chess-board-after-n-moves
Base cases:
There are 2 possible base cases:
  1. If the position (x,y) is outside the board, then the probability that it is within the board is 0. So we just 
    return 0;
     in this case
  2. If step == 0, then we have no more moves left. In this case if the passed parameter (x,y) is within the board, then we 
    return 1;
FindProbability(x, y, step) = 8i=1( FindProbability(next_x, next_y, step-1) ) / 8.0
where next_x, next_y are the possible next positions of the knight at position (x,y).

Memoization:
There are a lot of overlapping computations in the above recursion. There might be numerous calls to  the function 
FindProbability
 with the same parameters. In order to prevent recomputing these values again and again, we can simply cache the computed values every time we find them and just return this value for subsequent function calls with the same parameters.

For this, a 3D array 
double 
memo
[
8
][
8
][
MAX_MOVES
]
 is maintained, and the computed values are stored in the array.


Algorithm:
Start with the initial coordinates of the knight. Make all possible moves for this position and multiply these moves with their probability, for each move recursively call the function continue this process till the terminating condition is met. Terminating condition is if the knight is outside the chess board, in this case return 0, or the desired number of moves is exhausted, in this case return 1.

As we can see that the current state of the recursion is dependent only on the current coordinates and number of steps done so far. Therefore we can memoize this information in a tabular form.

Expected time complexity:
O((n ^ 2) * k) where n is the size of the board and k is the number of moves.
Expected space complexity:
O((n ^ 2) * k) where n is the size of the board and k is the number of moves.
#define MAXSIZE 100
#define MAXK 100
 
double dp[MAXSIZE][MAXSIZE][MAXK];
int vis[MAXSIZE][MAXSIZE][MAXK]; //stores 1 if there is a corresponding dp entry, 0 otherwise
 
double prob_knight(int x, int y, int size, int step, int k)
{
    //if knight is outside the board
    if(x < 0 || y < 0 || x >= size || y >= size) return 0;
    //if all moves are exhausted
    if(step == k) return 1;
 
    //if dp table has the this value stored return it
    if(vis[x][y][k] != 0)
        return dp[x][y][k];
 
    vis[x][y][step] = 1;
 
    //all possible x direction's for knight to move
    int dirx[] = {2, 2, -2, -2, 1, 1, -1, -1};
    //corresponding y direction for knight
    int diry[] = {1, -1, 1, -1, 2, -2, 2, -2};
 
    double ans = 0;
    for(int i = 0;i < 8; ++i){
        //knight makes the next move with probability (1 / 8)
        ans = ans + ((double)1 / (double)8) * prob_knight(x + dirx[i], y + diry[i], size, step + 1, k);
    }
 
    //update the dp table
    dp[x][y][k] = ans;
 
    return ans;
}
http://community.topcoder.com/tc?module=Static&d1=match_editorials&d2=tccc05_online_rd_1#3509
The idea is to keep track for each number of moves the probability that the knight will be on a certain square. Initially the probability is 1 (100%) that it will be on the start square and 0 on all other squares. After one move, the probability is 0.125 that it will be on any of the eight squares a knight distance away from the start, and 0 on all the other squares. If any of these 8 squares is outside the board, it's simply ignored - it doesn't affect the probability for any of the other squares.
Generally, the probability that the knight will be on a certain square after n moves is the sum of the probabilities of it being on the 8 squares a knight distance away after n - 1 moves, divided by 8 (this is basic probability math). By first determining the probability of the knight being on all 64 squares after 1 move, then 2 moves etc, we get an efficient algorithm:
for(int i=1; i<=n; i++) // n = number of moves we want the answer for
    for(int x=0; x<8; x++)
        for(int y=0; y<8; y++) {
            double prob = 0.0;
            for(int d=0; d<8; d++) {
                if (x+dx[d] >= 0 && x+dx[d] < 8 &&
                    y+dy[d] >= 0 && y+dy[d] < 8)
                    prob += boardprob[i-1][y+dy[d]][x+dx[d]] / 8.0;
            }
            boardprob[i][y][x] = prob;
        }

The answer is then simply the sum of the knight being on the 64 squares after n moves.
https://github.com/livingstonese/topcoder/blob/master/src/main/java/tccc05/round1/ChessKnight.java

public class ChessKnight { private static final int MAX_N = 101;
private static final int MAX_DIM = 9;
double[][][] dp = new double[MAX_N][MAX_DIM][MAX_DIM];
public double probability(int x, int y, int n) {
for (int i = 0; i < MAX_DIM; i++) {
Arrays.fill(dp[0][i], 1.0);
}
int[] dx = {-2, -2, -1, -1, 1, 1, 2, 2};
int[] dy = {1, -1, 2, -2, 2, -2, 1, -1};
for (int curN = 1; curN <= n; curN++) {
for (int curX = 1; curX < MAX_DIM; curX++) {
for (int curY = 1; curY < MAX_DIM; curY++) {
double prob = 0;
for (int i = 0; i < dx.length; i++) {
int nextX = curX + dx[i];
int nextY = curY + dy[i];
if (nextX > 0 && nextX < MAX_DIM && nextY > 0 && nextY < MAX_DIM)
prob += (0.125 * dp[curN-1][nextX][nextY]);
}
dp[curN][curX][curY] = prob;
}
}
}
return dp[n][x][y];
}
}
https://code.google.com/p/my-topcoder-code/source/browse/Code/src/tccc2005_round_1/ChessKnight.java
      public double probability(int x, int y, int n){
                double chess[][][]=new double[8][8][n+1];
                x--;
                y--;
                chess[x][y][0]=1;
                int move[][]={{2,1},{2,-1},{-2,1},{-2,-1},{1,2},{1,-2},{-1,2},{-1,-2}};
               
                for(int i=0;i<n;++i){
                        for(int xx=0;xx<8;++xx){
                                for(int yy=0;yy<8;++yy){
                                        if(chess[xx][yy][i]!=0){
                                                for(int k=0;k<8;++k){
                                                        int curx=xx+move[k][0];
                                                        int cury=yy+move[k][1];
                                                        if(curx>=0&&curx<8&&cury>=0&&cury<8){
                                                                chess[curx][cury][i+1]+=chess[xx][yy][i]/8;
                                                        }
                                                }
                                        }
                                }
                        }
                }
                double result=0;
                for(int xx=0;xx<8;++xx){
                        for(int yy=0;yy<8;++yy){
                                result+=chess[xx][yy][n];
                        }
                }
               
                return result;
        }
Read full article from An Efficient Algorithm for the Knight's Tour Problem Chessboard

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts