C# 随机整数中的最可能位
我做过这样的实验——从C和C#中随机抽取了1000万个数字。然后计算随机整数中15位的每一位被设置的次数。(我选择了15位,因为C只支持高达C# 随机整数中的最可能位,c#,c,random,C#,C,Random,我做过这样的实验——从C和C#中随机抽取了1000万个数字。然后计算随机整数中15位的每一位被设置的次数。(我选择了15位,因为C只支持高达0x7fff的随机整数) 我得到的是: 我有两个问题: 为什么有3个最可能的位?在C情况下,位8,10,12是最可能的。及 在C#中,位6,8,11是最可能的 似乎C#最有可能位与C最有可能位相比,大部分移位了2个位置。为什么会这样?因为C#使用了其他RAND#u MAX常量还是什么 C的我的测试代码: void accumulateResults(in
0x7fff
的随机整数)
我得到的是:
我有两个问题:
C
情况下,位8,10,12
是最可能的。及
在C#
中,位6,8,11
是最可能的C
的我的测试代码:
void accumulateResults(int random, int bitSet[15]) {
int i;
int isBitSet;
for (i=0; i < 15; i++) {
isBitSet = ((random & (1<<i)) != 0);
bitSet[i] += isBitSet;
}
}
int main() {
int i;
int bitSet[15] = {0};
int times = 10000000;
srand(0);
for (i=0; i < times; i++) {
accumulateResults(rand(), bitSet);
}
for (i=0; i < 15; i++) {
printf("%d : %d\n", i , bitSet[i]);
}
system("pause");
return 0;
}
static void accumulateResults(int random, int[] bitSet)
{
int i;
int isBitSet;
for (i = 0; i < 15; i++)
{
isBitSet = ((random & (1 << i)) != 0) ? 1 : 0;
bitSet[i] += isBitSet;
}
}
static void Main(string[] args)
{
int i;
int[] bitSet = new int[15];
int times = 10000000;
Random r = new Random();
for (i = 0; i < times; i++)
{
accumulateResults(r.Next(), bitSet);
}
for (i = 0; i < 15; i++)
{
Console.WriteLine("{0} : {1}", i, bitSet[i]);
}
Console.ReadKey();
}
非常感谢!!顺便说一句,操作系统是Windows7,64位体系结构和VisualStudio2010。
编辑
非常感谢@David Heffernan。我在这里犯了几个错误:
时间
变量值来研究结果的再现性因此,正如许多人所注意到的那样,结果是不可重复的,不应该认真对待。
(除了以某种形式确认C/C#PRNG足够好外:-)。你知道偏差约为2500/5000000,下降到0,05% 这只是常见的或花园取样变异 想象一个实验,你反复掷硬币十次。你不会期望每次都有五个头。这取决于抽样变化 同样,你的实验也会受到抽样变化的影响。每个位遵循相同的统计分布。但采样变化意味着您不会期望在0和1之间出现精确的50/50分割 现在,你的情节正在误导你,使你认为这种变化在某种程度上是有意义的或有意义的。如果从0开始绘制图形的Y轴,您将更好地理解这一点。该图如下所示: 如果RNG表现出应有的行为,则每个位都将以0.5的概率跟随。该分布具有方差np(1)− p) 。对于你的实验,这给出了250万的方差。取平方根得到1500左右的标准偏差。因此,你可以简单地从检查结果中看出,你所看到的变化并不是明显的异常。您有15个样本,没有一个样本与真实平均值的标准偏差超过1.6。那没什么好担心的 您已尝试识别结果中的趋势。您说过有“3个最可能的位”。这只是你对这个样本的特殊解释。尝试使用不同的RNG种子再次运行您的程序,您将看到一些不同的图形。他们仍将拥有相同的品质。有些位设置得比其他位多。但不会有任何可辨别的模式,当你将它们绘制在包含0的图形上时,你会看到水平线 例如,下面是C程序为随机种子
98723498734
输出的结果
我认为这足以说服你进行更多的试验。当你这样做的时候,你会发现没有特殊的位元被给予优惠待遇。注意,每个位元的频率差仅变化约0.08%(-0.03%到+0.05%)。我认为我不会认为这很重要。如果每一点的概率都完全相同,我会发现PRNG非常可疑,而不是有点可疑。你应该期望在过程中出现一定程度的差异,这些过程或多或少都是建模随机性…我在学校的统计课上记不太清楚了,但你需要找出异常值在统计上是否显著,或者仅仅是随机误差的结果。你永远不会得到一个完美的分布。这些结果是可重复的吗?那会让我吃惊的。如果你多次运行同一个测试,我怀疑在随后的运行中,不同的位会出现“更可能”和“不太可能”。我刚刚意识到图表上的比例不是0到1000000,而是加/减一个百分点的分数。我现在不那么惊讶了。请看关于“误导O-tron”的部分。顺便说一句,像这样绘制数据最好是条形图,而不是线形图。这些行在视觉上暗示了相邻位之间的关系,而在本例中,相邻位实际上并不存在。(Edward Tufte可能对此有更多的说法。)在假设每一位都是一致随机的情况下,方差是
n*p*q=n/4
,这意味着500万分之2500是2,还有一点标准差。我的意思不是(因为我几乎从未接触过这个主题,也几乎不知道它的任何具体情况),但是谢谢你的补充。我运行了500000000次迭代,得到了~0.003%+1。但是我们希望当N
变为无穷大时,预期的比率会收敛到50%。@Oli是的,但这里的N
是有限的。所以总是会有抽样变异。谢谢你的统计解释。然而,统计数据并不能解释具体实验结果的原因。在这个问题上,我最感兴趣的是结果的原因我能说精确的seed to random()会导致设置偏好位吗?
(这可以解释伪随机性的“伪”部分)每个具体实现都会有一些比其他设置更多的位。但你无法预测哪一个位子会排在首位,不同的位子会赢得不同的种子。当考虑随机过程时,你不可能在试图解释一个单一的实现上走得很远。你是什么