views:

3812

answers:

2

Hiya guys!! This is my first post, and 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 -

Thats 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 managable -though I'm willing to look into any sort of solution at this point)

[Hey -- 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

EDIT:: 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)));
    }
}
+4  A: 

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);
Babar
Unfortunately, that site doesn't help me much. It doesn't deal with 2D arrays like I need it too...Does anyone else have a solution/ suggestion?
Stan
I have updated my answer and added code sample.
Babar
@Babar: Nice way of nudging him in the right direction without spilling all the beans. +1
William Brendel
Very nice, TA-like answer :) +1.
Jared
@Stan - Babar is encouraging you to think about implementing the algorithm, not the data structures. That's definitely a better approach to learning the solution.
Jared
thanks guys-- I'll definitely look into the reading and implementation soon enough... Though it'd be mostly next week -- this week I'm mostly occupied. I'll post back when I get the chance/ time ;) !!
Stan
A: 

Hi

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

Paul Hinrichsen