zoukankan      html  css  js  c++  java
  • 『笔记』数学概率与期望

    前置芝士

    概率初步

    具体详情请参照人教版高中数学必修二课本

    一个随机事件中:

    • 某种可能的结果称为该实验的“样本点

    • 所有可能的结果构成的集合称为“样本空间

    在一个已知的样本空间里,随机事件就是样本空间的子集,是由若干个样本点组成的集合。

    随机变量是把样本点映射成实数的函数。离散型随机变量则是取值有限或可数的随机变量。

    形式化地说,一个随机变量被称为离散型随机变量,当它的值域大小 有限 或者为 可列无穷大

    概率

    以下来自于 OI-Wiki

    古典定义

    如果一个试验满足两条:

    • 试验只有有限个基本结果;
    • 试验的每个基本结果出现的可能性是一样的;

    这样的试验便是古典试验。
    对于古典试验中的事件 \(A\),它的概率定义为 \(P(A)=\frac{m}{n}\),其中 \(n\) 表示该试验中所有可能出现的基本结果的总数目,\(m\) 表示事件 \(A\) 包含的试验基本结果数。

    统计定义

    如果在一定条件下,进行了 \(n\) 次试验,事件 \(A\) 发生了 \(N_A\) 次,如果随着 \(n\) 逐渐增大,频率 \(\frac{N_A}{n}\) 逐渐稳定在某一数值 \(p\) 附近,那么数值 \(p\) 称为事件 \(A\) 在该条件下发生的概率,记做 \(P(A)=p\)

    公理化定义

    \(E\) 是随机试验,\(S\) 是它的样本空间(事件空间的同义词)。对 \(E\) 的每一个事件 \(A\) 赋予一个实数,记为 \(P(A)\),称为事件 \(A\) 的概率。这里 \(P(A)\) 是一个从集合到实数的映射,\(P(A)\) 满足以下公理:

    • 非负性:对于一个事件 \(A\),有概率 \(P(A)\in [0,1]\)

    • 规范性:事件空间的概率值为 \(1\)\(P(S)=1\).

    • 可加性:若 \(A\cap B=\varnothing\),则 \(P(A\cup B) = P(A)+P(B)\)

    \((S,P)\) 构成的这样的一个系统称为一个 概率空间

    定义

    若随机变量 \(x\) 的取值有 \(x_1,x_2,\cdots,\) 一个随机事件可以表示为 \(x=x_i\) ,其概率为 \(P(x=x_i)=p_i\) ,则称 \(E(x)=\sum{p_ix_i}\) 为随机变量 \(x\)数学期望

    也就是说,对于一个离散性随机变量 \(X\) 来说,其每个取值乘以该取值对应概率的总和成为该变量的 数学期望 是,记为 \(E(X)\)

    \[E(X)=\sum\limits_{\alpha \in I(X)} \alpha\cdot P(X=\alpha)=\sum\limits_{\omega\in S}X(\omega)P(\omega) \]

    其中 \(I(X)\) 表示随机变量 \(X\) 的值域,\(S\) 表示 \(X\) 所在概率空间的样本集合。

    通俗地讲,数学期望就是随机变量 \(x\) 的取值与概率的乘积之和。

    性质

    期望可加性

    数学期望是线性函数,满足

    \[E(a x+b y)=a \cdot E(x)+ b\cdot E(y) \]

    证明:

    利用乘法分配律概率的基本乘法运算有:

    \[\begin{aligned} E(a X+b Y) &= \sum_{e_{i} \in S}\left(aX\left(e_{i}\right)+bY\left(e_{i}\right)\right) P\left(e_{i}\right)\\ &= a \sum_{e_{i} \in S} X\left(e_{i}\right) P\left(e_{i}\right)+b \sum_{e_{i} \in S} Y\left(e_{i}\right) P\left(e_{i}\right)\\ &= a E(X)+b E(Y) \end{aligned} \]

    这可以说是数学期望最重要的一个性质,是我们能够对数学期望进行地推求解的基本依据。

    例如在掷两枚骰子的点数实验中,样本空间是由 \(36\) 个样本点组成的集合,每个样本点可以写作 \(\left(a,b\right)\) ,其中 \(1\leq a,b\leq 6\)

    定义“掷出的点数之和”为 \(x\) ,那么随机变量 \(x\) 的取值为 \(2 \sim 12\) 。随机事件可描述为“掷出 \(x\) 点” ,即由 \(a+b = x\) 的样本点 \(\left(a,b\right)\) 构成的自己。掷出 \(8\) 点的概率 \(P(x=8)=\frac{5}{36}\) ,则掷出的点数的数学期望为

    \[\frac{1}{36} \times(2+12)+\frac{1}{18} \times(3+11)+\frac{1}{12} \times(4+10)+\frac{1}{9} \times(5+9)+\frac{5}{36} \times(6+8)+\frac{1}{6} \times 7=7 \]

    如果利用期望的可加性,

    设随机变量 \(X\) 表示掷一枚骰子的点数,显然其期望值为

    \[E(x)=\frac{(1+2+3+4+5+6)}{6}=3.5 \]

    掷两枚骰子的点数可表示为随机变量 \(2X\) ,则有

    \[E(2 X)=2 E(x)=2 \times 3.5=7 \]

    例题

    P2911 [USACO08OCT]Bovine Bones G

    暴力思路

    这题直接暴力模拟就能过

    直接暴力模拟,没多少说的。

    /*
    
    Name: P2911 [USACO08OCT]Bovine Bones G
    
    Solution: 
       
    
    By Frather_
    
    */
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    #define ll long long
    #define InF 0x3f3f3f3f
    #define kMax 10e5
    #define kMin -10e5
    #define kMod 998244353
    using namespace std;
    /*===================================================快读*/
    inline int read()
    {
        int x = 0, f = 1;
        char c = getchar();
        while (c < '0' || c > '9')
        {
            if (c == '-')
                f = -1;
            c = getchar();
        }
        while (c >= '0' && c <= '9')
        {
            x = (x << 3) + (x << 1) + (c ^ 48);
            c = getchar();
        }
        return x * f;
    }
    /*===============================================定义变量*/
    int s1, s2, s3;
    
    const int _ = 1010;
    
    struct sz
    {
        int num;
        int id;
    } t[_];
    /*=============================================自定义函数*/
    bool cmp(sz a, sz b)
    {
        return a.num == b.num ? a.id > b.id : a.num < b.num;
    }
    /*=================================================主函数*/
    int main()
    {
        s1 = read();
        s2 = read();
        s3 = read();
    
        for (int i = 1; i <= s1; i++)
            for (int j = 1; j <= s2; j++)
                for (int k = 1; k <= s3; k++)
                    t[i + j + k].num++;
    
        for (int i = 1; i <= _; i++)
            t[i].id = i;
    
        sort(t + 1, t + s1 + s2 + s3 + 1, cmp);
    
        printf("%d\n", t[s1 + s2 + s3].id);
        return 0;
    }
    

    数学思路

    装上脑子想一想红题能加上 期望 的标签肯定有蹊跷。

    然后趁着刚装上的脑子还没过期赶紧思考数学解法。

    手玩几组骰子可以发现:

    对于两个骰子(面数分别是 \(a,b,\dots\)

    点数之和出现次数最多的是 1+a,1+a+1,1+a+2,...,1+b 且总共有 b-a+1 个出现次数最多的和

    要使出现次数最多,那么 b-a 应最大

    那么对于三个甚至更多骰子情况同样如此。这样我们很容易得出 \(b\) 应取为三个数中最大的数,\(a\) 应取为三个数中最小的数,\(c\) 自然就是中间的那个数

    /*
    
    Name: 
    
    Solution: 
       
    
    By Frather_
    
    */
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    #define ll long long
    #define InF 0x3f3f3f3f
    #define kMax 10e5
    #define kMin -10e5
    #define kMod 998244353
    using namespace std;
    /*===================================================快读*/
    inline int read()
    {
        int x = 0, f = 1;
        char s3 = getchar();
        while (s3 < '0' || s3 > '9')
        {
            if (s3 == '-')
                f = -1;
            s3 = getchar();
        }
        while (s3 >= '0' && s3 <= '9')
        {
            x = (x << 3) + (x << 1) + (s3 ^ 48);
            s3 = getchar();
        }
        return x * f;
    }
    /*===============================================定义变量*/
    int s1, s2, s3;
    
    /*=============================================自定义函数*/
    
    /*=================================================主函数*/
    int main()
    {
        s1 = read();
        s2 = read();
        s3 = read();
        if (s1 < s2)
            swap(s1, s2);
        if (s2 < s3)
            swap(s2, s3);
        if (s1 < s2)
            swap(s1, s2);
    
        if (s2 <= s1 - s3 + 1)
            printf("%d\n", 1 + s2 + s3);
        else
            printf("%d\n", 2 + s1 + (s2 - s1 + s3 - 1) / 2);
        return 0;
    }
    

    P4316 绿豆蛙的归宿

    本题思路源于 《算法竞赛进阶指南》

    \(F[x]\) 表示从节点 \(x\) 走到终点 \(n\) 所经过的路径的期望长度。若从 \(x\) 出发有 \(k\) 条边,分别到达 \(y_1,y_2,y_3,\dots,y_k\) ,边长分别为 \(w_1,w_2,w_3,\dots,w_k\) ,则有

    \[\operatorname{ans}[x]=\frac{1}{k} \sum_{i=1}^{k}\left(\operatorname{ans}\left[y_{i}\right]+w_{i}\right) \]

    显然 \(\operatorname{ans}[x]=0\) ,并且 \(\operatorname{ans}[1]\) 即为所求答案。

    故可以从终点 \(n\) 出发,在反向图上进行拓扑排序,并且计算 \(\operatorname{ans}[x]\) 的值。

    时间复杂度 \(O(n+m)\) 完全可以接受。

    /*
    
    Name: P4316 绿豆蛙的归宿
    
    Solution: 
       
    
    By Frather_
    
    */
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    #define ll long long
    #define InF 0x3f3f3f3f
    #define kMax 10e5
    #define kMin -10e5
    #define kMod 998244353
    using namespace std;
    /*===================================================快读*/
    inline int read()
    {
        int x=0,f=1;
        char c=getchar();
        while(c<'0'||c>'9')
        {
            if(c=='-')
            f=-1;
            c=getchar();
        }
        while(c>='0'&&c<='9')
        {
            x=(x<<3)+(x<<1)+(c^48);
            c=getchar();
        }
        return x*f;
    }
    /*===============================================定义变量*/
    int n,m;
    
    const int _ = 1000010;
    
    struct edge
    {
        int to;
        int dis;
        int nxt;
    }e[_];
    int cnt,head[_];
    int in[_],out[_];
    
    queue<int> q;
    double ans[_];
    /*=============================================自定义函数*/
    void add(int from,int to,int dis)
    {
        e[++cnt].to=to;
        e[cnt].dis=dis;
        e[cnt].nxt=head[from];
        head[from]=cnt;
    }
    
    void topa()
    {
        q.push(n);
        while (!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=head[u];i;i=e[i].nxt)
            {
                int v=e[i].to;
                ans[v]+=(ans[u]+e[i].dis)/in[v];
                out[v]--;
                if(!out[v])
                    q.push(v);
            }
        }
    }
    /*=================================================主函数*/
    int main()
    {
        n=read();
        m=read();
        for(int i=1;i<=m;i++)
        {
            int u=read();
            int v=read();
            int w=read();
            add(v,u,w);//反向建图,便于正向对图进行反向遍历
            in[u]++;
            out[u]++;
        }
    
        topa();//拓扑排序
    
        printf("%.2lf\n",ans);
        return 0;
    }
    

    『题单』概率与统计

    最后

    鸣谢:

    预计过几天会有关于数学期望更深入的笔记叭

    完结。

  • 相关阅读:
    关于“jdk”版本不支持问题的总结
    Linux系统下jdk卸载安装、配置
    weblogic-jdk 问题
    MCU有哪些复位因素
    MCU固件升级(OTA)的几种Flash划分方式
    003_Linux常用命令之文件操作
    002_Linux常用命令之目录操作
    001_Linux常用命令之ls命令
    dup与dup2函数
    Linux 系统查询机器最近重启时间命令
  • 原文地址:https://www.cnblogs.com/Frather/p/14587295.html
Copyright © 2011-2022 走看看