unity工具相关: 依次递增的概率如何计算期望
根据知乎:
https://www.zhihu.com/question/452918374
q+p1+p2+p3+p4+p5+p6+p7+p8+p9=1
我们项目需要 中间是固定次数个p1(初始有固定次数个初始概率),如果固定次数为1 则类似于上面链接的描述
结果:

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计算:



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
}

浙公网安备 33010602011771号