7 Stimmen

Dijkstra-Algorithmus für 2D-Arrays in Java

Es handelt sich um ein Schulprojekt, das mir große Schwierigkeiten bereitet, und ich kann keine verständliche Lösung finden.

   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 -

Das ist das zweidimensionale Array. Wenn du also den kürzesten Weg finden willst, ist es von a,b,e,d,z = 7, und (a,b) = (b,a) -- es bringt dich zur neuen Zeile für die angrenzenden Wege der Zeile

Kann mir jemand bei der Implementierung des Dijkstra-Algorithmus für dieses Beispiel helfen? Ich wäre sehr dankbar dafür. (Ich scheine Arrays am besten zu mögen, Maps und Sets verwirren mich ein wenig, Listen sind überschaubar - obwohl ich bereit bin, an dieser Stelle jede Art von Lösung zu prüfen)

[Wenigstens klaue ich nicht einfach eine Quelle aus dem Netz. Ich will diese Dinge wirklich lernen... Es ist nur wirklich schwer (>.<)]

Oh, Startpunkt ist A und Endpunkt ist Z


Wie die meisten Menschen, finde ich nicht das Konzept des Algorithmus schwierig - ich kann nur sehen, um die Codierung richtig zu bekommen... Hilfe bitte?

Beispielcode - ein Freund hat mir dabei sehr geholfen (obwohl er voller Datenstrukturen ist, die ich schwer nachvollziehen kann). Ich habe auch versucht, den C++-Code von dreamincode.net/forums/blog/martyr2/index.php?showentry=578 in Java zu übernehmen, aber das hat nicht so gut geklappt ...

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)));
    }
}

9voto

Babar Punkte 2766

Die Darstellung, die Sie 2D-Array nennen, ist die Adjazenzmatrix-Darstellung eines Graphen, und das Problem, das Sie zu lösen versuchen, ist eine Instanz des "Single-Source Shortest Paths" Problems. Dijkstras Algorithmus wurde entwickelt, um diese Art von Problem zu lösen. Dies könnte hilfreich sein http://renaud.waldura.com/doc/java/dijkstra/ . Laden Sie den Code von der Website herunter und lesen Sie die Dokumentation. Grundsätzlich müssen Sie Code ähnlich dem folgenden schreiben

    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);

0voto

Ich weiß nicht, ob noch jemand an dieser Matrix-Darstellung von Dijikstra interessiert ist, aber ich habe darüber nachgedacht, Dijikstra in Actionscript zu programmieren und musste mir daher erst einmal beibringen, wie Dijuikstra funktioniert. Als ich das getan hatte und versuchte, es zu programmieren, wurde mir erst gestern Abend klar, dass ich die Knoten und ihre Entfernungen in einer Matrix darstellen kann, wie Sie sie oben in diesem Beitrag haben. Meine Theorie ist dann, dass das Finden des kürzesten Weges eine sehr einfache Angelegenheit sein wird. Ich bin noch am Experimentieren, um sicherzustellen, dass ich richtig liege.

In der 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 -

Ich beginne mit der Zeile "a" (da dies der Startpunkt ist) und wähle die kleinste Zahl in der Zeile, die 2 ist (unter b). Also schreibe ich den Pfad als "a - b" mit Kosten von 2. Dann gehe ich zur Zeile "b" und finde wieder die kleinste Zahl RECHTS von b (da wir bereits am Knoten b sind). Dies gibt mir 2 unter dem "e". Der Pfad ist nun also "a - b - e" mit Gesamtkosten von 4. Dann schaue ich mir die "e"-Zeile an und die Regel sollte lauten: Finde die kleinste Zahl, die nach der "e"-Spalte steht. Dies würde "z" ergeben und den vollständigen Pfad "a - b - e - z" mit Gesamtkosten von 8. Allerdings, und das habe ich erst gestern Abend herausgefunden, muss die Methode erkennen, dass bei der Betrachtung der "e"-Zeile eine weitere Möglichkeit darin besteht, zur Spalte "d" zu gehen, was 1 kostet, und dann in der "d"-Zeile nach der kleinsten Zahl nach der "d"-Zeile zu suchen, was die "z"-Zeile mit Kosten von 2 ergibt.

Daher ist dies eine bessere Lösung mit dem Weg "a - b - e - d -z" bei Gesamtkosten von 7, wie Sie richtig sagten.

OK, ich muss das noch in Actionscript programmieren, aber mein Bauchgefühl sagt mir, dass es sehr einfach sein wird, in Actionscript zu programmieren. Ich fürchte, ich habe keine Erfahrung in Java, aber wenn Sie mit meiner Methode einverstanden sind, sollte es einfach sein, in Java zu kodieren.

Paul

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X