如何找到所有可用的迷宫路径?

发布于 2024-08-06 13:16:38 字数 5273 浏览 1 评论 0原文

我正在尝试编写一个程序,该程序被赋予一个迷宫并试图找到出路。 M是入口,E是出口,1是墙壁,0是路径。它应该找到每条路径并将P放入该路径中。它应该找到所有可用的路径。现在它找到了路径的一部分。

这是代码:

public class Maze 
{
    private int size;
    private String[][] board;
    private int total; //# of boards
    private int eX;
    private int eY;
    private int mX;
    private int mY;

    public Maze( int size, String[][] board )
    {
        this.size = size;
        this.board = board;
        total = 0;

    }

    private void find( String c )
    {
        int x=0, y=0;
        for( int i = 0; i < size; i++ )
        {
            for( int j = 0; j < size; j++ )
            {
                if( board[i][j].equals(c) )
                {
                    x = i;
                    y = j;
                }
            }
        }
        if( c.equals("M") )
        {
            mX = x;
            mY = y;
        }
        else if( c.equals("E") )
        {
            eX = x;
            eY = y;
        }
    }

    public void findPath(  )
    {
        find( "M" );
        find( "E" );
        findNext( mX, mY );
    }

    public void findNext( int x, int y )
    { 
        String last = board[x][y];
            if( board[x][y].equals("P") ) board[x][y] = "1";
        board[x][y] = "P";

        if( rightAvailability(x,y) )
        {
            findNext(x+1, y);
        }
        else if( leftAvailability(x,y) )
        {
            findNext(x-1, y);
        }
        else if( aboveAvailability(x,y) )
        {
            findNext(x, y+1);
        }
        else if( belowAvailability(x,y) )
        {
            findNext(x, y-1);
        }
        else
        {
            total++;
            printBoard();
        }

        board[x][y]= last;
    }

    public boolean rightAvailability( int x, int y )
    {
        if( x+1 >= size ) return false;
        else if( board[x+1][y].equals("1") ) return false;
        else if( board[x+1][y].equals("P") ) return false;
        else return true;
    }
    public boolean leftAvailability( int x, int y )
    {
        if( x-1 < 0) return false;
        else if( board[x-1][y].equals("1") ) return false;
        else if( board[x-1][y].equals("P") ) return false;
        else return true;
    }
    public boolean aboveAvailability( int x, int y )
    {
        if( y+1 >= size ) return false;
        else if( board[x][y+1].equals("1") ) return false;
        else if( board[x][y+1].equals("P") ) return false;
        else return true;
    }
    public boolean belowAvailability( int x, int y )
    {
        if( y-1 < 0) return false;
        else if( board[x][y-1].equals("1") ) return false;
        else if( board[x][y-1].equals("P") ) return false;
        else return true;
    }

    public void printBoard()
    {
        System.out.println( "The board number " +total+ " is: ");
        for(int i=0; i< size; i++ )
        {
            for(int j=0; j< size; j++ )
            {
                if( (i==mX) && (j==mY) )
                {
                    System.out.print("M");
                }
                else if( (i==eX) && (j==eY) )
                {
                    System.out.print("E");
                }
                else if( board[i][j].equals("1") )
                {
                    System.out.print("1");
                }
                else if( board[i][j].equals("0") )
                {
                    System.out.print("0");
                }
                else
                {
                    System.out.print("P");
                }
            }
            System.out.println();
        }
    }
}

这是测试器:

public class MazeTester 
{
    public static void main(String[] args) 
    {
        int size = 11;
        String[][] board = new String[][]
            {
                {"1","1","1","1","1","1","1","1","1","1","1"},
                {"1","0","0","0","0","0","1","0","0","0","1"},
                {"1","0","1","0","0","0","1","0","1","0","1"},
                {"E","0","1","0","0","0","0","0","1","0","1"},
                {"1","0","1","1","1","1","1","0","1","0","1"},
                {"1","0","1","0","1","0","0","0","1","0","1"},      
                {"1","0","0","0","1","0","1","0","0","0","1"},
                {"1","1","1","1","1","0","1","0","0","0","1"},
                {"1","0","1","M","1","0","1","0","0","0","1"},
                {"1","0","0","0","0","0","1","0","0","0","1"},
                {"1","1","1","1","1","1","1","1","1","1","1"},  
            };


        Maze m = new Maze( size, board );
        m.findPath();
    }
}

这是当前输出:

