Algorithm for finding all paths in a NxN grid

前端 未结 10 1314
忘了有多久
忘了有多久 2020-11-28 08:27

Imagine a robot sitting on the upper left hand corner of an NxN grid. The robot can only move in two directions: right and down. How many possible paths are there for the ro

相关标签:
10条回答
  • 2020-11-28 08:44

    I see no indications for obstacles in your question so we can assume there are none.

    Note that for an n+1 by n+1 grid, a robot needs to take exactly 2n steps in order to reach the lower right corner. Thus, it cannot make any more than 2n moves.

    Let's start with a simpler case: [find all paths to the right down corner]

    The robot can make exactly choose(n,2n)= (2n)!/(n!*n!) paths: It only needs to choose which of the 2n moves will be right, with the rest being down (there are exactly n of these).
    To generate the possible paths: just generate all binary vectors of size 2n with exactly n 1's. The 1's indicate right moves, the 0's, down moves.

    Now, let's expand it to all paths:
    First choose the length of the path. To do so, iterate over all possibilities: 0 <= i <= 2n, where i is the length of the path. In this path there are max(0,i-n) <= j <= min(i,n) right steps.
    To generate all possibilities, implement the following pseudo-code:

    for each i in [0,2n]:
      for each j in [max(0,i-n),min(i,n)]:
        print all binary vectors of size i with exactly j bits set to 1
    

    Note 1: printing all binary vectors of size i with j bits set to 1 could be computationally expensive. That is expected since there are an exponential number of solutions.
    Note 2: For the case i=2n, you get j in [n,n], as expected (the simpler case described above).

    0 讨论(0)
  • 2020-11-28 08:44

    https://math.stackexchange.com/questions/104032/finding-points-in-a-grid-with-exactly-k-paths-to-them - look here at my solution. Seems that it is exactly what you need (yes, statements are slightly different, but in general case they are just the same).

    0 讨论(0)
  • 2020-11-28 08:44

    Here is a full implementation that works for both rectangular and square grids. I will leave you to figure out how to take care of the excess "=>" at the end of each path.

       import java.util.Arraylist;
    
       public class PrintPath
       {
        static ArrayList<String> paths = new ArrayList<String>(); 
    
        public static long getUnique(int m, int n, int i, int j, String pathlist)
        {
    
            pathlist += ("(" + i + ", " + (j) + ") => ");
    
            if(m == i && n == j)
            {       
                paths.add(pathlist); 
            }
    
            if( i > m || j > n)
            {
                return 0;               
            }
    
            return getUnique(m, n, i+1, j, pathlist)+getUnique(m, n, i, j+1, pathlist); 
    
        }
    
        public static void printPaths()
        {
            int count = 1;
            System.out.println("There are "+paths.size() + " unique paths: \n");
    
            for (int i = paths.size()-1; i>=0; i--)
            {
    
             System.out.println( "path " + count + ":   " + paths.get(i));
             count++;
            }
    
        }
    
        public static void main(String args[])
        {
            final int start_Point = 1;
            int grid_Height = 2; 
            int grid_Width = 2; 
    
            getUnique(grid_Height, grid_Width, start_Point, start_Point, "");
            printPaths(); 
    
        }
    
    }
    
    0 讨论(0)
  • 2020-11-28 08:44
    int N;
    function num_paths(intx,int y)
    {
        int[][] arr = new int[N][N];
    arr[N-1][N-1] = 0;
    for(int i =0;i<N;i++)
    {
        arr[N-1][i]=1;
        arr[i][N-1]=1;
    }
    for(int i = N-2;i>=0;i--)
    {
        for(int j=N-2;j>=0;j--)
        {
            arr[i][j]= arr[i+1][j]+arr[i][j+1];
        }
    }
    return arr[0][0];
     }
    
    0 讨论(0)
  • 2020-11-28 08:46

    If you just need a count of the valid paths:

    Let's say you have a matrix n*m matrix and you set all cells to zero and the "offlimit" cells to -1.

    You can then solve the problem with dynamic programming:

    // a is a matrix with 0s and -1s
    // n, m are the dimensions
    // M is 10^9-7 incase you have a large matrix
    
    if (a[0][0] == 0) a[0][0] = 1;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (a[i][j] == -1) continue;
            if (i > 0) a[i][j] = (a[i][j] + max(a[i-1][j], 0LL)) % M;
            if (j > 0) a[i][j] = (a[i][j] + max(a[i][j-1], 0LL)) % M;
        }
    }
    
    // answer at lower right corner
    cout << a[n-1][m-1];
    

    Blazing fast without recursion or bloaty data structures.

    NOTE: this was deleted due to being duplicate but since this is the best thread on this topic, I've deleted my answer from elsewhere and will add this here.

    0 讨论(0)
  • 2020-11-28 08:54

    Below is the code in Java to count all the possible paths from top left corner to bottom right corner of a NXN matrix.

    public class paths_in_matrix {
    
        /**
         * @param args
         */
        static int n=5;
        private boolean[][] board=new boolean[n][n];
        int numPaths=0;
        paths_in_matrix(){
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    board[i][j]=false;
                }
            }
        }
        private void togglePiece(int i,int j){
            this.board[i][j]=!this.board[i][j];
        }
        private boolean hasBeenVisited(int i,int j){
            return this.board[i][j];
        }
        private boolean exists(int i,int j){
            return i < n && i > -1 && j < n && j > -1;
        }
        private boolean viablePosition(int i,int j){
            return exists(i, j) && !hasBeenVisited(i,j);
        }
        private void traversePaths(int i,int j){
            //BASE CASE: if reached (n - 1, n - 1), count as path and stop. 
            if (i == (n - 1) && j == (n - 1)) {
              this.numPaths++;
              return;
            }
            this.togglePiece(i, j);
            //RECURSIVE CASE: if next point is a viable position, go there and make the same decision
    
            //go right if possible
            if (this.viablePosition(i, j + 1)) {
              traversePaths(i, j + 1);
            }
          //go left if possible
            if (this.viablePosition(i, j - 1)) {
              traversePaths( i, j - 1);
            }
    
            //go down if possible
            if (this.viablePosition(i + 1, j)) {
              traversePaths( i + 1, j);
            }
    
            //go up if possible
            if (this.viablePosition(i - 1, j)) {
              traversePaths(i - 1, j);
            }
    
            //reset the board back to the way you found it after you've gone forward so that other paths can see it as a viable position for their routes
            this.togglePiece(i, j);
    
        }
        private int robotPaths(){
    
            traversePaths(0,0);
            return this.numPaths;
        }
        public static void main(String[] args) {
            paths_in_matrix mat=new paths_in_matrix();
            System.out.println(mat.robotPaths());
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题