用于方形网格的所有步行路径的Java程序

时间:2017-04-01 14:14:41

标签: java algorithm recursion

我试图编写一个程序,输出(在控制台中)所有可能的路径((x1,x1) --> (x2,x2) --> etc..格式),用于从左上角到右下角导航大小为NxN的网格;即从(0,0)到(N-1,N-1)。你只能向下或向右移动;即从(0,0)到(0,1)或到(1,0)。我希望程序在每次找到完整路径集时输出(即所有从左上角到右下角的移动),以及该路径设置是什么。

似乎写这个的最好方法是使用递归方法将每个移动输入到arrayList中(参见buildPath方法 - 程序中的最后一个方法),这是我在哪里遇到麻烦。

为了使它稍微复杂一些,我还会生成随机网格位置,这些位置是“禁止”#34;因此无法通过。 也就是说,一旦我/我弄清楚如何让这个东西完全适用于任何路径,我就可以为自己完成这部分工作。

如何实现递归方法来确定哪些路径可行?任何帮助都表示赞赏(即使伪代码也比没有好)!

到目前为止,这是我的代码(简单的位是伪代码,以便更容易完成,但请告诉我是否应该填写完整的代码):

import java.util.*;

public class RecursiveAlgorithm {

    public static ArrayList<Integer> allPaths = new ArrayList<Integer>();
    public static ArrayList<String> pathSet = new ArrayList<String>();
    public static int path;
    public static int N, M, x = 0, y = 0;
    public static String nString, mString;
    public static boolean grid[][];
    public static int right, down;

    @SuppressWarnings("resource")
    public static void main(String[] args) {

        //sets the current position to (0,0)
        right = 0;
        down = 0;

        Input value of N (size of grid)

        Input value of M (number of off-limits locations)

        offLimits(N, M); //calls offLimits method to randomly generate off-limits locations

        buildPath(right, down, allPaths, N); //calls buildPath method

    }

    public static void offLimits (int N, int M) {

        int mCount = 0;
        if (M == 0){
        } else {
            while (mCount < (M + 1)) {
              //int range1 = (max - min) + 1;
                int range1 = ((N-1) - 1) + 1;
                int range2 = ((N-1) - 0) + 1;
                int random1 = (int)((Math.random() * range1) + 1);
                int random2 = (int)(Math.random() * range2);


                //if an 'off-limits' point is generated at the finish point, move it to either 1 place to the left or 1 place above
                if ((random1 == N-1) && (random2 == N-1)) {
                    int switchSelect = (int)(Math.random() * 2);
                    while (switchSelect > 0) {
                        switch (switchSelect){

                        case 1: random1--;
                                break;

                        case 2: random2--;
                                break;

                        }
                    }
                }
                //sets a grid position to 'off-limits' (i.e. random1 = 1, random2 = 2 --> (1, 2) is 'off-limits')
                grid[random1][random2] = true;
                //counts the amount of off-limits grid locations generated
                mCount++;
            }
        }

    }

    public static ArrayList<String> buildPath (int right, int down, ArrayList<Integer> allPaths, int N) {

        //Updates path with current location (right, down)  


        /***** FROM HERE ON IS WHERE I AM HAVING TROUBLE *****/

        //Stopping Condition
        if ((right == N-1) && (down == N-1)) { //robot cannot go right
            allPaths.add(path);
            return pathSet;
        }   
        //Recursive Steps
        if (right == N-1) { //robot cannot go right
            buildPath (right, down + 1, allPaths, N);

        } else if (down == N-1) { //robot cannot go down
            buildPath (right + 1, down, allPaths, N);
        } else { //robot CAN go right or go down
                buildPath (right + 1, down, allPaths, N);
                //pathSet.add(Integer.toString(right));
                //pathSet.add(Integer.toString(down));
                buildPath (right, down + 1, allPaths, N);

            if (grid[x][y] == false) {
                //valid new position (substitute x and y for proposed new path step)

            } else if (grid[x][y] == true) {
                //off-limits position (substitute x and y for proposed new path step)

            }
        }
        return pathSet;
    }
}

1 个答案:

答案 0 :(得分:2)

你正走在正确的轨道上,但却走向了一个比需要更复杂的解决方案。这是一种方法,它发现它们允许所有4个罗盘方向(不仅仅是向右和向下)。通过删除代码,了解您可以做到多么简单。

import java.util.LinkedHashSet;

class Experimental {
  static class PathFinder {
    final int gridSize;
    final boolean [] [] isBlocked;
    final Coord goal;
    final LinkedHashSet<Coord> path = new LinkedHashSet<>();
    final Random gen = new Random();

    PathFinder(int gridSize, int nBlocked) {
      this.gridSize = gridSize;
      this.isBlocked = new boolean[gridSize][gridSize];
      this.goal = new Coord(gridSize - 1, gridSize - 1);
      // This gets really inefficient if nBlocked is too big.
      for (int n = 0; n < nBlocked; ++n) {
        int x, y;
        do {
          x = gen.nextInt(gridSize);
          y = gen.nextInt(gridSize);
        } while (isBlocked[x][y] || (x == gridSize - 1 && y == gridSize - 1));
        isBlocked[x][y] = true;
      }
    }

    void searchFrom(Coord coord) {
      if (path.contains(coord)) return;
      path.add(coord);
      if (coord.equals(goal)) System.out.println(path);
      if (coord.x > 0 && !isBlocked[coord.x - 1][coord.y])
        searchFrom(new Coord(coord.x - 1, coord.y));
      if (coord.y > 0 && !isBlocked[coord.x][coord.y - 1])
        searchFrom(new Coord(coord.x, coord.y - 1));
      if (coord.x < gridSize - 1 && !isBlocked[coord.x + 1][coord.y])
        searchFrom(new Coord(coord.x + 1, coord.y));
      if (coord.y < gridSize - 1 && !isBlocked[coord.x][coord.y + 1])
        searchFrom(new Coord(coord.x, coord.y + 1));
      path.remove(coord);
    }

    void printAllPaths() {
      searchFrom(new Coord(0, 0));
    }

    static class Coord {
      final int x, y;
      public Coord(int x, int y) {
        this.x = x;
        this.y = y;
      }
      @Override
      public boolean equals(Object obj) {
        if (obj instanceof Coord) {
          Coord other = (Coord) obj;
          return x == other.x && y == other.y;
        }
        return false;
      }
      @Override
      public int hashCode() {
        return Integer.hashCode(x) ^ Integer.hashCode(-y);
      }
      @Override
      public String toString() {
        return '(' + Integer.toString(x) + ',' + Integer.toString(y) + ')';
      }
    }
  }

  public static void main(String[] args) {
    new PathFinder(4, new boolean [] [] {
      { false, false, false, false },
      { false, false, true, false },
      { true, false, false, false },
      { false, false, false, false },
    }).printAllPaths();
  }
}

一个提示:链接的哈希集是这里路径的合理选择,因为我们需要查看&#34;后退&#34;在每一步,以确保我们不会访问已访问过的位置。该集合使查找O(1),而链接确保维持顺序,正常的散列集不是。你的问题不同。