(六)通俗易懂理解 viterbi演算法

2021-09-16 19:07:16 字數 3171 閱讀 5750

動態規劃是運籌學的乙個分支,是求解決策過程最優化的數學方法,通常情況下應用於最優化問題,這類問題一般有很多個可行的解,每個解有乙個值,而我們希望從中找到最優的答案。 在電腦科學領域,應用動態規劃的思想解決的最基本的乙個問題就是:尋找有向無環圖(籬笆網路)當中兩個點之間的最短路徑(實際應用於地圖導航、語音識別、分詞、機器翻譯等等)。 下面舉乙個比較簡單的例子做說明:求s到e的最短路徑。如下圖(各點之間距離不相同):

我們知道,要找到s到e之間最短路徑,最容易想到的方法就是窮舉法。也就是把所有可能的路徑都例舉出來。從s走向a層共有4種走法,從a層走向b層又有4種走法,從b層走向c層又有4種走法,然後c層走向e點只有一種選擇。所以最終我們窮舉出了4x4x4=64種可能。顯然,這種方法必定可行。但在實際的應用當中,對於數量極其龐大的結點數和邊數的圖,其計算複雜度也將會變得非常大,而計算效率也會隨之降低。

因此,這裡選擇使用一種基於動態規劃的方式來尋找最佳路徑。

所謂動態規劃。其核心就是「動態」的概念,把大的問題細分為多個小的問題,基於每一步的結果再去尋找下一步的策略,通過每一步走過之後的區域性最優去尋找全域性最優。這樣解釋比較抽象,下面直接用回剛剛的例子說明。如下圖:

首先,我們假設s到e之間存在一條最短路徑(紅色),且這條路徑經過c2點,那麼我們便一定能夠確定從s到c2的64條(4x4x4=64)子路徑當中,該子路徑一定最短。(證明:反證法。如果s到c2之間存在一條更短的子路徑,那麼便可以用它來代替原先的路徑,而原先的路徑顯然就不是最短了,這與原假設自相矛盾)。 同理,我們也可以得出從s到b2點為兩點間最短子路徑的結論。這時候,真相便慢慢浮出水面:既然如此,我們計算從s點出發到點c2的最短路徑,是不是只要考慮從s出發到b層所有節點的最短路徑就可以了?答案是肯定的!因為,從s到e的「全域性最短」路徑必定經過在這些「區域性最短」子路徑。沒錯!這就是上面提及到的通過區域性最優的最優去尋找全域性最優,問題的規模被不斷縮小! 接下來,要揭曉答案了!繼續看下圖:

回顧之前的分析:我們計算從s起到c2點的最短路徑時候只需要考慮從s出發到b層所有節點的最短路徑,b層也如是。對b2來說,一共有4條路線可以到達,分別是a1→b2,a2→b2,a3→b2,a4→b2。我們需要做的就是把a2→b2這條最短路線保留,而其他3條刪除掉(因為根據以上的分析,它們不可能構成全程的最短路線)。ok,來到這裡,我們會發現乙個小「漏洞」,這段s→a2→b2→c2→e的路線只是我一廂情願的假設,最短路徑不一定是經過以上這些點。所以,我們要把每層的每個節點都考慮進來。 以下是具體的做法: step1:從點s出發。對於第一層的3個節點,算出它們的距離d(s,a1),d(s,a2),d(s,a3),d(s,a4),因為只有一步,所以這些距離都是s到它們各自的最短距離。 step2:對於b層的所有節點(b1,b2,b3,b4),要計算出s到它們的最短距離。我們知道,對於特定的節點b2,從s到它的路徑可以經過a層的任何乙個節點(a1,a2,a3,a4)。對應的路徑長就是d(s,b2)=d(s,ai)+d(ai,b2)(其中i=1,2,3,4)。由於a層有4個節點(即i有4個取值),我們要一一計算,然後找到最小值。這樣,對於b層的每個節點,都需要進行4次運算,而b層有4個節點,所以共有4x4=16次運算。 step3:這一步是該演算法的核心。我們從step2計算得出的結果只保留4個最短路徑值(每個節點保留乙個)。那麼,若從b層走向c層來說,該步驟的基數已經不再是4x4,而是變成了4!也就是說,從b層到c層的最短路徑只需要基於b層得出的4個結果來計算。這種方法一直持續到最後乙個狀態,每一步計算的複雜度為相鄰兩層的計算複雜度為4x4乘積的正比!再通俗點說,連線這兩兩相鄰層的計算符合變成了「+」號,取代了原先的「x」號。用這種方法,只需進行4x4x2=32次計算! 其實上述的演算法就是著名的維特比演算法,事實上非常簡單!

