1. 程式人生 > 其它 >從Bellman Ford最短路徑演算法到Distance-Vector路由演算法

從Bellman Ford最短路徑演算法到Distance-Vector路由演算法

目錄

最短路徑演算法

路由器在建立路由表的時候,需要知道到其他伺服器節點的最短路徑,以確定檔案包的傳送方式。

尋找節點間最短路徑的演算法就是最短路徑演算法。常見的最短路徑演算法有Dijkstra演算法:對於一個節點而言,計算到其他節點的最短路徑,需要知道整個網路(N個節點)的相連路徑情況,再進行N次迭代計算最短路徑。使用該類演算法實現的路由演算法稱為Link-State路由演算法。這類演算法的基本方法是:每個節點先向其他所有節點發送本節點的路徑情況:和哪些節點相連,距離是多少。待收到其他所有節點的資訊後,進行一次完整的Dijkstra演算法計算從本節點出發的最短路徑。這類演算法的好處是:路徑計算過程中,迭代過程確保收斂,同時對於收到的錯誤路徑資訊能進行有效的檢驗(每個點都有一份完整的網路路徑資訊,某個節點處出現錯誤資訊容易發現及糾正)。

然而這類演算法每個節點都需要知道整個網路的路徑情況,這在範圍較大的公用網路中實現的代價可能比較大:如果沒有像在SDN中的一個集中的全域性控制器用以收集整個網路的情況,那所有節點都需要知道網路中其他所有節點的路徑情況,這會帶來很大的資料傳輸量,並使路由表的初始化過程十分緩慢。而基於Bellman Ford演算法的Distance-Vector(路徑向量)類路由演算法可以應對這個問題。這類演算法的特點是分散式實現及非同步迭代更新。

Bellman Ford演算法

對於一個n個節點,m條邊的圖,生成從節點p到其他所有節點的最短路徑:

1. 初始化距離:對於目標節點p,p到自身的距離d(p)=0,到其餘節點的距離d(i)初始化為無限大。

2. 進行n次迭代(或鬆弛relax):每次迭代中,遍歷圖中的每條邊eij(從點i到點j),如果p到邊起點i的最小距離d(i)加上邊長度eij小於p到邊終點的最小距離d(j),即d(i) + eij < d(j),則更新p到j的最小距離(鬆弛)為d(i) + eij。

因為p到其他任意節點的最短路徑最多隻會通過n個節點,因此上面的n次迭代能確保找到圖中存在的最短路徑(即確保最後的d(i)為最小值)。

演算法一共n次迭代,每次迭代都遍歷所用的m條邊進行距離更新,因此整個演算法的時間複雜度為O(nm)。

需要注意到的是,在每次迭代中,除了更新儲存的最短路徑外,其餘內容(圖中每條邊的距離)都是相對獨立的,這也就給這個演算法的拓展提供了空間:將演算法改進為分散式非同步迭代更新(每個節點計算最短路徑的迭代過程按各節點情況獨立進行),這就是下面要介紹的Distance-Vector演算法。

Distance-Vector(路徑向量)路由演算法

Distance-Vector演算法沿用了Bellman Ford演算法的基本思想 --Bellman Ford等式。

d(i) = min {d(j) + eij}

上面這個等式的意思是說,點p到點i的最短距離,等於這個變數的最小值:點p到任意點j的最短距離(d(j)),加上點i、點j間的距離(eij)。

這個說法可能有點繞,更直接和形象化的說法是這樣:要找到點p到點i間的最短路徑,分成兩步 -- 1.找到這個路徑的第一個(或最後一個)中間節點j。2.再找到點j和點p間的最短路徑。這看起來沒什麼意義,但是有一個重大的作用:確定了這個路徑間的一個節點j。依次迭代這樣的做法,那麼路徑中的所用節點就都能確定了。

事實上,對路由表來說,確定這個路徑的下一個節點就夠了:路由器把檔案轉發給那個節點對應的介面就完成工作了,後面的傳遞由其他的路由器完成。而這種依次確定下一個節點的思想,也在強化學習(Reinforcement learning)中的Q-學習(Q-learning)中有體現。

基於這個Bellman Ford等式,就有了下面的Distance-Vector演算法:

1.節點p初始化自己的距離向量(Distance Vector,也是這個演算法名字的由來)-- 到各個節點的最短距離,p到自身的距離d(p)=0,到相鄰節點的距離為邊的長度d(i) = epi,到其餘非相鄰節點的距離d(i)初始化為無限大。

2. 節點p向所用相鄰節點發送自己的距離向量。

3. 在收到其他節點發送的距離向量後,更新自己的距離向量。如果有變動,則重新發送自己的距離向量。一直持續這個過程。從理論上可以證明,如果網路狀況是穩定的, 這個過程會收斂到最短路徑。

這裡我們可以看到,在整個演算法的執行過程中,每個節點的距離向量(也就是路由表)都是獨立持續更新的。這就保證了無論網路多大,每個路由器始終都保有一份可用的路由表,並且會根據周圍節點傳來的資訊不斷更新。這在一定程度上解決了Link-State路由演算法初始化速度較慢,傳送資料較多(Distance-Vector只向相鄰節點發送路由表)的問題。

當然,Distance-Vector演算法也有自己的問題,比如收斂到最短路徑的速度會比較慢,如果網路狀況出現變化,最短路徑更新過程也可能比較慢。而這也是很多分散式演算法會存在的問題。

最後的話

從上面我們可以看到,理論上的演算法在實際應用中,可以根據不同的實際需求進行相應的改進,以適合實際的任務需求。但是改進後的演算法在實際應用中的表現,仍然在很大程度上取決於原演算法的理論性質。這就是演算法在理論研究與實際應用中的不同的分工與側重。