维特比算法,红白球

import java.text.DecimalFormat;


public class ViterbiBall {
	//观察集合
	private enum V{
		RED,WHITE
	}
	//状态
	private enum Q{
		BOX1,BOX2,BOX3
	}
	private static int QLength = Q.values().length;
	//转移概率
	private static float[][] A = new float[][]{
		{0.5f,0.2f,0.3f},
		{0.3f,0.5f,0.2f},
		{0.2f,0.3f,0.5f}
	};
	//观察概率
	private static float[][] B = new float[][]{
		{0.5f,0.5f},
		{0.4f,0.6f},
		{0.7f,0.3f}
	};
	//初始概率
	private static float[] PI = new float[]{
		0.2f,0.4f,0.4f
	};
	//观察序列
	private static V[] O = new V[]{V.RED,V.WHITE,V.RED}; 
	
	//初始化
	private static float[] init = new float[QLength];
	/**
	 * 初始化数据
	 */
	private void initData(){
		for(int i=0;i<QLength;i++){
			init[i] = PI[i]*B[i][O[0].ordinal()];
		}
	}
	
	
	/**
	 * 维特比算法
	 * @param i
	 * @return
	 */
	private ViterbiData[] viterbi(int i){
		if(i==2){
			ViterbiData[] ViterbiDataTemp = new ViterbiData[QLength];
			for(int k=0;k<QLength;k++){
				float max=0;
				int[] maxIndex= new int[O.length];
				for(int j=0;j<QLength;j++){
					float t = init[k]*A[j][k]*B[k][O[i-1].ordinal()];
					if(t>=max){
						max = t;
						maxIndex[0] = k;
					}
				}
				ViterbiDataTemp[k]=new ViterbiData(maxIndex, max);
			}
			return ViterbiDataTemp;
		}		
		
		ViterbiData[] previousData = viterbi(i-1);
		ViterbiData[] ViterbiDataTemp = new ViterbiData[QLength];
		for(int k=0;k<QLength;k++){
			float max=0;
			int[] maxIndex = previousData[k].getStatePath();
			for(int j=0;j<QLength;j++){
				float t = previousData[k].getMaxProbility()*A[j][k]*B[k][O[i-1].ordinal()];
				if(t>=max){
					max = t;
					maxIndex[i-2] = k;
				}
			}
			ViterbiDataTemp[k]=new ViterbiData(maxIndex, max);
		}
		if(i==O.length){
			float finalMax = 0;
			int finalIndex = 0;
			for(int k=0;k<QLength;k++){
				float temp = ViterbiDataTemp[k].getMaxProbility();
				if(temp>=finalMax){
					finalMax = temp;
					finalIndex = k;
				}
			}
			int[] statePath =  ViterbiDataTemp[finalIndex].getStatePath();
			statePath[i-1] = finalIndex;
			System.out.println("状态序列:");
			for(int j = statePath.length-1;j>=0; j--){
				System.out.print(Q.values()[statePath[j]]+" ");
			}
			System.out.println("\n最大概率:");
			DecimalFormat df = new DecimalFormat( "#.#####");   
			System.out.println(df.format(finalMax));
			return null;
		}
		return ViterbiDataTemp;
		
	}
	
	public static void main(String[] args) {
		ViterbiBall v = new ViterbiBall();
		v.initData();
		v.viterbi(O.length);
	}
}

/**
 * 存放递归时候传递数据的类,statePath是状态序列。maxProbility是每次最大的概率值。
 * @author ailab
 *
 */
class ViterbiData{
	private int statePath[];
	private float maxProbility;
	public int[] getStatePath() {
		return statePath;
	}
	public void setStatePath(int[] statePath) {
		this.statePath = statePath;
	}
	public float getMaxProbility() {
		return maxProbility;
	}
	public void setMaxProbility(float maxProbility) {
		this.maxProbility = maxProbility;
	}
	
	public ViterbiData(int[] statePath,float maxProbility){
		this.statePath = statePath;
		this.maxProbility = maxProbility;
	}
}




















  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值