unity工具相关: 依次递增的概率如何计算期望

根据知乎:

https://www.zhihu.com/question/452918374

q+p1+p2+p3+p4+p5+p6+p7+p8+p9=1

我们项目需要 中间是固定次数个p1(初始有固定次数个初始概率),如果固定次数为1 则类似于上面链接的描述

结果:

 

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
using System.Collections;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using Sirenix.OdinInspector.Editor;
using UnityEditor;
using UnityEngine;
 
/// <summary>
/// https://www.zhihu.com/question/452918374
/// 参考Timosky的回答
/// P0=q
/// P1=(1-base)*P1
/// Pn=(1-addValue*n)*Pn-1
/// p0+p1+p1....+p2+p3...+pn = 1
///fixed_count个p1
///offset_count个p2,pn
///算上p0,总次数为1+fixed_count+offset_count
/// </summary>
public class DesignExpectedValue : OdinEditorWindow
{
    [MenuItem("Window/策划/期望计算")]
    private static void OpenWindow()
    {
        myWindow = GetWindow<DesignExpectedValue>();
        myWindow.Show();
    }
 
    private static DesignExpectedValue myWindow;
    [InfoBox("算上p0,总次数为(1+固定次数+偏移次数)")]
    [LabelText("输入基础值")]
    public float baseValue = 0.1f;
    [LabelText("输入偏移值")]
    public float addValue = 0.1f;
 
    #region  求期望
    [TabGroup("求期望"), LabelText("输入固定次数")]
    public int fixed_count = 1;
    [TabGroup("求期望"), LabelText("输入偏移次数")]
    public int offset_count = 8;
    [TabGroup("求期望"), Button("获取期望值")]
    private void GetResult()
    {
        float factor_p0 = 1;
        float factor_p1 = 1 - baseValue;
        float factor_result = factor_p0;
 
        for (int i = 0; i < fixed_count; i++)
        {
            factor_result = factor_result + factor_p1;
        }
 
        float factor_px = factor_p1;
        for (int i = 2; i < offset_count + 2; i++)
        {
            factor_px = (1 - addValue * i) * factor_px;
            factor_result = factor_result + factor_px;
        }
        expectedValue = 1.0f / factor_result;
    }
    [TabGroup("求期望"), LabelText("期望"), ReadOnly, PropertyOrder(100)]
    public float expectedValue = 0.1f;
    #endregion
 
    #region  求次数
    [TabGroup("求次数"), LabelText("输入期望值")]
    public float c_expectedValue = 0.273208f;
    [TabGroup("求次数"), LabelText("输入固定值")]
    public float c_fixed_count = 1;
    [TabGroup("求次数"), LabelText("输入偏移次数上限,至少为1"), InfoBox("次数至少为1", InfoMessageType.Error, "IsMaxCountOk")]
    public int c_maxCount = 10000;
    [TabGroup("求次数"), LabelText("输入精度偏移")]
    public float c_offsetValue = 0.01f;
    [TabGroup("求次数"), Button("获取偏移次数值")]
    private void GetCountResult()
    {
        float p1 = (1 - baseValue) * c_expectedValue;
        float result = c_expectedValue;
        float Px = p1;
        bool isFind = false;
 
        for (int i = 0; i < c_fixed_count; i++)
        {
            result = result + p1;
        }
 
        for (int i = 2; i < c_maxCount; i++)
        {
            Px = (1 - addValue * i) * Px;
            result = result + Px;
            if (result >= (1.0f - c_offsetValue))
            {
                c_offsetCount = i;
                isFind = true;
                break;
            }
        }
 
        if (isFind)
        {
            c_result = "成功,偏移次数值:" + c_offsetCount + "总次数" + (c_offsetCount + 2) + " 趋向于1的结果:" + result;
        }
        else
        {
            c_result = "最大次数下,偏移次数值:" + c_maxCount + "总次数" + (c_offsetCount + 2) + " 趋向于1的结果:" + result;
        }
    }
 
    public bool IsMaxCountOk()
    {
        return c_maxCount < 1;
    }
 
    [TabGroup("求次数"), LabelText("偏移次数"), ReadOnly, PropertyOrder(100)]
    public int c_offsetCount = 0;
    [TabGroup("求次数"), LabelText("结果信息"), ReadOnly, PropertyOrder(101)]
    public string c_result = "";
 
