Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用DFS生成迷宫失败,我不知道';我不知道为什么_Java_Algorithm_Graph_Depth First Search_Maze - Fatal编程技术网

Java 使用DFS生成迷宫失败,我不知道';我不知道为什么

Java 使用DFS生成迷宫失败,我不知道';我不知道为什么,java,algorithm,graph,depth-first-search,maze,Java,Algorithm,Graph,Depth First Search,Maze,我只是想用最简单的算法生成一些迷宫,但我所有的迷宫看起来都像下面的一个: 下面是一段Java代码(whatVisit函数工作正常,不要看它): private void dfs(点开始,已访问的布尔值[]){ 点nextCell=什么是访问(开始,访问); if(nextCell==null)//如果没有可访问的内容 返回; //将当前单元格标记为已访问 已访问[start.y][start.x]=true; //破坏当前单元格和新单元格之间的墙 边框[(start.y+nextCell.y)

我只是想用最简单的算法生成一些迷宫,但我所有的迷宫看起来都像下面的一个:

下面是一段Java代码(whatVisit函数工作正常,不要看它):

private void dfs(点开始,已访问的布尔值[]){
点nextCell=什么是访问(开始,访问);
if(nextCell==null)//如果没有可访问的内容
返回;
//将当前单元格标记为已访问
已访问[start.y][start.x]=true;
//破坏当前单元格和新单元格之间的墙
边框[(start.y+nextCell.y)/2][(start.x+nextCell.x)/2]=真;
//从找到的单元格开始新搜索
dfs(nextCell,已访问);
}
私有点whatVisit(点p,布尔值[][]已访问){
Vectorcells=new Vector();//用于存储可能的单元格
//环顾四周
如果(p.x-2>=0&&!访问[p.y][p.x-2])
添加(新点(p.x-2,p.y));
如果(p.x+2<访问量[0]。访问长度和访问量[p.y][p.x+2])
添加(新点(p.x+2,p.y));
如果(p.y-2>=0&!已访问[p.y-2][p.x])
添加(新点(p.x,p.y-2));
如果(p.y+20)
返回单元格。获取(0);
否则返回null;
}
我知道为什么它不起作用!当DFS最终到达没有可访问单元的位置时,它只是返回开始

如何解决此问题并强制正确工作


谢谢。

事实上,我还是不明白你想要生成迷宫的目的是什么。但我有一些建议给你:

  • 通过随机化坐标,为dfs算法创建2或3个起点,这样迷宫就不会单调了

  • 在您的算法中,每次移动仅尝试1个可访问的单元格。尝试在每次移动中访问更容易访问的单元格,以便路径不会是要完成的单向路径。(这也是dfs在找不到可访问单元后返回启动的原因)

  • 这是我上面第二个想法的代码(根据上面的代码编辑):

    private void dfs(点开始,已访问的布尔值[]){
    ArrayList nextCell=whatVisit(开始,访问);
    if(nextCell==null)//如果没有可访问的内容
    返回;
    //将当前单元格标记为已访问
    已访问[start.y][start.x]=true;
    for(下一点:nextCell)//尝试新的可访问单元格
    {
    //破坏当前单元格和新单元格之间的墙
    边框[(start.y+next.y)/2][(start.x+next.x)/2]=真;
    //从找到的单元格开始新搜索
    dfs(下一步,访问);
    }
    }
    private ArrayList whatVisit(点p,布尔值[][]已访问){
    Vectorcells=new Vector();//用于存储可能的单元格
    //环顾四周
    如果(p.x-2>=0&&!访问[p.y][p.x-2])
    添加(新点(p.x-2,p.y));
    如果(p.x+2<访问量[0]。访问长度和访问量[p.y][p.x+2])
    添加(新点(p.x+2,p.y));
    如果(p.y-2>=0&!已访问[p.y-2][p.x])
    添加(新点(p.x,p.y-2));
    如果(p.y+20)
    {
    ArrayList tmp=新的ArrayList();
    //随机化将返回的单元格数
    intx=(int)(Math.random()*cells.size())+1;
    如果(x>cells.size())
    x=单元格。大小();
    收集。洗牌(单元格);
    对于(int i=0;i

    希望这会有所帮助;)

    看起来你只是在摆脱困境,一旦走到尽头就退出。相反,您应该回溯,直到找到一个仍然有可访问邻居的单元,然后从那里继续算法。通常的方法是使用堆栈:在访问项目时推送项目,弹出以回溯。大概是这样的:

    if (nextCell == null) { // You've reached a dead-end
      if (stack.empty()) // base-case, bail out
        return;
    
      dfs(stack.pop(), visited); // backtrack
    } else {
      stack.push(nextCell);
    
      visited[start.y][start.x] = true;
      borders[(start.y + nextCell.y)/2][(start.x + nextCell.x)/2] = true;
      dfs(nextCell, visited);
    }
    

    当DFS到达没有可访问单元的位置时,您希望发生什么,而不是返回开始?我想,我自己的倾向可能是尝试从已经创建的路径中的某个位置开始另一个路径搜索,并可能进行入口和出口。
    private void dfs(Point start, boolean[][] visited) {
        ArrayList<Point> nextCell = whatVisit(start, visited);
        if(nextCell == null)        // if there's nothing to visit
            return;
    
        // mark current cell as visited
        visited[start.y][start.x] = true;
    
        for (Point next : nextCell) // try new accessible cells
        {
            // destroy the wall between current cell and the new one
            borders[(start.y + next.y)/2][(start.x + next.x)/2] = true;    
            // start a new search from found cell
            dfs(next, visited);
        }
    }
    
    private ArrayList<Point> whatVisit(Point p, boolean[][] visited) {
        Vector<Point>cells = new Vector<Point>();   // to store acessible cells
    
        // lookaround
        if(p.x - 2 >= 0 && !visited[p.y][p.x - 2])
            cells.add(new Point(p.x - 2, p.y));
        if(p.x + 2 < visited[0].length && !visited[p.y][p.x + 2])
            cells.add(new Point(p.x + 2, p.y));
        if(p.y - 2 >= 0 && !visited[p.y - 2][p.x])
            cells.add(new Point(p.x, p.y - 2));
        if(p.y + 2 < visited.length && !visited[p.y + 2][p.x])
            cells.add(new Point(p.x, p.y + 2));
    
        // returns null if there are no accessible cells around
        if(cells.size() > 0)
        {
            ArrayList<Point> tmp = new ArrayList<Point>();
            // randomize how many cell that will be returned
            int x = (int)(Math.random()*cells.size()) + 1;
            if (x > cells.size())
                x = cells.size();
            Collections.shuffle(cells);
            for (int i = 0; i < x; i++)
                tmp.add(cells.get(i));
            return tmp;
        }
        else return null;
    }
    
    if (nextCell == null) { // You've reached a dead-end
      if (stack.empty()) // base-case, bail out
        return;
    
      dfs(stack.pop(), visited); // backtrack
    } else {
      stack.push(nextCell);
    
      visited[start.y][start.x] = true;
      borders[(start.y + nextCell.y)/2][(start.x + nextCell.x)/2] = true;
      dfs(nextCell, visited);
    }