C语言 均匀分布:Bug或Paradox



想象10辆汽车随机均匀地分布在长度为1的圆形轨道上。如果位置由[0,1>]范围内的C双精度对象表示;然后它们可以被分类,汽车之间的间隙应该是前面汽车的位置减去后面汽车的位置。最后一个间隙需要加1,以说明不连续性。

在程序输出中,最后一列的统计数据和分布与其他列非常不同。正确的行相加为1。这是怎么呢

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int compare (const void * a, const void * b)
{
if (*(double*)a > *(double*)b) return 1;
else if (*(double*)a < *(double*)b) return -1;
else return 0;
}
double grand_f_0_1(){
static FILE * fp = NULL;
uint64_t bits;
if(fp == NULL) fp = fopen("/dev/urandom", "r");
fread(&bits, sizeof(bits), 1, fp);
return (double)bits * 5.421010862427522170037264004349e-020; // https://stackoverflow.com/a/26867455
}
int main()
{
const int n = 10;
double values[n];
double diffs[n];
int i, j;

for(j=0; j<10000; j++) {

for(i=0; i<n; i++) values[i] = grand_f_0_1();
qsort(values, n, sizeof(double), compare);

for(i=0; i<(n-1); i++) diffs[i] = values[i+1] - values[i];
diffs[n-1] = 1. + values[0] - values[n-1];
for(i=0; i<n; i++) printf("%.5f%s", diffs[i], i<(n-1)?"t":"n");
}

return(0);
}

下面是输出的一个示例。第一列表示第一辆车和第二辆车之间的距离。最后一列表示第10辆车和第一辆车穿过起点/终点线之间的差距。像。33和。51这样的大数字在最后一列中更常见,而非常小的数字则相对较少。

0.13906 0.14241 0.24139 0.29450 0.01387 0.07906 0.02905 0.03160 0.00945 0.01962
0.01826 0.36875 0.04377 0.05016 0.05939 0.02388 0.10363 0.04640 0.03538 0.25037
0.04496 0.05036 0.00536 0.03645 0.13741 0.00538 0.24632 0.04452 0.07750 0.35176
0.00271 0.15540 0.03399 0.05654 0.00815 0.01700 0.24275 0.25494 0.00206 0.22647
0.34420 0.03226 0.01573 0.08597 0.05616 0.00450 0.05940 0.09492 0.05545 0.25141
0.18968 0.34749 0.07375 0.01481 0.01027 0.00669 0.04306 0.00279 0.08349 0.22796
0.16135 0.02824 0.07965 0.11255 0.05570 0.05550 0.05575 0.05586 0.07156 0.32385
0.12799 0.18870 0.04153 0.16590 0.02079 0.06612 0.08455 0.14696 0.13088 0.02659
0.00810 0.06335 0.13014 0.06803 0.01878 0.10119 0.00199 0.06656 0.20922 0.33263
0.00715 0.03261 0.05779 0.47221 0.13998 0.11044 0.06397 0.00238 0.04157 0.07190
0.33703 0.02945 0.06164 0.01555 0.03444 0.14547 0.02342 0.03804 0.16088 0.15407
0.10912 0.14419 0.04340 0.09204 0.23033 0.09240 0.14530 0.00960 0.03412 0.09950
0.20165 0.09222 0.04268 0.17820 0.19159 0.02074 0.05634 0.00237 0.09559 0.11863
0.09296 0.01148 0.20442 0.07070 0.05221 0.04591 0.08455 0.25799 0.01417 0.16561
0.08846 0.07075 0.03732 0.11721 0.03095 0.24329 0.06630 0.06655 0.08060 0.19857
0.06225 0.10971 0.10978 0.01369 0.13479 0.17539 0.17540 0.02690 0.00464 0.18744
0.09431 0.10851 0.05079 0.07846 0.00162 0.00463 0.06533 0.18752 0.30896 0.09986
0.23214 0.11937 0.10215 0.04040 0.02876 0.00979 0.02443 0.21859 0.15627 0.06811
0.04522 0.07920 0.02432 0.01949 0.03837 0.10967 0.11123 0.01490 0.03846 0.51915
0.13486 0.02961 0.00818 0.11947 0.17204 0.08967 0.09767 0.03349 0.08077 0.23426

您的代码没问题。最后一个差值的平均值是其他差值的两倍。

悖论来自于这样一个事实,即不是在单位区间上选择10个点,而是试图将其分成11个子区间,其中有10个切点。因此,每个子区间的期望长度为1/11。

连续点之间的差值接近1/11,除了最后一对,因为它包含最后一个子区间(最后一个点和点1之间)和第一个子区间(点0和第一个点之间)。

因此最后差值的平均值为2/11。

"圆上无特殊点">

问题是,在一个圆上,有一辆车看起来总是一样的,所以没有必要与零相关:你可以只与第一辆车相关。这意味着你可以将第一辆车固定在零,并将其他汽车的随机位置视为与它相关(从它测量)。

因此,方便的解决方案是将第一辆车固定为0,并认为您仍然生成的9个数字与第一辆车相关。

希望这是一个令人满意的答案:-)

IDENTITY(或哪个diff是第一个?)

如果10辆标有("1","2";等)随机放在一个圆圈上,区别于"1";到下一个的平均值是1/10。排序时,第一个diff失去了它的身份它是什么改变了:它类似于如果你选择第一个困难是最长的,它会平均更多. 根据汽车与零倾斜的关系(或者,用更好的说法:改变)以类似的方式选择它。

第一个差异(第二个,第三个等等)只是变成了一些不同的东西——将其定义为与给定汽车的差异更直观,并提供了将其用作参考的选项(很好地发挥了圆形对称性);其余车辆相对于它的分布是均匀的。处理最小的随机点并不那么简单。

总结:定义你正在计算的东西,知道你的定义和概率是非直觉的

经过3个月的困惑,我有了一个直观的解释,至少对我来说是这样。这是@wojand和@tstanisl提供的答案的累积。

我原来的代码是正确的:它在区间上均匀分布点,并且所有点的前向差具有相同的统计分布。矛盾的是,跨过0-1不连续点的最高值的正向差平均是其他点的两倍,并且它的分布具有不同的形状。

这个正向差值有不同分布的原因是它包含值0。较大的正向差值(间隙)更可能包含任何固定值,因为它们更大。

例如,我们可以搜索包含1/pi的间隙,它也会具有相同的非典型分布。

相关内容

  • 没有找到相关文章

最新更新