Java 中二维数组的 Dijkstra 算法

发布于 2024-07-22 08:05:13 字数 4153 浏览 3 评论 0原文

这是一个学校项目; 我遇到了很多麻烦,而且我似乎找不到可以理解的解决方案。

   a b c d e z
 a - 2 3 - - -
 b 2 - - 5 2 -
 c 3 - - - 5 -
 d - 5 - - 1 2
 e - 2 5 1 - 4
 z - - - 2 4 -

这就是二维数组。 因此,如果您想找到最短路径,则从 a,b,e,d,z = 7 开始,并且 (a,b) = (b,a) - 它将带您到新行以查找该行的相邻行paths

有谁可以帮我实现这个例子的 Dijkstra 算法吗? 我真的很感激。 (我似乎最喜欢数组,映射和集合让我有点困惑,列表是可以管理的 - 尽管我现在愿意研究任何类型的解决方案)

[至少我不只是从网。 我其实想学这些东西...这真的很难(>.<)]

哦,起点是A,终点是Z


正如大多数人一样,我不觉得算法的概念很难 - 我只是可以看到编码是否正确...请帮忙?

示例代码——一位朋友在这方面帮助了我很多(尽管它充满了我发现很难理解的数据结构)我也尝试过改编来自 dreamincode.net/forums/blog/martyr2/index.php 的 C++ 代码? showentry=578 进入java,但进展不太顺利......

import java.util.*;

public class Pathy{

    private static class pathyNode{
        public final String name;
        public Map<pathyNode, Integer> adjacentNodes;

        public pathyNode(String n){
            name = n;
            adjacentNodes = new HashMap<pathyNode, Integer>();
        }

    }

    //instance variables

    //constructors

    //accessors

    //methods
    public static ArrayList<pathyNode> convert(int[][] inMatrix){
        ArrayList<pathyNode> nodeList = new ArrayList<pathyNode>();
        for(int i = 0; i < inMatrix.length; i++){
            nodeList.add(new pathyNode("" + i));
        }
        for(int i = 0; i < inMatrix.length; i++){
            for(int j = 0; j < inMatrix[i].length; j++){
                if(inMatrix[i][j] != -1){
                    nodeList.get(i).adjacentNodes.put(nodeList.get(j),
                            new Integer(inMatrix[i][j]));
                }
            }
        }
        return nodeList;
    }

    public static Map<pathyNode, Integer> Dijkstra(ArrayList<pathyNode> inGraph){
        Set<pathyNode> visited = new HashSet<pathyNode>();
        visited.add(inGraph.get(0));
        pathyNode source = inGraph.get(0);
        Map answer = new TreeMap<pathyNode, Integer>();
        for(pathyNode node : inGraph){
            dijkstraHelper(visited, 0, source, node);
            answer.put(node, dijkstraHelper(visited, 0, source, node));
        }
        return answer;
    }

    private static int dijkstraHelper(Set<pathyNode> visited, int sum, pathyNode start, pathyNode destination){
        Map<pathyNode, Integer> adjacent = new HashMap<pathyNode, Integer>();

        for(pathyNode n : visited){
            for(pathyNode m: n.adjacentNodes.keySet()){
                if(adjacent.containsKey(m)){
                    Integer temp = n.adjacentNodes.get(m);
                    if(temp < adjacent.get(m)){
                        adjacent.put(m, temp);
                    }
                }
                else{
                    adjacent.put(m, n.adjacentNodes.get(m));
                }
            }
        }

        Map<pathyNode, Integer> adjacent2 = new HashMap<pathyNode, Integer>();
        Set<pathyNode> tempSet = adjacent.keySet();
        tempSet.removeAll(visited);
        for(pathyNode n: tempSet){
            adjacent2.put(n, adjacent.get(n));
        }
        adjacent = adjacent2;
        Integer min = new Integer(java.lang.Integer.MAX_VALUE);
        pathyNode minNode = null;

        for(pathyNode n: adjacent.keySet()){
            Integer temp = adjacent.get(n);
            if(temp < min){
                min = temp;
                minNode = n;
            }
        }
        visited.add(minNode);
        sum += min.intValue();
        sum = dijkstraHelper(visited, sum, start, destination);
        return sum;
    }

    //main
    public static void main(String[] args){

        int[][] input = new int[][] { {-1, 2, 3, -1, -1, -1},
                          {2, -1, -1, 5, 2, -1},
                          {3, -1, -1, -1, 5, -1},
                          {-1, 5, -1, -1, 1, 2},
                          {-1, 2, 5, 1, -1, 4},
                          {-1, -1, -1, 2, 4, -1},
                        };
                        //-1 represents an non-existant path

        System.out.println(Dijkstra(convert(input)));
    }
}

This is for a school project; I'm running into a huge amount of trouble, and I can't seem to find a understandable solution.

   a b c d e z
 a - 2 3 - - -
 b 2 - - 5 2 -
 c 3 - - - 5 -
 d - 5 - - 1 2
 e - 2 5 1 - 4
 z - - - 2 4 -

That's the two dimensional array. So if you want to find the shortest path, its from a,b,e,d,z = 7, and (a,b) = (b,a) -- it takes you to the new row to for the row's adjacent paths

Is there anyone that can help me implement Dijkstra's algorithm for this example? I'd really appreciate it. (I seem to like arrays best, maps and sets confuse me a bit, lists are manageable -though I'm willing to look into any sort of solution at this point)

[At least I'm not just ripping off a source from the net. I actually wanna learn these things... It's just really hard (>.<)]

Oh, start point is A and end point is Z


As most people, I don't find the concept of the algorithm difficult -- I just can see to get the coding right... Help please?

Sample code-- a friend helped me with this a lot (though its filled with data structures that I find difficult to follow) I"ve also tried adapting the C++ code from dreamincode.net/forums/blog/martyr2/index.php?showentry=578 into java, but that didn't go so well ...

import java.util.*;

public class Pathy{

    private static class pathyNode{
        public final String name;
        public Map<pathyNode, Integer> adjacentNodes;

        public pathyNode(String n){
            name = n;
            adjacentNodes = new HashMap<pathyNode, Integer>();
        }

    }

    //instance variables

    //constructors

    //accessors

    //methods
    public static ArrayList<pathyNode> convert(int[][] inMatrix){
        ArrayList<pathyNode> nodeList = new ArrayList<pathyNode>();
        for(int i = 0; i < inMatrix.length; i++){
            nodeList.add(new pathyNode("" + i));
        }
        for(int i = 0; i < inMatrix.length; i++){
            for(int j = 0; j < inMatrix[i].length; j++){
                if(inMatrix[i][j] != -1){
                    nodeList.get(i).adjacentNodes.put(nodeList.get(j),
                            new Integer(inMatrix[i][j]));
                }
            }
        }
        return nodeList;
    }

    public static Map<pathyNode, Integer> Dijkstra(ArrayList<pathyNode> inGraph){
        Set<pathyNode> visited = new HashSet<pathyNode>();
        visited.add(inGraph.get(0));
        pathyNode source = inGraph.get(0);
        Map answer = new TreeMap<pathyNode, Integer>();
        for(pathyNode node : inGraph){
            dijkstraHelper(visited, 0, source, node);
            answer.put(node, dijkstraHelper(visited, 0, source, node));
        }
        return answer;
    }

    private static int dijkstraHelper(Set<pathyNode> visited, int sum, pathyNode start, pathyNode destination){
        Map<pathyNode, Integer> adjacent = new HashMap<pathyNode, Integer>();

        for(pathyNode n : visited){
            for(pathyNode m: n.adjacentNodes.keySet()){
                if(adjacent.containsKey(m)){
                    Integer temp = n.adjacentNodes.get(m);
                    if(temp < adjacent.get(m)){
                        adjacent.put(m, temp);
                    }
                }
                else{
                    adjacent.put(m, n.adjacentNodes.get(m));
                }
            }
        }

        Map<pathyNode, Integer> adjacent2 = new HashMap<pathyNode, Integer>();
        Set<pathyNode> tempSet = adjacent.keySet();
        tempSet.removeAll(visited);
        for(pathyNode n: tempSet){
            adjacent2.put(n, adjacent.get(n));
        }
        adjacent = adjacent2;
        Integer min = new Integer(java.lang.Integer.MAX_VALUE);
        pathyNode minNode = null;

        for(pathyNode n: adjacent.keySet()){
            Integer temp = adjacent.get(n);
            if(temp < min){
                min = temp;
                minNode = n;
            }
        }
        visited.add(minNode);
        sum += min.intValue();
        sum = dijkstraHelper(visited, sum, start, destination);
        return sum;
    }

    //main
    public static void main(String[] args){

        int[][] input = new int[][] { {-1, 2, 3, -1, -1, -1},
                          {2, -1, -1, 5, 2, -1},
                          {3, -1, -1, -1, 5, -1},
                          {-1, 5, -1, -1, 1, 2},
                          {-1, 2, 5, 1, -1, 4},
                          {-1, -1, -1, 2, 4, -1},
                        };
                        //-1 represents an non-existant path

        System.out.println(Dijkstra(convert(input)));
    }
}

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

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

发布评论

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

评论(2

九局 2024-07-29 08:05:13

您调用的二维数组的表示是图的邻接矩阵表示,您试图解决的问题是“单源最短路径”问题的一个实例。 Dijkstra 算法就是为了解决此类问题而设计的。 这可能会有所帮助 http://renaud.waldura.com/doc/java/dijkstra/。 从网站下载代码并阅读文档。 基本上你需要编写类似于以下的代码

    RoutesMap map = map =  new DenseRoutesMap(5);
    map.addDirectRoute(City.A, City.B, 2);
    map.addDirectRoute(City.A, City.C, 3);
    map.addDirectRoute(City.B, City.A, 2);
    map.addDirectRoute(City.B, City.D, 5);
    map.addDirectRoute(City.B, City.D, 2);
    ...
    DijkstraEngine engine = new DijkstraEngine(map);
    int distance = engine.getShortestDistance(City.F);

The representation that you are calling 2D array, is the Adjacency matrix representation of a graph and the problem you are trying to solve is an instance of 'Single-Source Shortest Paths' problem. Dijkstra's algorithm is designed to solve this type of problem. This might be helpful http://renaud.waldura.com/doc/java/dijkstra/. Download the code from the site and read the documentation. Basically you will need to write code similar to following

    RoutesMap map = map =  new DenseRoutesMap(5);
    map.addDirectRoute(City.A, City.B, 2);
    map.addDirectRoute(City.A, City.C, 3);
    map.addDirectRoute(City.B, City.A, 2);
    map.addDirectRoute(City.B, City.D, 5);
    map.addDirectRoute(City.B, City.D, 2);
    ...
    DijkstraEngine engine = new DijkstraEngine(map);
    int distance = engine.getShortestDistance(City.F);
花之痕靓丽 2024-07-29 08:05:13

不知道是否有人仍然对 Dijikstra 的矩阵表示感兴趣,但我一直在考虑在 Actionscript 中编写 Dijikstra 代码,因此首先必须自学 Dijikstra 的工作原理。 完成此操作并尝试对其进行编码后,我直到昨晚才意识到我可以表示矩阵中的节点和距离,就像您在这篇文章的顶部一样。 我的理论是,找到最短路径将是一件非常简单的事情。 我仍在尝试以确保我的正确性。

在矩阵中;

abcdeza - 2 3 - - -
b 2 - - 5 2 -
c 3 - - - 5 -
d - 5 - - 1 2
e-2 5 1-4
z - - - 2 4 -

我开始查看“a”行(因为这是起点)并选择该行中最小的数字 2(在 b 下)。 因此,我将路径写为“a - b”,成本为 2。然后我转到 b 行,再次找到 b 右侧的最小数字(因为我们已经位于 b 节点。这给了我 2所以路径现在是“a - b - e”,总成本为 4。 i 然后查看“e”行,规则应该是找到“e”列之后出现的最小数字。这会给我“z”,并给出完整路径“a - b - e - z”,总成本为 8。但是,请记住我昨晚才弄清楚这一点,该方法需要认识到,在查看时“e”行的另一种可能性是以 1 的成本转到 d 列。然后查看 d 行以查找 d 行之后的最低数字,这将以 2 的成本给出“z”行。

因此这是一个更好的解决方案,路径为“a - b - e - d -z”,正如你所说的那样,总成本为 7

好吧,我仍然需要在 Actionscript 中对此进行编码,但我的直觉是这会非常困难。恐怕我没有 Java 经验,但如果您同意我的方法,那么用 Java 编码应该很容易。

保罗

Dont know if anyone is still interested in this matrix representation of Dijikstra but I have been thinking about coding Dijikstra in Actionscript and so first had to teach myself how Dijuikstra worked. Having done that and in trying to code it I realised only last night that I could represent the nodes and there distances in a matrix such as you have on top of this post. My theory is then that finding the shortest path will be a very simple matter. I am still experimenting to ensure that I correct.

In the matrix;

a b c d e z
a - 2 3 - - -
b 2 - - 5 2 -
c 3 - - - 5 -
d - 5 - - 1 2
e - 2 5 1 - 4
z - - - 2 4 -

I start looking at row "a" (since this is the starting point) and pick the smallest number in the row being 2 (under b). So I write the path as "a - b" at a cost of 2. Then I go to the b row and again find the smallest number to the RIGHT of b (since we are already at the b node. This gives me 2 under the "e". So the path is now "a - b - e" at a total cost of 4. i Then look at the "e" row and the rule should be find the smallest number appearing after the "e" column. This would give me "z" and give the full path as "a - b - e - z" and a total cost of 8. However, and remember I only figured this out last night, the methodology needs to recognise that while looking at the "e" row another possibility is to go to the d column at a cost of 1. Then look at the d row for the lowest number after the d row which will give me the "z" row at a cost of 2.

Hence this is a better solution with the path being "a - b - e - d -z" at a total cost of 7 as you correctly said.

OK I still need to code this in Actionscript but my gut feeling is that it will be very easy to code in Actionscript. Afraid I have no experince in Java but if you agree with my method it should be easy to code in Java.

Paul

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