⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hmm.cpp

📁 隐马尔可夫模型演示,給出向前矩阵和向后矩阵
💻 CPP
字号:
// Hmm.cpp: implementation of the CHmm class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "hmm_1.h"
#include "Hmm.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CHmm::CHmm()
{
	m_pA = NULL;
	m_pB = NULL;
	m_pPI = NULL;

	m_pInput = NULL;
	m_pRltMatrix = NULL;
	m_plamda = NULL;

	m_iDimA = 0;
	m_iDimB = 0;
	m_iInputLen = 0;
}

CHmm::~CHmm()
{
}

/*
	int iDimA		转换矩阵的维数
	int iDimB		输出符号数
	double **pA		状态转换矩阵iDimA*iDimA
	double **pB		输出符号的概率 iDimA*iDimB
	double *pPI		初始状态概率
*/
void CHmm::SetHmmParam(int iDimA, int iDimB, double **pA, double **pB, double *pPI)
{
	m_pA = pA;
	m_iDimA = iDimA;

	m_pB = pB;
	m_iDimB = iDimB;
	
	m_pPI = pPI;
}

/*
 *	向前算法
 *	int *pInput			检测序列
 *	int iInputLen		序列长度
 *	double **pRltMatrix	中间结果
 */
double CHmm::Forward(int *pInput, int iInputLen, double **pRltMatrix)
{
	for(int i=0; i<iInputLen; i++)
	{
		if(pInput[i]>=m_iDimB)
		{
			AfxMessageBox("输入的数据超界");
			return 0.0;
		}
	}


	m_pRltMatrix = pRltMatrix;

	double rlt = 0;
	m_pInput = pInput;
	m_iInputLen = iInputLen;

//	NewMatrix();

	double *alfa;
	alfa = new double[m_iDimA];

	for(i=0; i<m_iDimA; i++)
	{
		alfa[i] = forward_recursion(iInputLen-1, i);
		//m_pRltMatrix[i][0] = alfa[i];
		rlt+=alfa[i];
	}



	delete [] alfa;
	return rlt;
}

double CHmm::forward_recursion(int iIndex, int j)
{
	double rlt= 0;
	double *alfa_last;
	alfa_last = new double[m_iDimA];

	if(iIndex==1)
	{

		for(int i=0; i<m_iDimA; i++)
		{
			alfa_last[i] = m_pPI[i]*m_pB[i][m_pInput[0]];
			m_pRltMatrix[i][0] = alfa_last[i];
		}
	}
	else
	{
		for(int i=0; i<m_iDimA; i++)
		{
			alfa_last[i] = forward_recursion(iIndex-1, i);
		}
	}

	for(int i=0; i<m_iDimA; i++)
	{
		rlt+=alfa_last[i]*m_pA[i][j];
	}

	rlt *= m_pB[j][m_pInput[iIndex]];

	m_pRltMatrix[j][iIndex] = rlt;
	//m_pRltMatrix[j][iIndex+1] = rlt;
	delete [] alfa_last;
	return rlt;
}


/*
 *	向后算法
 *	int *pInput			检测序列
 *	int iInputLen		序列长度
 *	double **pRltMatrix	中间结果
 */
double CHmm::Backward(int *pInput, int iInputLen, double **pRltMatrix)
{
	for(int i=0; i<iInputLen; i++)
	{
		if(pInput[i]>=m_iDimB)
		{
			AfxMessageBox("输入的数据超界");
			return 0.0;
		}
	}


	m_pRltMatrix = pRltMatrix;

	double rlt = 0;
	m_pInput = pInput;
	m_iInputLen = iInputLen;

//	NewMatrix();

	double *beta;
	beta = new double[m_iDimA];

	for(i=0; i<m_iDimA; i++)
	{
		beta[i] = backward_recursion(0, i)*m_pPI[i]*m_pB[i][m_pInput[0]];
		m_pRltMatrix[i][0] = beta[i];
		rlt+=beta[i];
	}


	return rlt;
}
double CHmm::backward_recursion(int iIndex, int j)
{
	double rlt = 0.0;
	double *beta_last;
	beta_last = new double[m_iDimA];

	if(iIndex==m_iInputLen-1)
	{
		rlt = 1.0;
		//rlt = 2.0;

	}
	else
	{
		for(int i=0; i<m_iDimA; i++)
		{
			beta_last[i] = backward_recursion(iIndex+1, i);

			rlt+=beta_last[i]*m_pA[j][i]*m_pB[i][m_pInput[iIndex+1]];
		}
	}


	//保存中间结果
	m_pRltMatrix[j][iIndex+1] = rlt;


	return rlt;
}


/*
 *	韦特比算法
 *	int *pInput			检测序列
 *	int iInputLen		序列长度
 *	int *pBestPath		结果最佳序列
 *	double **pRltMatrix	中间结果
 */
double CHmm::Viterbi(int *pInput, int iInputLen, int *pBestPath, double **pRltMatrix, int **plamda)
{

	for(int i=0; i<iInputLen; i++)
	{
		if(pInput[i]>=m_iDimB)
		{
			AfxMessageBox("输入的数据超界");
			return 0.0;
		}
	}

	m_pRltMatrix = pRltMatrix;
	m_plamda = plamda;


	double rlt = 0.0;

	m_pInput = pInput;
	m_iInputLen = iInputLen;


	double *deta;
	deta = new double[m_iDimA];

	for(i=0; i<m_iDimA; i++)
	{
		deta[i] = viterbi_recursion(iInputLen-1, i);
		if(rlt<deta[i])
		{
			rlt=deta[i];
			pBestPath[iInputLen-1] = i+1;
		}
	}

	
	for(i=iInputLen-2; i>=0; i--)
	{
		pBestPath[i] = m_plamda[pBestPath[i+1]-1][i+1];
	}

	delete [] deta;
	return rlt;
}
//韦特比算法 的递推函数
double CHmm::viterbi_recursion(int iIndex, int j)
{
	double rlt= 0;
	double *deta_last;
	deta_last = new double[m_iDimA];

	if(iIndex==1)
	{

		for(int i=0; i<m_iDimA; i++)
		{
			deta_last[i] = m_pPI[i]*m_pB[i][m_pInput[0]];

			//保存中间结果
			m_pRltMatrix[i][0] = deta_last[i];
			
		}
	}
	else
	{
		for(int i=0; i<m_iDimA; i++)
		{
			deta_last[i] = viterbi_recursion(iIndex-1, i);
		}
	}

	double temp;
	for(int i=0; i<m_iDimA; i++)
	{
		temp = deta_last[i]*m_pA[i][j];
		if(rlt<temp)
		{
			rlt=temp;

			//保存最佳路径
			m_plamda[j][iIndex] = i+1;
		}
	}

	rlt *= m_pB[j][m_pInput[iIndex]];

	//保存中间结果
	//m_pRltMatrix[iIndex][j] = rlt;
	m_pRltMatrix[j][iIndex] = rlt;

	delete [] deta_last;
	return rlt;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -