一 区别
最小生成树能够保证整个拓扑图的所有路径之和最小,但不能保证任意两点之间是最短路径。
最短路径是从一点出发,到达目的地的路径最小。
二 实现方法
1. 最小生成树
最小生成树有两种算法来得到:Prims算法和Kruskal算法。
Kruskal算法:根据边的加权值以递增的方式,一次找出加权值最低的边来构建最小生成树,而且规定:每次添加的边不能造成生成树有回路,知道找到N-1个边为止。
Prims算法:以每次加入一个的临界边来建立最小生成树,直到找到N-1个边为止。其规则为:以开始时生成树的集合(集合U)为起始的定点,然后找出与生成树集合邻接的边(集合V)中,加权值最小的边来建立生成树,为了确定新加入的边不会造成回路,所以每一个新加入的边,只允许有一个顶点在生成树集合中,重复执行此步骤,直到找到N-1个边为止。
下面是一段实现Prims算法的代码:


[java]  view plain copy print ?

    1. while(alreadyVisited.size() != Switches.size())  
    2. {  
    3.     Vector neighbors = getNeighborSet(topo, Switches, alreadyVisited);  
    4. new Vector();  
    5. int cost = 40000000;  
    6. null, dstsw = null;  
    7. for(int i = 0;i < neighbors.size();i++)  
    8.     {  
    9.         ASwitch sw1 = (ASwitch)neighbors.get(i);  
    10. for(int j = 0;j < alreadyVisited.size();j++)  
    11.         {  
    12.             ASwitch sw2 = (ASwitch)alreadyVisited.get(j);  
    13. int tempcost = getCost(topo, sw1, sw2, insid, "legacy");  
    14. if( (tempcost > 0) && (tempcost < cost ))  
    15.             {  
    16.                 cost = tempcost;  
    17.                 srcsw = sw1;  
    18.                 dstsw = sw2;  
    19.             }  
    20.         }  
    21. //end for neighbors  
    22. //得到一个最小花费的邻居  
    23.     alreadyVisited.add(srcsw);  
    24.       
    25. new treenode();  
    26.     temptr.Mac = srcsw.SWName;  
    27.     current.childlist.push(temptr);  
    28.     current = temptr;  
    29. }//end while


    2 最短路径



    算法描述


      (这里描述的是从节点1开始到各点的dijkstra算法,其中Wa->b表示a->b的边的权值,d(i)即为最短路径值)


      1. 置集合S={2,3,...n},  数组

    d(1)=0, d(i)=W1->i(1,i之间存在边) or +无穷大(1.i之间不存在边)

      2. 在S中,令d(j)=min{d(i),i属于S},令S=S-{j},若S为空集则算法结束,否则转3


      3. 对全部i属于S,如果存在边j->i,那么置d(i)=min{d(i), d(j)+Wj->i},转2


      Dijkstra算法思想为:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , 就将 加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。


      算法具体步骤 


      (1)初始时,S只包含源点,即S=,v的距离为0。U包含除v外的其他顶点,U中顶点u距离为边上的权(若v与u有边)或  ∞ (若u不是v的出边邻接点)。


      (2)从U中选取一个距离v最小的顶点k,把k,加入S中(该选定的距离就是v到k的最短路径长度)。


      (3)以k为新考虑的中间点,修改U中各顶点的距离;若从源点v到顶点u(u U)的距离(经过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值为顶点k的距离加上边上的权。


      (4)重复步骤(2)和(3)直到所有顶点都包含在S中。

    复杂度分析


      Dijkstra 算法的时间复杂度为O(n^2)


      空间复杂度取决于存储方式,邻接矩阵为O(n^2)




    下面是一段最短路径算法的代码:


    [java]  view plain copy print ?


    1. while(Visited.size() != Switches.size())  
    2. {  
    3. for(int i = 0;i < alreadyVisited.size(); i ++)  
    4.     {  
    5.         ASwitch sw1 = (ASwitch)alreadyVisited.get(i);  
    6. "already visited: "+sw1.SWName);  
    7.         Vector ng = getNeighbors(topo, Switches, sw1);  
    8.         alreadyVisited.remove(sw1);  
    9. //Visited.add(sw1);  
    10.         Visited = addtoVector(Visited,sw1);  
    11. for(int j = 0;j < ng.size();j++)  
    12.         {  
    13.             ASwitch sw2 = (ASwitch)ng.get(j);  
    14. if((swValue.get(sw2) == 0) ) continue;  
    15. int tempcost = -1;  
    16. int tcost = getCost(topo, sw1, sw2, insid, "legacy");;  
    17. if(tcost >0 ) tempcost = swValue.get(sw1)+tcost;  
    18. if((tempcost > 0) && (tempcost < swValue.get(sw2)))  
    19.             {  
    20.                 swValue.put(sw2, tempcost);  
    21.                 presw.put(sw2, sw1);  
    22. "sw: "+sw2.SWName+"   cost: "+tempcost+"   presw: "+sw1.SWName);  
    23.                   
    24.                 alreadyVisited.add(sw2);  
    25.   
    26.             }  
    27.         }  
    28.     }  
    29. }