要为“随机分区”问题找到真正公正的解决方案需要做一些工作。但首先有必要了解“无偏见”在这种情况下的含义。
一条推理是基于随机抛硬币的直觉。一枚无偏硬币正面朝上的频率与反面朝上的频率一样多,因此我们可能会认为,我们可以通过将无偏硬币抛 100 次并计数,将 100 次抛掷分成两部分(正面计数和尾部计数)的无偏分区.这就是Edwin Buck's proposal 的精髓,经过修改以生成四分区而不是二分区。
但是,我们会发现许多分区从未出现过。有 101 个 100 的两个分区 -- {0, 100}, {1, 99} … {100, 0} 但硬币抽样解决方案在 10,000 次尝试中发现不到一半。正如所料,分区{50, 50} 是最常见的(7.8%),而从{0, 100} 到{39, 61} 的所有分区总共不到1.7%(而且,在我做的试验中,分区从{0, 100} 到{31, 69} 根本没有出现。)[注1]
所以这看起来不像是可能的分区的无偏样本。一个无偏的分区样本将以相等的概率返回每个分区。
所以另一个诱惑是从所有可能的大小中选择分区的第一部分的大小,然后从剩下的任何大小中选择第二部分的大小,依此类推,直到我们达到小于分区的大小,此时剩下的任何东西都在最后一部分。然而,这也会有偏差,因为第一部分比其他任何部分都大。
最后,我们可以枚举所有可能的分区,然后随机选择其中一个。这显然是不偏不倚的,但不幸的是有很多可能的分区。例如,对于 100 个 4 分区的情况,有 176,581 种可能性。在这种情况下也许这是可行的,但似乎不会导致通用解决方案。
为了更好的算法,我们可以从观察分区开始
{p<sub>1</sub>, p<sub>2</sub>, p<sub>3</sub>, p<sub>4</sub>}
可以无偏差地重写为累积分布函数 (CDF):
{p<sub>1</sub>, p<sub>1</sub>+p<sub>2</sub>, p<sub>1</sub>+p<sub>2</sub>+p<sub>3</sub>, p<sub>1</sub>+p<sub>2</sub>+p<sub>3</sub>+p<sub>4</sub>}
最后一项就是所需的总和,在本例中为 100。
那仍然是 [0, 100] 范围内的四个整数的集合;但是,它保证是按递增顺序排列的。
生成四个以 100 结尾的随机排序序列并不容易,但是生成三个不大于 100 的随机整数,对它们进行排序,然后找到相邻的差异是很简单的。这导致了一个几乎没有偏见的解决方案,对于大多数实际目的来说,这可能已经足够接近了,特别是因为实现几乎是微不足道的:
(Python)
def random_partition(n, k):
d = sorted(randrange(n+1) for i in range(k-1))
return [b - a for a, b in zip([0] + d, d + [n])]
不幸的是,由于sort,这仍然存在偏见。未排序的列表是从所有可能列表中毫无偏差地选择的,但排序步骤不是简单的一对一匹配:具有重复元素的列表比没有重复元素的列表具有更少的排列,因此特定排序列表的概率没有重复的概率远高于有重复的排序列表的概率。
随着 n 相对于 k 变大,具有重复的列表的数量迅速下降。 (这些对应于其中一个或多个部分为 0 的最终分区。)在渐近线中,我们从连续体中进行选择并且碰撞概率为 0,算法是无偏的。即使在 n=100,k=4 的情况下,对于许多实际应用,偏差也可能是可忽略的。将 n 增加到 1000 或 10000(然后缩放生成的随机分区)将减少偏差。
有一些快速算法可以生成无偏整数分区,但它们通常要么难以理解,要么速度慢。慢的,需要时间(n),类似于reservoir sampling;如需更快的算法,请参阅Jeffrey Vitter. 的工作
注意事项
-
这是快速而简单的 Python + shell 测试:
$ python -c '
from random import randrange
n = 2
for i in range(10000):
d = n * [0]
for j in range(100):
d[randrange(n)] += 1
print(' '.join(str(f) for f in d))
' | sort -n | uniq -c
1 32 68
2 34 66
5 35 65
15 36 64
45 37 63
40 38 62
66 39 61
110 40 60
154 41 59
219 42 58
309 43 57
385 44 56
462 45 55
610 46 54
648 47 53
717 48 52
749 49 51
779 50 50
788 51 49
723 52 48
695 53 47
591 54 46
498 55 45
366 56 44
318 57 43
234 58 42
174 59 41
118 60 40
66 61 39
45 62 38
22 63 37
21 64 36
15 65 35
2 66 34
4 67 33
2 68 32
1 70 30
1 71 29