最小生成樹與最短路徑的區別以及實現方法
阿新 • • 發佈:2019-02-14
一 區別
最小生成樹能夠保證整個拓撲圖的所有路徑之和最小,但不能保證任意兩點之間是最短路徑。
最短路徑是從一點出發,到達目的地的路徑最小。
二 實現方法
1. 最小生成樹
最小生成樹有兩種演算法來得到:Prims演算法和Kruskal演算法。
Kruskal演算法:根據邊的加權值以遞增的方式,一次找出加權值最低的邊來構建最小生成樹,而且規定:每次新增的邊不能造成生成樹有迴路,知道找到N-1個邊為止。
Prims演算法:以每次加入一個的臨界邊來建立最小生成樹,直到找到N-1個邊為止。其規則為:以開始時生成樹的集合(集合U)為起始的定點,然後找出與生成樹集合鄰接的邊(集合V)中,加權值最小的邊來建立生成樹,為了確定新加入的邊不會造成迴路,所以每一個新加入的邊,只允許有一個頂點在生成樹集合中,重複執行此步驟,直到找到N-1個邊為止。
下面是一段實現Prims演算法的程式碼:
2 最短路徑while(alreadyVisited.size() != Switches.size()) { Vector neighbors = getNeighborSet(topo, Switches, alreadyVisited); Vector CostOfNeighbors = new Vector(); int cost = 40000000; ASwitch srcsw = null, dstsw = null; for(int i = 0;i < neighbors.size();i++) { ASwitch sw1 = (ASwitch)neighbors.get(i); for(int j = 0;j < alreadyVisited.size();j++) { ASwitch sw2 = (ASwitch)alreadyVisited.get(j); int tempcost = getCost(topo, sw1, sw2, insid, "legacy"); if( (tempcost > 0) && (tempcost < cost )) { cost = tempcost; srcsw = sw1; dstsw = sw2; } } }//end for neighbors //得到一個最小花費的鄰居 alreadyVisited.add(srcsw); treenode temptr = new treenode(); temptr.Mac = srcsw.SWName; current.childlist.push(temptr); current = temptr; }//end while
演算法描述
(這裡描述的是從節點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有邊)或 ∞下面是一段最短路徑演算法的程式碼:
while(Visited.size() != Switches.size())
{
for(int i = 0;i < alreadyVisited.size(); i ++)
{
ASwitch sw1 = (ASwitch)alreadyVisited.get(i);
System.out.println("already visited: "+sw1.SWName);
Vector ng = getNeighbors(topo, Switches, sw1);
alreadyVisited.remove(sw1);
//Visited.add(sw1);
Visited = addtoVector(Visited,sw1);
for(int j = 0;j < ng.size();j++)
{
ASwitch sw2 = (ASwitch)ng.get(j);
if((swValue.get(sw2) == 0) ) continue;
int tempcost = -1;
int tcost = getCost(topo, sw1, sw2, insid, "legacy");;
if(tcost >0 ) tempcost = swValue.get(sw1)+tcost;
if((tempcost > 0) && (tempcost < swValue.get(sw2)))
{
swValue.put(sw2, tempcost);
presw.put(sw2, sw1);
System.out.println("sw: "+sw2.SWName+" cost: "+tempcost+" presw: "+sw1.SWName);
alreadyVisited.add(sw2);
}
}
}
}