随机序列中的周期长度

时间:2015-06-17 16:08:27

标签: c# arrays algorithm random cycle

以下LINQPad代码生成从0到N的唯一整数的随机序列,并计算从0开始的每个整数的循环长度。为了计算给定整数的循环长度,它从{读取值{1}}索引处的数组等于该整数,而不是取值并从索引读取等于该值,依此类推。当从数组读取的值等于我们开始使用的原始整数时,该过程停止。计算每个周期长度所花费的迭代次数将保存到boxes

Dictionary

典型结果如下:

Result from LINQPad

我得到的结果对我来说似乎很奇怪:

  • 所有周期的长度只能分为几个桶(通常为3到7个)。我希望看到更多不同的桶。
  • 大多数时间内每个桶中的元素数量与它们所属的桶值一起增长。我希望它会更随机。

我尝试过几种不同的随机函数,比如.NET的const int count = 100; var random = new Random(); var boxes = Enumerable.Range(0, count).OrderBy(x => random.Next(0, count - 1)).ToArray(); string.Join(", ", boxes.Select(x => x.ToString())).Dump("Boxes"); var stats = Enumerable.Range(0, count).ToDictionary(x => x, x => { var iterations = 0; var ind = x; while(boxes[ind] != x) { ind = boxes[ind]; iterations++; } return iterations; }); stats.GroupBy(x => x.Value).Select(x => new {x.Key, Count = x.Count()}).OrderBy(x => x.Key).Dump("Stats"); stats.Sum(x => x.Value).Dump("Total Iterations"); Random类,以及从random.org生成的随机数据。所有这些似乎都会产生类似的结果。

我做错了吗?这些结果是从数学角度预期的吗?或者,也许,我使用的随机函数的伪性质有副作用?

1 个答案:

答案 0 :(得分:1)

您正在做的是生成大小为count的随机排列。然后检查排列的属性。如果你的随机数生成器是好的,那么你应该观察random permutations的统计数据。

对于k<count,长度k的平均周期数为1 / k。平均而言,有1个固定点,1/2个长度为2个周期,1个长度为3个周期,等等。因此,任何长度的平均周期数为1 + 1/2 + 1/3 + ...... + 1 / count~ln count + gammadistribution of the number of cycles有很多简洁的属性。偶尔会有很多周期,但2 ^#周期的平均值是count + 1。

您的水桶对应于不同周期长度的数量,最多是周期数,但由于重复周期长度可能会更低。平均而言,重复几个循环长度。即使计数增加到无穷大,并且平均周期数增加到无穷大,重复周期长度的平均数也保持有限。

在统计信息中的排列测试(通常是bootstrapping的示例)中,为了分析某些类型的数据,您将其视为排列的示例。例如,您可能会观察到两个数量,x_i和y_i。通过对xs和ys进行排序,并查看y的索引与第k个x值配对,可以获得排列。然后,将此排列的统计信息与随机排列的属性进行比较。这并没有对底层分布做太多假设,但它仍然可以检测x和y何时相关。因此,知道随机排列会有什么期望是有用的。