我试图测试特定数据集群偶然发生的可能性 . 一种强有力的方法是蒙特卡罗模拟,其中数据和组之间的关联被随机重新分配很多次(例如10,000),并且使用聚类度量来比较实际数据与模拟以确定ap值 .
我已经完成了大部分工作,使用指针将分组映射到数据元素,因此我计划随机重新分配指向数据的指针 . 问题:在没有替换的情况下采样的快速方法是什么,以便在复制数据集中随机重新分配每个指针?
例如(这些数据只是一个简化的例子):
数据(n = 12值) - A组:0.1,0.2,0.4 / B组:0.5,0.6,0.8 / C组:0.4,0.5 / D组:0.2,0.2,0.3,0.5
对于每个复制数据集,我将具有相同的簇大小(A = 3,B = 3,C = 2,D = 4)和数据值,但会将值重新分配给簇 .
为此,我可以生成1-12范围内的随机数,分配A组的第一个元素,然后生成1-11范围内的随机数,并分配A组中的第二个元素,依此类推 . 指针重新分配很快,我将预先分配所有数据结构,但没有替换的采样似乎是一个可能已经解决过很多次的问题 .
逻辑或伪代码首选 .
6 回答
请参阅我对这个问题的回答Unique (non-repeating) random numbers in O(1)? . 同样的逻辑应该完成你想要做的事情 .
这里有一些基于Knuth的书籍Seminumeric Algorithms的算法3.4.2S的无需替换的代码 .
Jeffrey Scott Vitter在“An Efficient Algorithm for Sequential Random Sampling”,ACM Transactions on Mathematical Software,13(1),1987年3月,58-67中有一种更有效但更复杂的方法 .
基于answer by John D. Cook的C工作代码 .
受@John D. Cook's answer的启发,我在Nim写了一个实现 . 起初我很难理解它是如何工作的,所以我还广泛评论了一个例子 . 也许这有助于理解这个想法 . 另外,我稍微更改了变量名称 .
当种群大小远大于样本大小时,上述算法变得低效,因为它们具有复杂度O(n),n是种群大小 .
当我还是学生时,我写了一些算法,无需替换即可统一采样,平均复杂度为O(s log s),其中s是样本大小 . 以下是二叉树算法的代码,平均复杂度为O(s log s),在R中:
该算法的复杂性在以下讨论:Rouzankin,P . S . ; Voytishek,A . V.关于随机选择算法的成本 . 蒙特卡罗方法Appl . 5(1999),没有 . 1,39-54 . http://dx.doi.org/10.1515/mcma.1999.5.1.39
如果您发现该算法有用,请参考 .
另见:P . Gupta,G . P. Bhattacharjee . (1984)一种无需替换的随机抽样的有效算法 . 国际计算机数学杂志16:4,第201-209页 . DOI:10.1080 / 00207168408803438
Teuhola,J . 和Nevalainen,O . 1982.两种有效的随机抽样算法,无需替换 . / IJCM /,11(2):127-140 . DOI:10.1080 / 00207168208803304
在上一篇论文中,作者使用哈希表并声称他们的算法具有O(s)复杂性 . 还有一个快速哈希表算法,很快就会在pqR中实现(很快R):https://stat.ethz.ch/pipermail/r-devel/2017-October/075012.html
另一种无需替换的采样算法被描述为here .
它类似于John D. Cook在他的回答和Knuth中描述的那个,但它有不同的假设:种群大小未知,但样本可以适合记忆 . 这个被称为“Knuth算法S” .
引用rosettacode文章: