原理请参见鄙人前面的一篇文章
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Viterbi
{
class Program
{
const int m = 2; //隐含状态数
const int n = 3; //观察状态数
static int[] sArray = new int[n]; //隐含状态序列
static int[] oArray = { 0, 1, 2 }; //可观察状态序列
static double[] iArray = { 0.6, 0.4 };//初始概率矩阵
static double[,] aArray = { { 0.7, 0.3 }, { 0.4, 0.6 } };//转移概率矩阵
static double[,] bArray = { { 0.5, 0.4, 0.1 }, { 0.1, 0.3, 0.6 } };//发射概率矩阵
static double[,] resultArray = new double[n, m];//保存结果
static void Main(string[] args)
{
Viterbi(sArray, oArray, iArray, aArray, bArray);
foreach (int i in sArray)
{
Console.Write(i);
}
Console.ReadKey();
}
static void Viterbi(int[] s, int[] o, double[] i, double[,] a, double[,] b)
{
for (int j = 0; j < m; j++)
{
resultArray[0, j] = iArray[j] * bArray[j, oArray[0]];
}
for (int j = 1; j < n; j++)
{
for (int p = 0; p < m; p++)
{
for (int k = 0; k < m; k++)
{
double tmp = resultArray[j - 1, p] * aArray[p, k] * bArray[k, oArray[j]];
if (tmp > resultArray[j, k])
resultArray[j, k] = tmp;
}
}
}
for (int j = 0; j < n; j++)
{
double tmp = resultArray[j, 0];
sArray[j] = 0;
for (int p = 0; p < m; p++)
{
if (resultArray[j, p] > tmp)
sArray[j] = p;
}
}
}
}
}
运行结果如下:
输入可观察状态序列:012
隐含状态序列:001