The board number 1 is: 
11111111111
1PPPPP1PPP1
1P1PPP1P1P1
EP1PPPPP1P1
101111101P1
10101PPP1P1
10001P1PPP1
11111P1PP01
101M1P1PP01
100PPP1PP01
11111111111
The board number 2 is: 
11111111111
1PPPPP1PPP1
1P1PPP1P1P1
EP100PPP1P1
101111101P1
10101PPP1P1
10001P1PPP1
11111P1PP01
101M1P1PP01
100PPP1PP01
11111111111
The board number 348 is: 
11111111111
1PPPPP10001
1P1PPP10101
EP1PPPPP101
1011111P101
10101PPP101
10001P10001
11111P10001
101M1P10001
100PPP10001
11111111111

编辑:我添加了 if( board[x][y].equals("P") ) board[x][y] = "1";在 findIndex 的开头。我还解决了 x <= 0 问题。我将输出更新为我现在得到的(实际上是打印 348 个类似的板)。

I am trying to write a program that is given a maze and tries to find the way out. M is the entrance, E is the exit, 1s are walls, and 0s are pathways. It is supposed to find each path and put P in the path. It is supposed to find all available paths. Right now it finds part of a path.

Here is the code:

public class Maze 
{
    private int size;
    private String[][] board;
    private int total; //# of boards
    private int eX;
    private int eY;
    private int mX;
    private int mY;

    public Maze( int size, String[][] board )
    {
        this.size = size;
        this.board = board;
        total = 0;

    }

    private void find( String c )
    {
        int x=0, y=0;
        for( int i = 0; i < size; i++ )
        {
            for( int j = 0; j < size; j++ )
            {
                if( board[i][j].equals(c) )
                {
                    x = i;
                    y = j;
                }
            }
        }
        if( c.equals("M") )
        {
            mX = x;
            mY = y;
        }
        else if( c.equals("E") )
        {
            eX = x;
            eY = y;
        }
    }

    public void findPath(  )
    {
        find( "M" );
        find( "E" );
        findNext( mX, mY );
    }

    public void findNext( int x, int y )
    { 
        String last = board[x][y];
            if( board[x][y].equals("P") ) board[x][y] = "1";
        board[x][y] = "P";

        if( rightAvailability(x,y) )
        {
            findNext(x+1, y);
        }
        else if( leftAvailability(x,y) )
        {
            findNext(x-1, y);
        }
        else if( aboveAvailability(x,y) )
        {
            findNext(x, y+1);
        }
        else if( belowAvailability(x,y) )
        {
            findNext(x, y-1);
        }
        else
        {
            total++;
            printBoard();
        }

        board[x][y]= last;
    }

    public boolean rightAvailability( int x, int y )
    {
        if( x+1 >= size ) return false;
        else if( board[x+1][y].equals("1") ) return false;
        else if( board[x+1][y].equals("P") ) return false;
        else return true;
    }
    public boolean leftAvailability( int x, int y )
    {
        if( x-1 < 0) return false;
        else if( board[x-1][y].equals("1") ) return false;
        else if( board[x-1][y].equals("P") ) return false;
        else return true;
    }
    public boolean aboveAvailability( int x, int y )
    {
        if( y+1 >= size ) return false;
        else if( board[x][y+1].equals("1") ) return false;
        else if( board[x][y+1].equals("P") ) return false;
        else return true;
    }
    public boolean belowAvailability( int x, int y )
    {
        if( y-1 < 0) return false;
        else if( board[x][y-1].equals("1") ) return false;
        else if( board[x][y-1].equals("P") ) return false;
        else return true;
    }

    public void printBoard()
    {
        System.out.println( "The board number " +total+ " is: ");
        for(int i=0; i< size; i++ )
        {
            for(int j=0; j< size; j++ )
            {
                if( (i==mX) && (j==mY) )
                {
                    System.out.print("M");
                }
                else if( (i==eX) && (j==eY) )
                {
                    System.out.print("E");
                }
                else if( board[i][j].equals("1") )
                {
                    System.out.print("1");
                }
                else if( board[i][j].equals("0") )
                {
                    System.out.print("0");
                }
                else
                {
                    System.out.print("P");
                }
            }
            System.out.println();
        }
    }
}

Here is the tester:

public class MazeTester 
{
    public static void main(String[] args) 
    {
        int size = 11;
        String[][] board = new String[][]
            {
                {"1","1","1","1","1","1","1","1","1","1","1"},
                {"1","0","0","0","0","0","1","0","0","0","1"},
                {"1","0","1","0","0","0","1","0","1","0","1"},
                {"E","0","1","0","0","0","0","0","1","0","1"},
                {"1","0","1","1","1","1","1","0","1","0","1"},
                {"1","0","1","0","1","0","0","0","1","0","1"},      
                {"1","0","0","0","1","0","1","0","0","0","1"},
                {"1","1","1","1","1","0","1","0","0","0","1"},
                {"1","0","1","M","1","0","1","0","0","0","1"},
                {"1","0","0","0","0","0","1","0","0","0","1"},
                {"1","1","1","1","1","1","1","1","1","1","1"},  
            };


        Maze m = new Maze( size, board );
        m.findPath();
    }
}

