All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.venky.network.shortestpath.Dijkstra Maven / Gradle / Ivy

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.venky.network.shortestpath;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;

import com.venky.network.Edge;
import com.venky.network.Network;
import com.venky.network.Node;

/**
 *
 * @author venky
 */
public class Dijkstra extends Network{
    public final String LENGTH = "length";
    public Path shortestPath(int from,int to){
        final Map distanceHash = new HashMap();
        final Map previousHash = new HashMap();
        
        List path = new ArrayList();
        //Node source = getNode(from);
        for (int nodeId :getNodes()){
            distanceHash.put(nodeId, Integer.MAX_VALUE);
            previousHash.put(nodeId, null);
        }
        distanceHash.put(from, 0);
        PriorityQueue q = new PriorityQueue(getNodes().size(),new Comparator(){

            public int compare(Integer o1, Integer o2) {
                int ret = distanceHash.get(o1) - distanceHash.get(o2);
                if (ret == 0){
                    ret = o1  - o2; 
                }
                return ret;
            }
            
        });
        q.addAll(getNodes());
        
        while (!q.isEmpty()){
            Integer u = q.poll();
            if (distanceHash.get(u) == Integer.MAX_VALUE){
                break;
            }
            Node n = getNode(u);
            for (Edge e : n.getEdges()){
                Integer v = e.getConnectedNode(u);
                int edge_length = (Integer)e.getAttribute(LENGTH);
                int alt = distanceHash.get(u) + edge_length;
                if (distanceHash.get(v) > alt){
                    q.remove(v);
                    previousHash.put(v,u);
                    distanceHash.put(v,alt);
                    q.offer(v);
                }
            }
            
        }
        if (distanceHash.get(to) == Integer.MAX_VALUE) {
            throw new RuntimeException("Cannot reach destination from source");
        }
        
        int curr = to; 
        while (curr != from ){
            path.add(curr);
            curr = previousHash.get(curr);
        }
        path.add(from);
        Collections.reverse(path);
        
        return new Path(path);
    }
    
    
    public class Path { 
        List nodeSequence =new ArrayList();
        List edgeSequence = new ArrayList(); 
        int length = 0;
        public Path(List nodeList){
            this.nodeSequence.addAll(nodeList);
            
            Iterator nodeIterator = nodeSequence.iterator(); 
            int current = nodeIterator.next(); 
            while (nodeIterator.hasNext()){
                int next = nodeIterator.next(); 
                Edge e = getEdge(current, next);
                edgeSequence.add(e);
                int edgeLength = (Integer)e.getAttribute(LENGTH);
                length += edgeLength;
                current = next;
            }
        }
        
        public int getLength(){ 
            return length;
        }

        public List getEdgeSequence() {
            return edgeSequence;
        }

        public List getNodeSequence() {
            return nodeSequence;
        }
        
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy