維特比演算法C 實現

2021-07-04 03:31:40 字數 3669 閱讀 4751

維特比演算法用來解決hmm的**問題(解碼decoding),即已知模型hmm和觀測序列o=

(o1,

o2,.

..on

) ,求對給定觀測序列條件概率p(

i/o)

的最大狀態序列i=

(i1,

i2,.

..in

) .

維特比演算法實際用動態規劃的思想來求解hmm模型**問題。由動態規劃原理,最優路徑具有這樣特性:如果最優路徑在時刻t通過結點i∗

t ,那麼這一路徑從結點i∗

t 到終點i∗

t 的部分路徑,對於所有從i∗

t 到終點i∗

t 的可能部分路徑來說必須是最優的。因為假如不是這樣,那麼從i∗

t 到i∗

t 就會有另一條更好的部分路徑存在,如果把它和從i∗

1 到i∗

t 的的部分路徑連起來,就會形成一條比原來更有的路徑,這是矛盾的。

因此,基於以上思想,我們只需從時刻t=

1 開始,遞推地計算在時刻

t 狀態為

i的各條部分路徑的最大概率,直至得到時刻t=

t 狀態為

j 的各條路徑的最大概率。時刻t=

t的最大概率即為最優路徑的概率p∗

,最優路徑的終結點i∗

t 也同時求得。之後,為了找出最優路徑的各個節點,從終結點i∗

t 開始,由後向前逐步求得節點it

−1∗ ,…,i∗

1 ,得到最優路徑i∗

=(i∗

1,i∗

2,..

.,i∗

t).匯入變數

δ 和

ψ ,定義在時刻

t 狀態為

i的所有單個路徑(i

∗1,i

∗2,.

..,i

∗t) 中概率最大值為 δt

(i)=

maxi

1,i2

...i

t−1p

(it=

i,it

−1,.

..i1

,ot,

...,

o1|λ

),i=

1,2,

...n

由此可得變數

δ 遞推公式: δt

+1(i

)=ma

xi1,

i2..

.itp

(it+

1=i,

it,.

..i1

,ot+

1,..

.,o1

|λ)=

max0

<

j<=n[

δt(j

)aji

]bi(

ot+1

),i=

1,2,

...n

定義在時刻

t 狀態為

i的所有單個路徑(i

∗1,i

∗2,.

..,i

∗t) 中概率最大的路徑的t−

1 個節點為 ψt

(i)=

argm

ax0<

j<=n[

δt−1

(j)a

ji],

i=1,

2,..

.n輸入:模型λ=

(a,b

,π) 和觀測序列o=

(o1,

o2,.

..on

) 輸出:最優路徑i∗

=(i∗

1,i∗

2,..

.,i∗

t).

step1:初始化 δ1

(i)=

πibi

(o1)

,i=1

,2,.

..n

ψ1(i

)=0,

i=1,

2,..

.n

step2:遞推,對t=

2,3,

...t

δt=max0

<

j<=n[

δt−1

(j)a

ji]b

i(ot

),i=

1,2,

...n

ψt(i)=m

ax0<

j<=n[

δt−1

(j)a

ji],

i=1,

2,..

.n

step3:終止 p∗

=max

0<

i<=nδ

t(i)

i∗t=arg

max0

<

i<=n[

δt(i

)]

step4:最優路徑回溯,對t=

t−1,

t−2,

...1 i∗

t=ψt

+1(i

∗t+1

)

#include 

#include

#include

using

namespace

std;

int main()

; double c[3][3] = ;

double e[3][2] = ;

string output[4] = ;

int state[3] = ;

int row = 3;

int column = 3;

//開闢陣列空間

double **delta = new

double *[row];

int **path = new

int *[row];

int i, j,k;

for (i = 0; i < 3; i++)

//將輸出狀態轉為陣列

int outnum[4];

for (i = 0; i < row; i++)

//初始化

for (i = 0; i < column; i++)

//遞迴

for (j = 1; j < row; j++)//序列遍歷,矩陣列遍歷

}delta[k][j] = pro;

path[k][j]= sta;

}

}//終止,找到概率最大值

double max = 0;

int sta = 0;

for (i = 0; i < column; i++)

}//回溯,找到最大路徑及其對應的狀態值

list

listpath;

listpath.push_back(sta+1);

for (j = row - 1; j > 0; j--)

//輸出

cout

<< "max probability: "

<< max << endl;

list

::iterator itepath;

for (itepath = listpath.begin(); itepath != listpath.end(); itepath++)

cout

<< *itepath << " ";

}

維特比演算法 python 維特比演算法實現分詞

維特比演算法原理可以參考以下文章,講解的非常詳細,那麼接下來將講解維特比演算法如何應用到分詞演算法中,並如何用python 實現。如何通俗地講解 viterbi 演算法?www.zhihu.com 一 過程分析 句子 經常有意見分歧 詞典 經常 經 有 有意見 意見 分歧 見 意 見分歧 分 概率 ...

維特比演算法

維特比演算法在機器學習中非常重要,在求解隱馬爾科夫和條件隨機場的 問題中均用到了維特比演算法。實際上,維特比演算法不僅是很多自然語言處理的解碼演算法,也是現代數字通訊中使用最頻繁的演算法。以乙個簡單的隱馬爾科夫模型為例,n 為觀測符號,y y1,y2,y n 為隱狀態序列,要求的 問題為 y 1,y...

維特比演算法

維特比演算法主要用來解決籬笆網路,老實講我第一次聽到這個名字是發懵的,網路我是知道的,說白了就是圖 迪傑特斯拉演算法 但是,籬笆網路是值下面這種一列一列的圖,只會前面連線到後面,而且不會跳層連線,可以說是一種非常特殊且友好的圖了 正常的圖能逼死強迫症 x max xx x x x xma x x 這...