哪位高手给看一下,下面的HMM的viterbi算法没错吧,谢谢
首先,需要定义HMM的数据结构,也就是HMM的五个基本要素
typedef struct
{
int N; /* 隐藏状态数目;Q={1,2,…,N} */
int M; /* 观察符号数目; V={1,2,…,M}*/
double **A; /* 状态转移矩阵A[1..N][1..N]. a[i][j] 是从t时刻状态i到t+1时刻状态j的转移概率 */
double **B; /* 发射或混淆矩阵B[1..N][1..M],b[j][k]在状态j时发射字符k的概率。*/
double *pi; /* 初始向量pi[1..N],pi[i] 是初始状态概率分布 */
} HMM;
void Viterbi(HMM *phmm, int T, int *O, double **delta, int **psi, int *q,double *pprob)
{
int i, j; /* 状态索引 */
int t; /* 时间索引 */
double val; /*求局部概率时的中间值*/
double maxval,val; /*求局部概率时的中间值的最大值 */
int maxvalind; /*最大值对应的状态i*/
/* 1. 初始化:计算t=1时刻所有状态的局部概率: */
for (i = 1; i <= phmm->N; i++)
{
delta[1][i] = phmm->pi[i]* phmm->B[i][O[1]];
psi[1][i] =0;
}
/* 2. 归纳:递归计算每个时间点,t=2,… ,T时的局部概率 */
for (t = 1; t < T; t++)
{
for (j = 1; j <= phmm->N; j++)
{
maxval = 0.0;
maxvalind = 1;
for (i = 1; i <= phmm->N; i++)
{
val= delta[t][i]* (phmm->A[i][j]);
if(val>maxval)
{
maxval = val;
maxvalind = i;
}
}
delta[t+1][j] = maxval*(phmm->B[j][O[t+1]]);
psi[t+1][j] =maxvalind;
}
}
/* 3. 终止*/
*pprob = 0.0;
q[T]=1;
for (i = 1; i <= phmm->N; i++)
{
if(delta[T][i]>*pprob)
{
*pprob = delta[T][i];
q[T]=i;
}
}
/* 4. 路径(状状态序列)回溯*/
for (t = T-1; t >= 1; t--)
q[t]=psi[t+1][q[t+1]];
}