论马尔可夫链的稳定状态与MFC结合在天气预测中的应用

摘要:在《线性代数》课程中学习了“天气马尔可夫链的稳定状态”。马尔可夫模型(HiddenMarkovModel,HMM)是统计模型,它用来描述一个含有隐含未知参数的马尔可夫过程。其难点是从可观察的参数中确定该过程的隐含参数。然后利用这些参数来做进一步的分析,例如模式识别。在正常的马尔可夫模型中,状态对于观察者来说是直接可见的。这样状态的转换概率便是全部的参数。而在隐马尔可夫模型中,状态并不是直接可见的,但对于受到状态影响的某些变量则是可见的。每一个状态在可能输出的符号上都有一概率分布。因此输出符号的序列能够透露出状态序列的一些信息。在这里,我运用计算机科学与技术专业中所用的微软基础类库(英语:Microsoft Foundation Classes,简称MFC),并使用C++语言知识进行编程,深入探究马尔可夫链的稳定状态与MFC结合在天气预测中的应用。

 

关键字:马尔可夫链;转移概率矩阵;MFCC++;天气预测。

 

引言:马尔可夫链模型(Markov Chain Model)是一种常用的概率模型也叫马尔可夫分析(Markov Chain Analysis),其原理为利用概率转移矩阵所进行的模拟分析。此模型为一动态模型,参数可随时间而变,故可以用来预测未来事物变化状态的趋势。

 

 

应用案例介绍

论马尔可夫链的稳定状态与MFC结合在天气预测中的应用_第1张图片

论马尔可夫链的稳定状态与MFC结合在天气预测中的应用_第2张图片

该应用案例中,使用ω0三维列向量来存今日晴、阴、雨的概率,

                      ╭0.75, 0.5, 0.25,  ╮

转移矩阵A =│ 0.125, 0.25, 0.5,  │

                    ╰ 0.125, 0.25, 0.25 ╯

运用公式:ωk = Ak*ω0,k=1,2,3…

即可依次得到第k天的晴、阴、雨天气状态概率,最终得到天气马尔可夫链的稳定状态时的天气状态概率。

在使用MFC编程前,我预先用C语言进行了一个小实验。先用VisualC++6.0新建Win32 Console Aplication的工程编程,定义三维数组w[k][i][j](k=11,i=3,j=1),编写马尔可夫链中矩阵运算,其中“k”表示包括 “今天”在内的从今天起第k天的状态,“i”和“j”表示i行j列的矩阵,定义m_dSunny,m_dCloudy,m_dRainy三个double型变量分别存“晴”、“阴”、“雨”三种天气状态的概率,假设今日天气的三种概率分别为:晴20%,阴30%,雨50%。则先由以下代码简单计算一下未来10天(包括今天)的天气状态概率。

#include

 

int main()

{

  int i, j, k;

  double w[11][3][1] = {0.0};

  double A[3][3] = {0.75, 0.5, 0.25,

                    0.125, 0.25, 0.5,

                    0.125, 0.25, 0.25};

  //初始化今日天气:晴20%,阴30%,雨50%。

  double m_dSunny = 20, m_dCloudy = 30, m_dRainy= 50;

  w[0][0][0] =100*m_dSunny/(m_dSunny+m_dCloudy+m_dRainy);

  w[0][1][0] =100*m_dCloudy/(m_dSunny+m_dCloudy+m_dRainy);

  w[0][2][0] =100*m_dRainy/(m_dSunny+m_dCloudy+m_dRainy);

 

  for(k = 0; k < 10; k ++)  //10天

  {

      for(i = 0; i < 3; i ++) //行

      {

          for(j = 0; j < 3; j++)  //列

          {

              w[k+1][i][0] += A[i][j] *w[k][j][0];

          }

      }

  }

  for(k = 0; k <= 10; k ++)  //10天

  {

      for(i = 0; i < 3; i ++) //行

      {

          printf("%d\t", (int)w[k][i][0]);

      }

      printf("\n\n");

  }

  return 0;

}

控制台窗口打印结果如下:

论马尔可夫链的稳定状态与MFC结合在天气预测中的应用_第3张图片

即包括 “今天”在内的从今天起第k天的状态概率:

论马尔可夫链的稳定状态与MFC结合在天气预测中的应用_第4张图片

这里用的是C语言编写Win32 Console Aplication控制台程序进行的预先实验,可以看到天气状态概率随天数增加逐步趋近于一组常数:晴60%,阴21%,雨17%。即马尔可夫链的稳定状态。

接下来用MFC写对话框程序,部分关键代码如下:

 

