c# - 计算序列在随机分布中出现的频率时出现意外结果
问题描述
给定一个硬币游戏:你从一美元开始,硬币被翻转。如果是正面,则美元翻倍,如果是反面,则游戏结束。但是,如果再次翻转正面,则收益现在是四倍,如果正面翻转 3 次 8 倍,依此类推。悖论是期望值是 1/2*1+1/4*2+1/8*4... = 无穷大。因此,如果您玩游戏的时间足够长,您应该会逐渐变得富有。蒙特卡罗模拟表明不是。这是著名的圣彼得堡悖论的模拟
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sorrow
{
class Program
{
static void Main(string[] args)
{
Random rnd = new Random(Environment.TickCount);
double totalSum = 0;
int bigWins = 0;
double iterations = 1000;
for (int z = 0; z < 10; z++)
{
iterations *= 10;
for (double i = 1; i < iterations; i++)
{
int sum = 1;
int a = 1;
while (a == 1)
{
//generate a random number between 1 and 2
a = rnd.Next(1, 3);
if (a == 1)
{
sum *= 2;
}
if (sum > 8000&&sum<12000)// given discrete probability landing 13 times
{
// if the sum is over 8000 that means that it scored 1 13 times in a row (2^13) - that should happen
//once every 8192 times. Given that we run the simulation 100 000 000 times it should hover around
// 100 000 000/8192
//However is much , much bigger
bigWins++;
}
}
totalSum += sum;
}
Console.WriteLine("Average gain over : "+iterations+" iterations is:" + totalSum / iterations);
Console.WriteLine("Expected big wins: " + iterations / 8192 + " Actual big wins: " + bigWins);
Console.WriteLine();
}
}
}
}
如您所见,我们应该期望这个数字小 7 倍。这让我觉得也许 c# random 很容易一遍又一遍地选择相同的数字?这是真的还是我的代码有问题?我该如何解决这个问题?
解决方案
你有两个错误。您的循环在获胜后开始,因此大赢的机会是 1/2^12,并且您在 12 之后继续增加大赢以获得额外的胜利。
尝试
static void Main(string[] args)
{
Random rnd = new Random(Environment.TickCount);
double iterations = 1000;
for (int z = 0; z < 10; z++)
{
double totalSum = 0;
int bigWins = 0;
iterations *= 10;
for (double i = 1; i < iterations; i++)
{
int sum = 2;
int a = 1;
while (a == 1)
{
//generate a random number between 1 and 2
a = rnd.Next(1, 3);
if (a == 1)
{
sum *= 2;
}
if (sum > 8000)
{
// if the sum is over 8000 that means that it scored 1 12 times in a row (2^12) - that should happen
//once every 4096 times. Given that we run the simulation 100 000 000 times it should hover around
// 100 000 000/4096
bigWins++;
break;
}
}
totalSum += sum;
}
Console.WriteLine("Average gain over : " + iterations + " iterations is:" + totalSum / iterations);
Console.WriteLine("Expected big wins: " + iterations / 4096 + " Actual big wins: " + bigWins);
Console.WriteLine();
}
Console.ReadKey();
}
输出类似:
Average gain over : 10000 iterations is:12.6774
Expected big wins: 2.44140625 Actual big wins: 1
Average gain over : 100000 iterations is:14.09468
Expected big wins: 24.4140625 Actual big wins: 21
Average gain over : 1000000 iterations is:14.022718
Expected big wins: 244.140625 Actual big wins: 249
Average gain over : 10000000 iterations is:14.0285748
Expected big wins: 2441.40625 Actual big wins: 2456
Average gain over : 100000000 iterations is:14.00012582
Expected big wins: 24414.0625 Actual big wins: 24574
Average gain over : 1000000000 iterations is:14.000105548
Expected big wins: 244140.625 Actual big wins: 244441
Average gain over : 10000000000 iterations is:13.9990068676
Expected big wins: 2441406.25 Actual big wins: 2440546
推荐阅读
- java - 创建后如何设置 Vaadin7 Grid 的 DataType
- google-app-engine - 部署到 GAE 柔性环境时应该跳过哪些文件?
- php - 是否可以获得城市集合但排除任何重复项?
- r - 通过匹配 R 中的 vactor 和列名来填充矩阵中的数据
- java - JSF 页面在提交时不显示任何内容?
- azure-cosmosdb - 如何通过分区优化 cosmoDB 并最终降低成本
- c++ - 如何解决非常大的数组输入的 SIGSEGV 错误?
- php - For循环当月php的第15天和最后一天
- c++ - 如果模板类型也可以是字符串,如何将其转换为字符串?
- graph-databases - 无法为状态为 [INSTALLED] 的索引调用更新操作 [REINDEX]