c - 均匀分布 : Bug or Paradox

标签 c debugging random paradox uniform-distribution

想象一下10辆车随机,均匀分布在长度为1的圆形轨道上。如果位置用[0,1>范围内的C double表示,那么它们可以排序,车之间的间隙应该是车的位置前面减去后面汽车的位置。最后一个间隙需要添加 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 个点,而是实际上试图将其划分为 10 个切割的 11 个子间隔。因此每个子间隔的预期长度为 1/11。
除了最后一对之外,连续点之间的差异接近 1/11,因为它包含最后一个子区间(最后一个点和点 1 之间)和第一个子区间(点 0 和第一个点之间)。
因此,最后一个差异的平均值是 2/11。

关于c - 均匀分布 : Bug or Paradox,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68957388/

相关文章:

c++ - Floyd 循环查找算法中使用的 While 条件

c - 功能性能测试

ios - 使用字典中的值更新多个标签?

javascript - 如何在随机有序列表中随机化多个无序列表?

c# - 在 C# 中实现 "percent chance"

C .pc 文件警告

c - 如何检测空的epoll集

.net - 轻量级 .NET 调试器?

visual-studio-2010 - VS.NET 2010 中的异常窗口缺少 "User-unhandled"列

javascript - 在 Android Webkit : unhelpful exception 中调试