zoukankan      html  css  js  c++  java
  • Dijkstra 算法

     今天又翻了翻算法导论,看了看dijstra算法。兴趣来了就实现了下。完全按照书上的步骤实现,没有使用最小堆等数据结构,使用的邻接表方式表示图。因此实现的算法效率很抵,不过这里只是想通过程序来说明这个算法。不是工程上用的。如果工程上使用,最好用矩阵表示图,然后再使用最小堆。。。。不多说了,直接上代码。

    (原理参见算法导论第二版p366)

    package Graph;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Stack;
    
    
    public class Dijkstra2 {
    	private AdjacencyList adjList = new AdjacencyList();
    	public static void main(String[] args) {
    		try{
    			double[][] matrix = { 
    					{ util.max, 5, util.max, util.max, 10 }, 
    					{ util.max, util.max, 2, 9, 3 },
    					{ 7, util.max, util.max, 6, util.max },
    					{ util.max, util.max, 4 , util.max, util.max },
    					{ util.max, 2, util.max, 1, util.max } 
    					};
    			
    			Dijkstra2 dijkstra = new Dijkstra2(matrix);
    			
    			dijkstra.adjList.print();
    			dijkstra.calculate(0);
    			dijkstra.print();
    			
    		}catch(Exception e){
    			e.printStackTrace();
    		}
    	}
    	
       public Dijkstra2(double [][] matrix){
    	   adjList = new AdjacencyList(matrix);
       }
       //存储前驱节点
       private int [] pre ;
       //存储距离
       private double [] dist;
       /**
        * @function 计算最近路径
        * @param v 源点
        */
       public void calculate(int v){
    	   pre = new int [this.adjList.size()];
    	   dist = new double[this.adjList.size()];
    	   //s序列,存放
    	   boolean [] s = new boolean [this.adjList.size()];
    	   
    	   //初始化距离
    	   Arrays.fill(dist, util.max);
    	   //初始化前驱节点
    	   Arrays.fill(pre, -1);
    	   //初始队列s中没有点
    	   Arrays.fill(s, false);
    	   
    	   //源点的距离为0
    	   dist[v] = 0;
    	   int gray = v;
    	  
    	   while(true){
    		   //找出距离最小的点
    		   double mindis = Double.MAX_VALUE;
    		   for(int i = 0 ; i < dist.length ; i++){
    			   if(mindis > dist[i] && !s[i]){
    				   mindis = dist[i];
    				   gray = i;
    			   }
    		   }
    		   //把找到的这个点加入到s队列中
    		   s[gray] = true;
    		   
    		   //======对与gray点有边的点进行松驰=====
    		   Node pnode = adjList.get(gray);
    		   //向后移一个节点,因为第一个节点是自己。后面的点才是当前节点的后继节点。
    		   pnode = pnode.next;
    		   while(pnode != null){
    			   //后继节点与当前节点的距离 + 当前节点与源点的距离   < 	后继节点到源点的距离
    			   if(pnode.weight + mindis < dist[pnode.index]){
    				   //后继节点的到源点的距离 更新 为 后继节点与当前节点的距离 + 当前节点与源点的距离
    				   dist[pnode.index] = pnode.weight + mindis;
    				   //后继节点的前驱节点更新为 当前节点
    				   pre[pnode.index] = adjList.get(gray).index;
    			   }
    			   //下一个后继节点
    			   pnode = pnode.next;
    		   }
    		   
    		   //===判断s中是否包含全部的点了
    		   boolean con = false;
    		   for(boolean b : s)
    			   if(b == false){
    				   con = true;
    				   break;
    			   }
    		   if(!con)
    			   break;
    		   
    	   }
    	   
       }
    	
     
    	public void print() {
    		for(int i = 0 ; i < dist.length ; i++){
    			System.out.print(dist[i] + "	");
    			printpath(i);
    			System.out.println();
    		}
    	}
    
    	public void printpath(int v){
    		Stack<Integer> stack = new Stack<Integer>(); 
    		while(pre[v] >= 0){
    			stack.add(pre[v]);
    			v = pre[v];
    		}
    		while(stack.size() > 0)
    			System.out.print(stack.pop() + "	");
    	}
       public double getWeight(Node node , int index){
    	   while(node != null){
    		   int ndx = node.index;
    		   if(ndx == index)
    			   return node.weight;
    		   node = node.next;
    	   }
    	   return util.max;
       }
    }
    
    class AdjacencyList{
    	
    	private List<Node> adjList = new ArrayList<Node>();
    	public AdjacencyList(){};
    	
    	public int size(){
    		return adjList.size();
    	}
    	public Node get(int index){
    		return this.adjList.get(index);
    	}
    	public List<Node> getData(){
    		return this.adjList;
    	}
    	public AdjacencyList(double [][] matrix){
    		for(int i = 0 ; i < matrix.length ; i++){
    			double [] vals = matrix[i];
    			addData(i , vals);
    		}
    	}
    	
    	public void addData(int v , double [] vals){
    		Node  node = new Node(v , 0);
    		Node head = node;
    		for(int j = 0 ; j < vals.length ; j++){
    			if(vals[j] < util.max && vals[j] != 0.0){
    				node.next = new Node();
    				node = node.next;
    				node.set( j , vals[j]);
    			}
    		}
    		adjList.add(head);
    	}
    	
    	public void print(){
    		for(Node node : adjList){
    			while(node != null){
    				System.out.print(node.toString() + "	");
    				node = node.next;
    			}
    			System.out.println();
    		}
    	}
    }
    
    
    class Node{
    	Node next;
    	double weight = util.max;
    	int index = -1;
    	public Node(){
    		
    	}
    	
    	public Node(int index , double weight){
    		set(index , weight);
    	}
    	public void set(int index , double weight){
    		this.index = index;
    		this.weight = weight;
    	}
    	@Override
    	public String toString() {
    		// TODO Auto-generated method stub
    		return "[ " + index + " , " + weight + " ]"; 
    	}
    }
    
    class util{
    	public static double max = Double.MAX_VALUE;
    }
    

      

  • 相关阅读:
    多线程
    ERP概念介绍
    Servlet生命周期
    springmvc工作流程
    spring事务管理的接口
    解决主从备份Slave_SQL_Running:No
    实现Mysql主从备份
    springboot集成mybatis进行开发
    SpringBoot 入门第一章
    Hibernate 关联关系映射
  • 原文地址:https://www.cnblogs.com/nocml/p/3634583.html
Copyright © 2011-2022 走看看