    #endregion
 
 
}

  

 

 

 

另外一种excel计算模型的

excel计算:

 

 

 

 

 

 

 

 

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
using System.Collections;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using Sirenix.OdinInspector.Editor;
using UnityEditor;
using UnityEngine;
 
public class DesignExpectedValue : OdinEditorWindow
{
    [MenuItem("Window/策划/期望计算")]
    private static void OpenWindow()
    {
        myWindow = GetWindow<DesignExpectedValue>();
        myWindow.Show();
    }
 
    private static DesignExpectedValue myWindow;
    [LabelText("基础概率")]
    public float baseValue = 0.02f;
    [LabelText("递增概率")]
    public float addValue = 0.05f;
 
    #region  求期望
    [TabGroup("求期望"), LabelText("概率固定次数")]
    public int fixed_count = 1;
    [TabGroup("求期望"), LabelText("概率递增最大次数")]
    public int offset_count = 8;
    [TabGroup("求期望"), Button("获取期望值")]
    private void GetResult()
    {
        float factor_u = 1;
        float factor_v = 0;
        float factor_p_result = 0;
 
        for (int i = 0; i < fixed_count + offset_count; i++)
        {
            if (i < fixed_count)
            {
                factor_v = baseValue * factor_u;
                factor_u = (1 - baseValue) * factor_u;
            }
            else
            {
                float realBaseValue = baseValue + (i - fixed_count + 1) * addValue;
                factor_v = realBaseValue * factor_u;
                factor_u = (1 - realBaseValue) * factor_u;
            }
            factor_p_result = factor_p_result + factor_v * (i + 1);
        }
 
        expectedValue = 1.0f / factor_p_result;
    }
    [TabGroup("求期望"), LabelText("期望"), ReadOnly, PropertyOrder(100)]
    public float expectedValue = 0.1f;
    #endregion
 
    #region  求次数
    [TabGroup("求次数"), LabelText("输入期望值")]
    public float c_expectedValue = 0.0297636f;
    [TabGroup("求次数"), LabelText("概率固定次数")]
    public int c_fixed_count = 50;
    [TabGroup("求次数"), LabelText("输入偏移次数上限,至少为1"), InfoBox("次数至少为1", InfoMessageType.Error, "IsMaxCountOk")]
    public int c_maxCount = 10000;
    [TabGroup("求次数"), Button("获取偏移次数值")]
    private void GetCountResult()
    {
        bool isFind = false;
        float factor_u = 1;
        float factor_v = 0;
        float factor_p_result = 0;
        for (int i = 0; i < c_fixed_count + c_maxCount; i++)
        {
            if (i < c_fixed_count)
            {
                factor_v = baseValue * factor_u;
                factor_u = (1 - baseValue) * factor_u;
            }
            else
            {
                float realBaseValue = baseValue + (i - c_fixed_count + 1) * addValue;
                factor_v = realBaseValue * factor_u;
                factor_u = (1 - realBaseValue) * factor_u;
            }
            factor_p_result = factor_p_result + factor_v * (i + 1);
 
            if (factor_p_result * c_expectedValue >= 1)
            {
                isFind = true;
                c_offsetCount = i + 1 - c_fixed_count;
                break;
            }
        }
 
        if (isFind)
        {
            c_result = "成功,偏移次数值:" + c_offsetCount + "总次数" + (c_offsetCount + c_fixed_count) + " 总期望值:" + factor_p_result;
        }
        else
        {
            c_result = "最大次数下,偏移次数值:" + c_maxCount + "总次数" + (c_offsetCount + c_fixed_count) + " 总期望值:" + factor_p_result;
        }
    }
 
    public bool IsMaxCountOk()
    {
        return c_maxCount < 1;
    }
 
    [TabGroup("求次数"), LabelText("偏移次数值"), ReadOnly, PropertyOrder(100)]
    public int c_offsetCount = 19;
    [TabGroup("求次数"), LabelText("结果信息"), ReadOnly, PropertyOrder(101)]
    public string c_result = "";
 
    #endregion
 
 
}

  

 

posted @   sun_dust_shadow  阅读(541)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示