概率论——马尔科夫链

这篇博客介绍了马尔科夫链的概念,通过一个具体的例子展示了如何使用马尔科夫链来计算在特定步数后处于某一层楼的概率。博主使用了矩阵乘法和快速幂运算来高效地解决这个问题,并提供了一个C++程序实现。文章还涉及到递推矩阵和状态转移概率的概念,适合对概率论和算法感兴趣的读者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概率论——马尔科夫链

马尔科夫链是一个随机过程,包含一些状态和转移概率,对于每一个状态,我们都知道由这个状态向其他状态转移的概率是多少。

例如,我们考虑处在一个 n n n层楼的一楼,每次我们都有同等概率的上楼或下楼,除非处在一楼或者顶楼。那么 k k k步之后处于 m m m层的概率是多少?

如果 n = 5 n=5 n=5,每一层楼都是一个状态的话,对应的马尔科夫链为:

Markov
我们定义向量 V k = [ p 1 , p 2 , … , p n ] V_k=[p_1,p_2,\ldots,p_n] Vk=[p1,p2,,pn],为经过 k k k步之后,处在 i i i p i p_i pi的概率向量。

每一个马尔科夫链都对应一个递推矩阵 T T T,使得 V k = T V k − 1 V_k = T V_{k-1} Vk=TVk1

例如上述马尔科夫链就可以转换为:

Matrix

例题

P3758

#include <bits/stdc++.h>

using namespace std;

#define FR freopen("in.txt", "r", stdin)
#define FW freopen("out.txt", "w", stdout)

typedef long long ll;

ll mod = 2017;

struct Matrix
{
    ll arr[35][35];
    int n;

    Matrix(int N)
    {
        n = N;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                arr[i][j] = 0;
    }

    Matrix operator*(Matrix o)
    {
        Matrix ans(n);
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                for (int k = 1; k <= n; k++)
                    ans.arr[i][j] = (ans.arr[i][j] + (arr[i][k] * o.arr[k][j]) % mod) % mod;
        return ans;
    }
};

Matrix fpow(Matrix a, ll e)
{
    Matrix ans(a.n);

    for (int i = 1; i <= a.n; i++)
    {
        ans.arr[i][i] = 1;
    }

    for (; e; e >>= 1, a = a * a)
    {
        if (e & 1)
            ans = ans * a;
    }
    return ans;
}

int main()
{
    int n, m;
    scanf("%d %d", &n, &m);
    Matrix T(n + 1);

    for (int i = 1; i <= m; i++)
    {
        int u, v;
        scanf("%d %d", &u, &v);

        T.arr[u][v] = 1;
        T.arr[v][u] = 1;
    }

    for (int i = 1; i <= n; i++)
    {
        T.arr[i][i] = 1;
        T.arr[n + 1][i] = 1;
    }
    T.arr[n + 1][n + 1] = 1;
    ll t;
    scanf("%lld", &t);
    T = fpow(T, t);

    ll ans = 0;

    for (int i = 1; i <= n + 1; i++)
    {
        ans = (ans + T.arr[i][1]) % mod;
    }

    printf("%lld", ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值