机器学习算法题1

机器学习算法题

题目说明

Elwin觉得自己在大学期间陷入了一个怪圈:不管他在学期初确立了多么严格的工作习惯,他最终

都会陷入到某个固定的工作节奏中。为此,Elwin请你帮他建立马尔科夫链模型,请你帮他分析分

析发生这种情况的原因。为了简化题目难度,我们可以认为Elwin在生活中只会干三件事:玩手

机,工作,学习。

Elwin给你提供了一些他的生活规律:

玩手机后,有90%的概率继续玩手机,7.5%的概率工作,2.5%的概率学习;

工作后,有15%的概率玩手机,80%的概率继续工作,5%的概率学习;

学习后,有25%的概率玩手机,25%的概率工作,50%的概率继续学习。

在第一个学期中,Elwin一开始时的工作习惯为:30%概率玩手机,40%概率工作,30%概率

学习。

在第二个学期中,Elwin一开始时的工作习惯为:10%概率玩手机,40%概率工作,50%概率

学习。

题目要求

使用C/C++语言完成

请勿抄袭


分析

马尔科夫链模型:就是事件的下一状态只跟当前状态有关,与过去的事件无关(无记忆)

分析:假设此时在做A事件,则下一时刻做A,B,C事件的概率分别为Paa,Pab,Pac,则再下一时刻做A事件的概率为P1=Paa*Paa+Pab*Pba+Pac*Pca,同理可得再下一时刻做B,C事件的概率P2,P3

观察P1,P2,P3式子,下一时刻概率可用矩阵表示

设一开始做A,B,C事件的概率为P1=[p1,p2,p3]

状态转移矩阵P=【Paa Pab Pac

​ Pba Pbb Pbc

​ Pca Pcb Pcc】

下一时刻概率可用P1*P计算出

通过不断的矩阵相乘,寻找题目中所说的”固定的生活节奏“。

代码实现

1.矩阵相乘

int matrixx ( const float* a, const float b[3][3], float* p )//a,b为相乘的矩阵,此处因为本题一直都是1x3与3x3的矩阵相乘,所以a为一维数组,p为相乘的结果
{
	int i;
	for ( i = 0; i < 3; i++ )
	{
		float stemp = 0;
		for ( int j = 0; j < 3; j++ )
		{
			stemp = a[j] * b[j][i] + stemp;//前行乘后列
		}
		p[i] = stemp;
	}
	

2.判断是否停止迭代

	double diff = 0;
	for ( int i = 0; i < 3; i++ )
	{
		double x = 0;
		x = p[i] - a[i];
		if ( x < 0 )
		{
			x = -x;
		}
		diff = diff + x;
	}
	if ( diff > 0 && diff < 0.0000001 )//以三个概率与前一时刻概率差的和小于0.0000001为界限
	{
		return 0;
	}
	else
	{
		return 1;
	}
}

3.打印输出”固定的生活节奏“

void law ( float* a, const float b[3][3])//传入martixx函数所需的两个数组
{

	float pn1[3] = {0, 0, 0};
	int flag;
	flag = matrixx ( a, b, pn1 );
	while ( flag )
	{
		float pn2[3] = {0, 0, 0};
		flag = matrixx ( pn1, b, pn2 ); //这里我也不知道咋回事,
       								    //用pn1来接收相乘结果就会出错,
        							    //必须一直用每一项都是0的数组来存。
		for ( int i = 0; i < 3; i++ )
		{
			pn1[i] = pn2[i];
		}
	}
	for ( int i = 0; i < 3; i++ )
	{
		printf ( "%f\t", pn1[i] );
	}
	printf("\n");

}

c完整代码

#include<stdio.h>
int matrixx ( const float* a, const float b[3][3], float* p )
{
	int i;
	for ( i = 0; i < 3; i++ )
	{
		float stemp = 0;
		for ( int j = 0; j < 3; j++ )
		{
			stemp = a[j] * b[j][i] + stemp;
		}
		p[i] = stemp;
	}
	double diff = 0;
	for ( int i = 0; i < 3; i++ )
	{
		double x = 0;
		x = p[i] - a[i];
		if ( x < 0 )
		{
			x = -x;
		}
		diff = diff + x;
	}
	if ( diff > 0 && diff < 0.0000001 )
	{
		return 0;
	}
	else
	{
		return 1;
	}
}

void law ( float* a, const float b[3][3])
{

	float pn1[3] = {0, 0, 0};
	int flag;
	flag = matrixx ( a, b, pn1 );
	while ( flag )
	{
		float pn2[3] = {0, 0, 0};
		flag = matrixx ( pn1, b, pn2 );
		for ( int i = 0; i < 3; i++ )
		{
			pn1[i] = pn2[i];
		}
	}
	for ( int i = 0; i < 3; i++ )
	{
		printf ( "%f\t", pn1[i] );
	}
	printf("\n");

}


int main()
{
	float p1[3] = {0.3, 0.4, 0.3};
	float p2[3] = {0.1, 0.4, 0.5};
	float p[3][3] = {{0.9, 0.075, 0.025},
		{0.15, 0.8, 0.05},
		{0.25, 0.25, 0.5}
	};/*90%的概率继续玩手机,7.5%的概率工作,2.5%的概率学习;
                工作后,有15%的概率玩手机,80%的概率继续工作,5%的概率学习;
                 学习后,有25%的概率玩手机,25%的概率工作,50%的概率继续学习。
                                                                    */

	law(p1,p);
	law(p2,p);
	return 0;
}



python numpy实现

import numpy as np


def check(n2, n1):
    flag = 0
    for i in range(3):
        stem = n2[i] - n1[i]
        if stem < 0:
            stem = -stem
        flag = flag + stem
    if 0 < flag < 0.000000001:
        return 0
    else:
        return 1

def end(p1,p):
    n = np.dot(p1, p)
    flag1 = check(n, p1)
    while flag1:
        n1 = n
        n = np.dot(n, p)
        flag1 = check(n, n1)
    print(n)

p = np.array([[0.9, 0.075, 0.025], [0.15, 0.8, 0.05], [0.25, 0.25, 0.5]])
p1 = np.array([0.3, 0.4, 0.3])
p2 = np.array([0.1, 0.4, 0.5])

end(p1, p)
end(p2, p)

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值