Java 使用Dijkstra';s算法?

Java 使用Dijkstra';s算法?,java,shortest-path,dijkstra,Java,Shortest Path,Dijkstra,这是我第一次实现Dijkstra算法。好的,这里我有一个简单的2D 9 x 9数组: 起点是1,我们试图到达任何绿色正方形。红色方块是墙或熔岩(满足你想象的任何东西) 如何在Java中实现这一点 计算机科学不是我的专业,因此我不是一个经验丰富的程序员,所以我可能不知道如何进行堆栈推送,只知道循环和递归:(请尽量简单,请耐心听我说!我建议你从写下应用dijkstras算法的方法开始(假设你一开始就知道)然后开始将其转换为您的编程语言 您需要回答的基本问题如下: 节点是什么 有什么联系 每个连接

这是我第一次实现Dijkstra算法。好的,这里我有一个简单的2D 9 x 9数组:

起点是1,我们试图到达任何绿色正方形。红色方块是墙或熔岩(满足你想象的任何东西)

如何在Java中实现这一点


计算机科学不是我的专业,因此我不是一个经验丰富的程序员,所以我可能不知道如何进行堆栈推送,只知道循环和递归:(请尽量简单,请耐心听我说!

我建议你从写下应用dijkstras算法的方法开始(假设你一开始就知道)然后开始将其转换为您的编程语言

您需要回答的基本问题如下:

  • 节点是什么
  • 有什么联系
  • 每个连接的重量是多少
一旦你这样做了,你应该能够找到一个(可能没有效率的)解决方案。

以下是一些应该让您开始的内容。但是,下面提供的解决方案试图到达右下角。您可以放宽该条件以查找底部行。您还需要稍微更改编码,使其具有表示该行的唯一值

public class MazeSolver {

    final static int TRIED = 2;
    final static int PATH = 3;

    // @formatter:off
    private static int[][] GRID = { 
        { 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1 },
        { 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1 },
        { 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0 },
        { 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1 },
        { 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1 },
        { 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } 
    };
    // @formatter:off

    public static void main(String[] args) {
        MazeSolver maze = new MazeSolver(GRID);
        boolean solved = maze.solve();
        System.out.println("Solved: " + solved);
        System.out.println(maze.toString());
    }

    private int[][] grid;
    private int height;
    private int width;

    private int[][] map;

    public MazeSolver(int[][] grid) {
        this.grid = grid;
        this.height = grid.length;
        this.width = grid[0].length;

        this.map = new int[height][width];
    }

    public boolean solve() {
        return traverse(0,0);
    }

    private boolean traverse(int i, int j) {
        if (!isValid(i,j)) {
            return false;
        }

        if ( isEnd(i, j) ) {
            map[i][j] = PATH;
            return true;
        } else {
            map[i][j] = TRIED;
        }

        // North
        if (traverse(i - 1, j)) {
            map[i-1][j] = PATH;
            return true;
        }
        // East
        if (traverse(i, j + 1)) {
            map[i][j + 1] = PATH;
            return true;
        }
        // South
        if (traverse(i + 1, j)) {
            map[i + 1][j] = PATH;
            return true;
        }
        // West
        if (traverse(i, j - 1)) {
            map[i][j - 1] = PATH;
            return true;
        }

        return false;
    }

    private boolean isEnd(int i, int j) {
        return i == height - 1 && j == width - 1;
    }

    private boolean isValid(int i, int j) {
        if (inRange(i, j) && isOpen(i, j) && !isTried(i, j)) {
            return true;
        }

        return false;
    }

    private boolean isOpen(int i, int j) {
        return grid[i][j] == 1;
    }

    private boolean isTried(int i, int j) {
        return map[i][j] == TRIED;
    }

    private boolean inRange(int i, int j) {
        return inHeight(i) && inWidth(j);
    }

    private boolean inHeight(int i) {
        return i >= 0 && i < height;
    }

    private boolean inWidth(int j) {
        return j >= 0 && j < width;
    }

    public String toString() {
        String s = "";
        for (int[] row : map) {
            s += Arrays.toString(row) + "\n";
        }

        return s;
    }

}
公共类MazeSolver{
最终静态积分=2;
最终静态int路径=3;
//@formatter:off
私有静态int[][]网格={
{ 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1 },
{ 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1 },
{ 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0 },
{ 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1 },
{ 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1 },
{ 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } 
};
//@formatter:off
公共静态void main(字符串[]args){
MazeSolver迷宫=新MazeSolver(网格);
布尔解算=maze.solve();
System.out.println(“已解决:+已解决”);
System.out.println(maze.toString());
}
私有int[][]网格;
私人内部高度;
私有整数宽度;
私有int[][]映射;
公共MazeSolver(int[][]网格){
this.grid=grid;
this.height=grid.length;
this.width=grid[0]。长度;
this.map=新整数[高度][宽度];
}
公共布尔解(){
回程导线(0,0);
}
私有布尔遍历(int i,int j){
如果(!isValid(i,j)){
返回false;
}
如果(i结束(i,j)){
map[i][j]=路径;
返回true;
}否则{
map[i][j]=已尝试;
}
//北
if(横向(i-1,j)){
map[i-1][j]=路径;
返回true;
}
//东边
if(横向(i,j+1)){
map[i][j+1]=路径;
返回true;
}
//南方
if(横向(i+1,j)){
map[i+1][j]=路径;
返回true;
}
//西部
if(横向(i,j-1)){
map[i][j-1]=路径;
返回true;
}
返回false;
}
私有布尔isEnd(int i,int j){
返回i==高度-1&&j==宽度-1;
}
私有布尔值有效(int i,int j){
if(在区间(i,j)&&isOpen(i,j)&&isTried(i,j))中){
返回true;
}
返回false;
}
专用布尔等参线(int i,int j){
返回网格[i][j]==1;
}
私有布尔isTried(int i,int j){
返回映射[i][j]==已尝试;
}
范围内的私有布尔值(int i,int j){
返回高度(i)和返回宽度(j);
}
私有布尔inHeight(int i){
返回i>=0&&i<高度;
}
私有布尔inWidth(int j){
返回j>=0&&j
最佳解决方案确实是使用具有不同完成条件的or AStar。因此,您需要编写
if(targetNodes.contains(u))break;
而不是
if(target==u)break;

(参见维基百科:如果我们只对源和目标顶点之间的最短路径感兴趣,那么如果u=target,我们可以在第13行终止搜索。)


这已经在我的名为…哦,这是家庭作业吗;)?

的项目中实现了,我个人不太有信心将代码发布到一个显然是作业问题的项目中。这可能会降低学习效果:)@Vespasian:公平地说,这不是完整的解决方案。此外,为什么“这显然是一个任务问题”?不管怎样,网络上有很多解决方案。我不想冒犯你。如果听起来像这样,我很抱歉。他提供的图片给了我一个印象。当然,你对解决方案的看法是正确的。记录在案,近10年后,这对我真的很有帮助,我甚至没有做任何作业;)只要扩展这里的内容,就可以找到最理想的可行路径。你可以找到一个有效的解决方案:Dijkstra!看我的回答嘿,我想在游戏中实现Dijkstra,你能帮我吗