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;
}
}
维特比算法,红白球
最新推荐文章于 2024-03-12 08:24:45 发布