voidCMyDlg::OnButtonSubmit()

{

    // TODO: Add your control notificationhandler code here

/***************天气马尔可夫链运算*******************/

//X轴刻度值 0(20, 360)->10(320,360)  Y轴刻度值 0(20,360)->10(20, 60)  单位长度30

    UpdateData(TRUE);

    int i, j, k;

    double w[11][3][1] = {0.0}, m;

    double A[3][3] = {0.75, 0.5, 0.25,

                      0.125, 0.25, 0.5,

                      0.125, 0.25, 0.25};

 

    m = m_dSunny+m_dCloudy+m_dRainy;

    w[0][0][0] = 100*m_dSunny/m;

    w[0][1][0] = 100*m_dCloudy/m;

    w[0][2][0] = 100*m_dRainy/m;

 

    for(k = 0; k < 10; k ++)  //10天

    {

        for(i = 0; i < 3; i ++) //行

        {

            for(j = 0; j < 3; j++)  //列

            {

                w[k+1][i][0] += A[i][j] *w[k][j][0];

            }

        }

    }

/*************天气马尔可夫链曲线绘制********************/

    //Sunny

        //强制更新绘图, 不可少, 否则绘图会出错

            //使static控件区域无效

    pWnd->Invalidate();

            //更新窗口

    pWnd->UpdateWindow();

    CDC *pDC = pWnd->GetDC();                   //获取控件的CDC指针

    CPen *pPenLine = new CPen(); //创建画笔对象

    pPenLine ->CreatePen(PS_SOLID, 3,RGB(255, 255, 0)); //黄色画笔

    CPen *pPen = NULL;

    //选中当前黄色画笔,并保存以前的画笔

    CGdiObject *pOldPen = pDC->SelectObject(pPenLine);

    //画线

    pDC ->MoveTo(20, 360 - 3 * w[0][0][0]);

    for(i = 1; i <=10; i++)

    {

        pDC ->LineTo(20 + 30 * i, 360 - 3 *w[i][0][0]);

    }

    //恢复以前的画笔

    pDC ->SelectObject(pOldPen);

    delete pPenLine;

    if(pPen != NULL)

    delete pPen;

    ReleaseDC(pDC);

 

    //Cloudy

    pWnd->Invalidate();

    //更新窗口

    pWnd->UpdateWindow();

    CDC *pDC2 = pWnd->GetDC();                   //获取控件的CDC指针

    CPen *pPenLine2 = new CPen(); //创建画笔对象

    pPenLine2 ->CreatePen(PS_SOLID, 3,RGB(153, 217, 234)); //蓝色画笔

    CPen *pPen2 = NULL;

        //选中当前蓝色画笔,并保存以前的画笔

    CGdiObject *pOldPen2 = pDC->SelectObject(pPenLine2);

    //画线

    pDC ->MoveTo(20, 360 - 3 * w[0][1][0]);

    for(i = 1; i <=10; i++)

    {

        pDC ->LineTo(20 + 30 * i, 360 - 3 *w[i][1][0]);

    }

    //恢复以前的画笔

    pDC ->SelectObject(pOldPen);

    delete pPenLine2;

    if(pPen2 != NULL)

    delete pPen2;

    ReleaseDC(pDC);

 

    //Rainy

    pWnd->Invalidate();

    //更新窗口

    pWnd->UpdateWindow();

    CDC *pDC3 = pWnd->GetDC();                   //获取控件的CDC指针

    CPen *pPenLine3 = new CPen(); //创建画笔对象

    pPenLine3 ->CreatePen(PS_SOLID, 3, RGB(0,255, 128)); //绿色画笔

    CPen *pPen3 = NULL;

        //选中当前绿色画笔,并保存以前的画笔

    CGdiObject *pOldPen3 = pDC->SelectObject(pPenLine3);

    //画线

    pDC ->MoveTo(20, 360 - 3 * w[0][2][0]);

    for(i = 1; i <=10; i++)

    {

        pDC ->LineTo(20 + 30 * i, 360 - 3 *w[i][2][0]);

    }

    //恢复以前的画笔

    pDC ->SelectObject(pOldPen);

    delete pPenLine3;

    if(pPen3 != NULL)

    delete pPen3;

    ReleaseDC(pDC);

}

该函数用于当用户填写好“今日天气比例”后,点击提交按钮时,绘制天气马尔科夫链。

绘制后界面效果如下:

论马尔可夫链的稳定状态与MFC结合在天气预测中的应用_第5张图片

你可能感兴趣的:(MFC)