Algorithm 从集合中获取X个唯一数字

Algorithm 从集合中获取X个唯一数字,algorithm,random,theory,set,unique,Algorithm,Random,Theory,Set,Unique,我想,获取唯一随机数最优雅的方法是什么 现在我需要随机唯一数,我使用while循环检查它是否唯一,看看我以前是否使用过随机数 所以它看起来像: int n = getRandomNumber % [Array Size]; for each ( Previously used n in list) Check if I've used n before, if I have...try again. 有很多方法可以解决这个线性O(n/2)问题,我只是想知道是否有一个优雅的方法来解决它

我想,获取唯一随机数最优雅的方法是什么

现在我需要随机唯一数,我使用while循环检查它是否唯一,看看我以前是否使用过随机数

所以它看起来像:

int n = getRandomNumber % [Array Size];

for each ( Previously used n in list)
    Check if I've used n before, if I have...try again.
有很多方法可以解决这个线性O(n/2)问题,我只是想知道是否有一个优雅的方法来解决它。试着回想一下MATH115离散数学,并记住老讲师是否涉及与看似琐碎的问题有关的内容


我现在不能思考,所以也许一旦我喝了一些咖啡因,我的大脑就会用咖啡引起的高智商来支持它。

如果你想从集合{1,…,n}中抽取k个随机整数而不进行替换(以获得唯一的数字),那么你需要的是[n]的随机排列中的第一个k元素。生成这种随机排列的最优雅的方法是使用Knuth shuffle。请参见此处:

既然您要强制唯一性,那么伪随机生成器就足够了,它可以配置为在您可能需要的时间内不重复序列。例如,一个:如果seed是uint32,并且最初为0,那么使用(1664525*seed)+1013904223作为下一个seed,并将低位字作为未重复的16位结果。

在重复内部状态之前,n位最大周期线性移位反馈寄存器(LFSR)将在其所有(2^n-1)内部状态之间循环。LFSR是最大周期LFSR当且仅当由抽头序列加1形成的多项式是基多项式mod 2

因此,n位最大周期LFSR将为您提供(2^n-1)个唯一随机数序列,每个随机数的长度为n位

LFSR非常优雅

抓住我思考的唯一随机数

  • 制作一个由N个唯一元素组成的数组(例如,范围为0..N-1的整数),将N存储为arraySize和initialArraySize(arraySize=N;initialArraySize=N)
  • 请求随机数时:
    2.1如果arraySize为零,则arraySize=initialArraySize
    2.1生成索引=getRandomNuber()%arraySize
    2.3结果=数组[索引]。暂时不要返回结果。
    2.2将数组[index]与数组[arraySize-1]交换。交换是指“交换”c=数组[索引];数组[索引]=数组[数组大小-1];数组[arraySize-1]=c
    2.3减少1。
    2.4返回结果
    您将得到一个随机数列表,在用完唯一值之前,这些随机数不会重复。O(1)复杂性。

    我认为这并不能回答问题。虽然MT的周期不会重复(对于2^19937),但数字本身会重复,这违反了提问者对数字唯一性的限制。你仍然混淆了随机序列的周期与该序列中生成的数字的唯一性。MT序列中的数字一直在重复。如何配置LCG使其不重复数字?如果可以考虑阵列大小,这是可能的(如果事先知道,这很容易),但我怀疑这比@joe snyder所想的要困难得多。这仅适用于足够小的
    n
    。例如,如果
    n
    >=2^32-1,这将是不切实际的。@codekaizen:我从OPs帖子中推测,n是数组的大小,所以在这种情况下这应该是可行的。@GregS:是的,在这种情况下,这是真的。我读这个问题的方式是,他想要生成任意长度的序列。当然,这是伪随机的,并且是完全预先确定的。任何使用算法生成且不涉及特殊类型硬件的内容都将是PRNG。对于TRNG,您必须利用一些被认为是随机的物理现象。它也不能解决OPs问题,因此没有理由怀疑数组长度为2^n-1。可能的重复