迪科斯彻算法(Dijkstra)的一个java实现(有向图)

  1. import java.util.ArrayList;  
  2. import java.util.HashMap;  
  3. import java.util.HashSet;  
  4. import java.util.List;  
  5. import java.util.Map;  
  6. import java.util.Set;  
  7. /** 
  8.  * 迪科斯彻算法(Dijkstra)是由荷兰计算机科学家艾兹格•迪科斯彻(Edsger Wybe Dijkstra)发明的。 
  9.  * 算法解决的是有向图中单个源点到其他顶点的最短路径问题。<br /> 
  10.  * 算法参考:<a href=”http://zh.wikipedia.org/w/index.php” mce_href=”http://zh.wikipedia.org/w/index.php”>http://zh.wikipedia.org/w/index.php</a> 
  11.  * @author czs 
  12.  * 
  13.  */  
  14. public class Dijkstra {  
  15.     private int [][] graph;//加权有向图    
  16.     private int start;//源点编号 从 0开始  
  17.     private int dimention;  
  18.     static int INF  = Integer.MAX_VALUE /100 ;  
  19.     //用于标记顶点是否已经计算  
  20.     private Set<Integer> vertexSet = new HashSet<Integer>();      
  21.     //存储结果,Map的key对应各终点编号,value对应路径编号列表。  
  22.     private Map<Integer, List<Integer>> pathListMap = new HashMap<Integer, List<Integer>>();  
  23.     /** 
  24.      * 构造函数,必须初始化路径矩阵和起始点 
  25.      * @param graph 
  26.      * @param start 
  27.      */  
  28.     public Dijkstra(int[][] graph, int start) {  
  29.         this.graph = graph;  
  30.         this.start = start;  
  31.         this.dimention = graph.length;        
  32.         calculate();  
  33.     }  
  34.     /** 
  35.      * 计算函数 
  36.      */  
  37.     private void calculate()  {  
  38.         //初始化  
  39.         for(int end=0; end<dimention; end++){  
  40.             if(end == start){ continue; }//起始点自己的路径排除。  
  41.             List<Integer> pathList =  new ArrayList<Integer>();  
  42.             pathList.add( start );//每条路径的起始点都为start,pathList只记录编号,不记录路径权值  
  43.             pathList.add( end );//每条路径的第二个参数为终点编号  
  44.             pathListMap.put(end, pathList);               
  45.         }     
  46.         //计算主体  
  47.         for(int bridge=0; bridge<dimention; bridge++){  
  48.             if(bridge == start){ continue; }  
  49.             if(!vertexSet.contains(bridge)){//确保每个基点只循环计算一次  
  50.                 for(int next=0; next<dimention; next++){  
  51.                     if(next == start || next==bridge ){ continue; }                       
  52.                     if(startTo(bridge) + getRawLength(bridge, next) < startTo(next) ){  
  53.                         List<Integer> pathList =  pathListMap.get(next);  
  54.                         List<Integer> bridgePathList =  pathListMap.get(bridge);  
  55.                         //清空,使用新的  
  56.                         pathList.clear();  
  57.                         pathList.addAll( bridgePathList );  
  58.                         pathList.add( next );  
  59.                     }  
  60.                 }  
  61.             }  
  62.             vertexSet.add(bridge);  
  63.         }     
  64.         //检查,是否桥接的路径都被更新          
  65.         for(int end=0; end<dimention; end++){  
  66.             if(end == start){ continue; }  
  67.             List<Integer> pathList =  pathListMap.get(end);     
  68.             int size = pathList.size();  
  69.             if(size>2){                
  70.                 for(int end2=0; end2<dimention; end2++){  
  71.                     int isEnd = pathList.get(size-2 );  
  72.                     if(end2 == isEnd){  
  73.                         pathList.clear();  
  74.                         pathList.addAll(  pathListMap.get(end2) );  
  75.                         pathList.add( end );  
  76.                     }  
  77.                 }                 
  78.             }             
  79.         }  
  80.     }  
  81.     /** 
  82.      * 获取当前指定路径的长度 
  83.      * @param start 
  84.      * @param end 
  85.      * @return 
  86.      */  
  87.     private int startTo(int end) {   
  88.         int pathLen = 0;           
  89.         List<Integer> pathList = pathListMap.get(end);  
  90.         for(int i=0;i< pathList.size()-1;i++){  
  91.             pathLen += graph[pathList.get(i)][pathList.get(i+1)];  
  92.         }  
  93.         return pathLen;  
  94.     }  
  95.     /** 
  96.      * 直接提取矩阵中的相邻路径。 
  97.      * @param start 
  98.      * @param end 
  99.      * @return 
  100.      */  
  101.     private int getRawLength(int start, int end) {   
  102.         if(end == start){  
  103.             return 0;  
  104.         }  
  105.         return graph[start][end];  
  106.     }  
  107.     /** 
  108.      * 得到指定目标的路劲长度 
  109.      * @param end 
  110.      * @return 
  111.      */  
  112.     public int getLength(int end) {   
  113.         if(end == start){  
  114.             return 0;  
  115.         }  
  116.         return startTo(end);  
  117.     }  
  118.     /** 
  119.      * 在控制台打印输出所有路径编号 
  120.      */  
  121.     public void printResult(){  
  122.         System.out.println( pathListMap);  
  123.     }  
  124.     /** 
  125.      * 所有路径编号 
  126.      * @return 
  127.      */  
  128.     public Map<Integer, List<Integer>> getPathListMap() {  
  129.         return pathListMap;  
  130.     }  
  131.     /** 
  132.      * Test out put 
  133.      * @param args 
  134.      */  
  135.     public static void main(String[] args) {  
  136.         /*   
  137.         int [][] graph = { 
  138.                 { INF,  10, INF,  30, 100}, 
  139.                 { INF, INF,  50, INF, INF}, 
  140.                 { INF, INF, INF, INF,  10}, 
  141.                 { INF, INF,  20, INF,  60}, 
  142.                 { INF, INF, INF, INF, INF}};*/  
  143.         int[][] graph={  
  144.                 {INF, INF, 10 , INF, 30 , 100},  
  145.                 {INF, INF, 5  , INF, INF, INF},  
  146.                 {INF, INF, INF, 50 , INF, INF},  
  147.                 {INF, INF, INF, INF, INF, 10 },  
  148.                 {INF, INF, INF, 20 , INF, 60 },  
  149.                 {INF, INF, INF, INF, INF, INF},  
  150.         };  
  151.         int start = 0;  
  152.         int end = 0;  
  153.         int length = graph.length;  
  154.         for(start=0; start<length; start++){  
  155.             System.out.println();  
  156.             Dijkstra dijkstra = new Dijkstra(graph, start);  
  157.             dijkstra.printResult();  
  158.             for(end=0; end<length; end++){  
  159.                 if(end == start){ continue;}  
  160.                 int len = dijkstra.getLength( end );  
  161.                 System.out.println( ” Length(“ + start + “-“  + end + “) = “ +  ( (len == INF)? “Infinity” : len )  );                
  162.             }  
  163.         }  
  164.     }  
    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/u013454060/article/details/41832283
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