重點:我在看第3步的時候還是有些懵逼,我個人一開始看他從終點開始倒推著說,並沒有解決我心中的疑惑,因為我一直想著點與點之間的權重不同,總覺得他忽略了什麼,直到step3還是沒能徹底理解,後面自己再重新思考下才真的明白其中含義(可能自己腦子太不好使)。

在上圖中,s到b層的距離中以b1為例,可以知道s-a1-b1,s-a2-b1,s-a3-b1,s-a4-b1四條路線的大小,因而可以知道有一條路徑比如s-a1-b1是s到b1的最短路徑。同樣的道理,可以知道4條路徑分別為s到b1,b2,b3,b4的最短路徑。也就是可以忽略了a層的存在,又直接考慮s到b層再到c層的最短路徑,繼續找到4條路徑分別為s層到c1,c2,c3,c4的最短路徑,依此迴圈,直至到達終點。

若假設整個網格的寬度為d,網格長度為n,那麼若使用窮舉法整個最短路徑的演算法複雜度為o(dn),而使用這種演算法的計算複雜度為o(nd2)。試想一下,若d與n都非常大,使用維特比演算法的效率將會提高幾個數量級! **實現(c語言版):

#同樣是實現從s到e的最短路徑。不過這次把剛剛的情況簡化了一下,原理是相同的。

#include#include#define x 9999

#define max 9999

int data[10][10];

int dist[10];//記錄最短路徑為多少

int path[10];//記錄最短路徑

int kmin(int,int);

void fpath(int a[10]);

int froute(int a[10]);

void main()

, ,,,

,,,,

,};/*for (i=0;i<10;i++)

*/fpath(a);

printf("最短路徑大小為: %d\n",dist[9]);

m=froute(a);

for(i=m-1;i>=0;i--)

printf("最短路徑經過: %d\n",path[i]);

}void fpath(int a[10])}}

} return k;

}

TCP IP協議六 通俗易懂說網路協議 ARP

將ip位址解析為乙太網mac位址 在網路傳輸中,主機a要發資料給主機b,那麼a需要知道b的ip位址才能通訊,由於ip位址必須要封裝成幀才能通過物理網路傳送,因此還需要知道對方的實體地址,所以裝置上需要存在乙個從ip位址到實體地址的對映關係,那麼arp應運而生。其中,每個欄位的含義如下。硬體型別 指明...

(十)通俗易懂理解 EM演算法

這篇文章不涉及數學原理上的說明,用簡單的例子說明了em演算法的出彩之處。001 乙個非常簡單的例子 假設現在有兩枚硬幣1和2,隨機拋擲後正面朝上概率分別為p1,p2。為了估計這兩個概率,做實驗,每次取一枚硬幣,連擲5下,記錄下結果,如下 可以很容易地估計出p1和p2,如下 p1 3 1 2 15 0...

通俗易懂 理解「委託」

委託的意義在於實現多型 在於讓物件能夠在程式執行時滿足外界對其的改變。1 乙個物件屬性 動作,如果在編譯時就能確定,可以在這個物件的類裡面來實現。2 乙個物件的屬性 動作,如果在執行時才能確定,則只能通過這個物件的委託來實現。換句話說 類,滿足編譯時對物件的設定和要求。委託,用於滿足執行時對物件的設...