Random 随机均匀生成子集?
下面是一个组合算法的例子,它可以均匀随机地选择n-集的子集。因为一个n-集有2n个子集,所以每个子集应该有一个概率:2-n被选中 我相信我已经正确地实现了这个算法(请告诉我是否有错误)。然而,当我在Linux机器上用Java 7运行程序时,我得到的结果我无法很好地解释。这个谜似乎围绕着随机数发生器。我理解,要“确保分布达到一致性”,需要“大量”运行程序。然而,问题是大到多大。我做过几次实验,结果表明,除非实验次数>=10亿次,否则所选子集的分布是相当不均匀的 该算法基于Herbert Wilf教授的《组合算法》一书,其中的实现(略有不同)是用Fortran完成的,即使程序只运行了1280次,分布也或多或少是一致的 以下是一些示例运行(当n为常数时,运行之间存在一些变化),以获得4-集的随机子集:Random 随机均匀生成子集?,random,probability,subset,Random,Probability,Subset,下面是一个组合算法的例子,它可以均匀随机地选择n-集的子集。因为一个n-集有2n个子集,所以每个子集应该有一个概率:2-n被选中 我相信我已经正确地实现了这个算法(请告诉我是否有错误)。然而,当我在Linux机器上用Java 7运行程序时,我得到的结果我无法很好地解释。这个谜似乎围绕着随机数发生器。我理解,要“确保分布达到一致性”,需要“大量”运行程序。然而,问题是大到多大。我做过几次实验,结果表明,除非实验次数>=10亿次,否则所选子集的分布是相当不均匀的 该算法基于Herbert Wilf教
你会期待这样的表现吗?威尔夫教授怎么可能只用一个等效程序的1280次迭代就获得类似的结果呢?每次调用
ranInt()
,您都会重置RNG。因此,从长远来看,这些数字不再是随机的Moved
Random r=新的Random(System.currentTimeMillis())将代码>添加到顶部,并向其添加静态
class RandomSubsetSimulation {
static Random r = new Random(System.currentTimeMillis());
public static void main(String[] args) { ...
我可以得到以下结果与8集
Total: 1000, number of subsets with a frequency > 0: 256
Total # of subsets possible: 256
4集的完整结果
Frequencies of chosen subsets ....
[3] : 76, 4, 5.94
[4] : 72, 8, 5.63
[] : 83, -3, 6.48
[1] : 90, -10, 7.03
[2] : 80, 0, 6.25
[3, 4] : 86, -6, 6.72
[2, 3] : 88, -8, 6.88
[2, 4] : 55, 25, 4.30
[1, 2, 3] : 99, -19, 7.73
[1, 2, 4] : 75, 5, 5.86
[2, 3, 4] : 76, 4, 5.94
[1, 3] : 85, -5, 6.64
[1, 2] : 94, -14, 7.34
[1, 4] : 72, 8, 5.63
[1, 2, 3, 4] : 71, 9, 5.55
[1, 3, 4] : 78, 2, 6.09
Total: 1280, number of subsets with a frequency > 0: 16
Total # of subsets possible: 16
修正了原始代码