Here is the current output:

The board number 1 is: 
11111111111
1PPPPP1PPP1
1P1PPP1P1P1
EP1PPPPP1P1
101111101P1
10101PPP1P1
10001P1PPP1
11111P1PP01
101M1P1PP01
100PPP1PP01
11111111111
The board number 2 is: 
11111111111
1PPPPP1PPP1
1P1PPP1P1P1
EP100PPP1P1
101111101P1
10101PPP1P1
10001P1PPP1
11111P1PP01
101M1P1PP01
100PPP1PP01
11111111111
The board number 348 is: 
11111111111
1PPPPP10001
1P1PPP10101
EP1PPPPP101
1011111P101
10101PPP101
10001P10001
11111P10001
101M1P10001
100PPP10001
11111111111

EDIT: I added if( board[x][y].equals("P") ) board[x][y] = "1"; at the beginning of findIndex. I also fixed the x <= 0 problem. I updated the output to what I am getting now (it is actually print 348 similar boards).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

强辩 2024-08-13 13:16:38

我在行中放置了部分猜测:

else if( belowAvailability(x,y) )
{
        findNext(x, x-1);
}

x-1 应该是 y-1

您会发现的另一个问题是您正在使用 else if 块。如果你遇到一个分支,说

1E1
101
1P0
1P1

你会先尝试向右走,然后当它严重失败时,它就不会尝试向上。您实际上可以在测试输出中看到,

_._._789_._
_..._6_A54_
_____5_B23_
_._M_4_C10_
_..123_DEF_
___________

为了方便阅读,以十六进制编号。它进入右下角,然后卡住;由于无处可去,棋盘被打印出来,递归结束时不会回溯到未经测试的方块。

再次编辑。仍在寻找,但在左/右可用性中,您有另一个 x/y 不匹配,并且您可能只想在 x-1 < 时拒绝可用性。 0(或y-1);因为目标节点位于 y=0。

通过这些更改,并且仅当 x==eX && 时才触发打印y==eY,我正在得到解决方案的输出。解决方案有很多,但是解决方案。

关于编辑计数的另一个幽默事实是:您可以向后/向左和向上/向下。 x 坐标指定您正在查看的输入的行,y 坐标指定列。在这种情况下使用 r/c 是相当常见的。

I put a partial Guess at the line:

else if( belowAvailability(x,y) )
{
        findNext(x, x-1);
}

x-1 should be y-1

Another problem you'll find is in the fact that you're using else if blocks. If you encounter a branch, say

1E1
101
1P0
1P1

You will try to go right first, and then when that fails miserably, it won't try to go up. You can actually see that in the test output,

_._._789_._
_..._6_A54_
_____5_B23_
_._M_4_C10_
_..123_DEF_
___________

Numbered in Hex for easy reading convenience. It gets into the lower right corner, then gets stuck; having nowhere else to go the board is printed, and the recursion ends with no backtracking into untested squares.

EDIT again. Still looking, but in the left/right availability you have another x/y mismatch, and you probably only want to deny availability when x-1 < 0 (or y-1); as the goal node is at y=0.

With those changes, and having print trigger only when x==eX && y==eY, I'm getting output of solutions. A great many solutions, but solutions.

One more humorous fact for edit count: you have left/right and up/down backwards. The x coordinate is specifying the row of the input you're looking at, and the y coordinate is specifying the column. It's reasonably common to use r/c in cases like this.

魂牵梦绕锁你心扉 2024-08-13 13:16:38

标准路径查找算法应该可以工作,您需要修改它们以匹配您的世界定义。

但 A* 或 D* 算法效果很好。他们使用图表,您应该能够根据您的世界定义来定义该图表。 (http://en.wikipedia.org/wiki/A*)

Dijstra 算法也应该努力寻找路径(再次使用图表)。它通常用于网络路由 - 但它也适用于正常的路径查找。 (http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm)

基本上我的方法是将迷宫定义转换为图表(节点是“连接点”,边缘是“走廊”),然后使用其中一种算法。

Standard path finding algorithms should work, you'll need to modify them to match your world definition.

But A* or D* algorithms work pretty well. They use a graph, which you should be able to define from your world definition. (http://en.wikipedia.org/wiki/A*)

Also Dijstra's algorithm should work at finding a path (again uses a graph). It is commonly used for network routing - but it also works for normal path finding. (http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm)

Basically my approach would be to turn your maze definition into a graph (nodes are "join points", edges are the "hallways") and then use one of those algorithms.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文