/**
* 【计算维特比矩阵】
* delta[ t ][ k ] = v_k(i) =log( max(P(pi in state k has sym i | path pi)) )
*/
public void CalculateViterbiMatrix() {
int T = O.length;
delta = new double[ T ][N];
PSI = new int[ T ][N];
//1、初始化,计算初始时刻(直觉上的第1时刻)所有状态的局部概率
for (int i = 0; i < N; i++){
delta[0][i] = logPI[ i ] + logB[ i ] [ O[0] ];
}
//2、归纳,递归计算
for (int t = 1; t < T; t++){
for (int i = 0; i < N; i++) {
int maxProdIndex = 0;
double maxProd = delta[t - 1][ maxProdIndex ] + logA[ maxProdIndex ][ i ];
for (int j = 1; j < N; j++) {
double prod = delta[t - 1][ j ] + logA[ j ][ i ];
if (prod > maxProd) {
maxProdIndex = j;
maxProd = prod;
}
}
delta[ t ][ i ] = maxProd + logB[ i ][ O[ t ] ] ;
PSI[ t ][ i ] = maxProdIndex;
}
}
//3、(隐藏状态序列)回溯求最佳路径——从T-1时刻往初始时刻——寻找累积最大概率的最佳路径
path=new int[T];//定义最佳路径
double maxProd = delta[ T-1 ][ 0 ];
path[T-1]=0;
for (int i = 1; i < N; i++) {
if (delta[ T-1 ][ i ] > maxProd) {
path[ T-1 ] = i;
maxProd = delta[ T-1 ][ i ];
}
}
//4、路径回溯——寻找最佳路径
for(int t= T-2; t>=0; t--){
path[ t ]= PSI[ t+1 ][ path[ t+1 ] ];
}
}
/**
* 打印最佳隐藏路径
* @since HMM必须给state和syms参数
*/
public void printPath(){
if(state==null){
throw new IllegalArgumentException("隐藏状态state名称没有设置");
}
int T=O.length;
for(int i=0; i< T; i++){
System.out.print( state[ path[ i ] ] +" ");
}
System.out.println();
}