Алгоритм Дейкстры для двумерного массива в Java - PullRequest
7 голосов
/ 01 июня 2009

Это для школьного проекта; У меня огромные проблемы, и я не могу найти понятного решения.

   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) - он перенесет вас в новую строку для соседней строки пути

Кто-нибудь может помочь мне реализовать алгоритм Дейкстры для этого примера? Я действительно ценю это. (Кажется, мне больше всего нравятся массивы, карты и наборы меня немного смущают, списки управляемы, хотя сейчас я готов рассмотреть любое решение)

[По крайней мере, я не просто вырываю источник из сети. Я на самом деле хочу научиться этим вещам ... Это просто очень трудно (>. <)] </p>

О, начальная точка A, а конечная точка Z


Как и большинство людей, я не нахожу концепцию алгоритма сложной - я просто вижу, как правильно написать кодировку ... Помогите, пожалуйста?

Пример кода - друг очень помог мне с этим (хотя он заполнен структурами данных, которые мне трудно отслеживать) Я также пытался адаптировать код C ++ из dreamincode.net/forums/blog/martyr2/index .php? 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)));
    }
}

Ответы [ 2 ]

9 голосов
/ 01 июня 2009

Представление, которое вы называете двумерным массивом, является представлением графа в матрице смежности, а проблема, которую вы пытаетесь решить, является экземпляром проблемы «Кратчайшие пути из одного источника». Алгоритм Дейкстры предназначен для решения этого типа проблемы. Это может быть полезно 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);
0 голосов
/ 26 июля 2010

Не знаю, заинтересован ли кто-либо еще в этом матричном представлении Dijikstra, но я думал о кодировании Dijikstra в Actionscript и поэтому сначала должен был научиться сам, как работает Dijuikstra. Сделав это и попытавшись закодировать его, я только вчера понял, что могу представить узлы и расстояния в матрице, как у вас в верхней части этого поста. Моя теория заключается в том, что поиск кратчайшего пути будет очень простым делом. Я все еще экспериментирую, чтобы убедиться, что я исправлюсь.

В матрице;

a b c d e z а - 2 3 - - - б 2 - - 5 2 - с 3 - - - 5 - д - 5 - - 1 2 е - 2 5 1 - 4 z - - - 2 4 -

Я начинаю смотреть на строку "a" (поскольку это начальная точка) и выбираю наименьшее число в строке, равное 2 (ниже b). Поэтому я записываю путь как «a - b» по цене 2. Затем я иду в строку b и снова нахожу наименьшее число справа от b (поскольку мы уже находимся в узле b. Это дает мне 2 под "e". Таким образом, путь теперь "a - b - e", общая стоимость которого равна 4. i Затем посмотрите на строку "e", и правило должно найти наименьшее число, появляющееся после столбца "e". Это дало бы мне «z» и полный путь в виде «a-b-e-z» и общую стоимость 8. Однако, и помните, я понял это только вчера вечером, методология должна признать, что, глядя на строка «е», другая возможность - перейти к столбцу d по цене 1. Затем посмотрите на строку d для наименьшего числа после строки d, что даст мне строку «z» со стоимостью 2.

Следовательно, это лучшее решение, когда путь "a - b - e - d -z", как вы правильно сказали, будет стоить 7.

ОК. Мне все еще нужно кодировать это в Actionscript, но у меня сложилось ощущение, что будет очень легко кодировать в Actionscript. Боюсь, у меня нет опыта работы с Java, но если вы согласны с моим методом, код на Java должен быть простым.

Пол

...