Algorithm 穷举随机数发生器

Algorithm 穷举随机数发生器,algorithm,random,Algorithm,Random,在我的一个项目中,我遇到了在给定范围内生成一组数字的需要,这些数字将是: 详尽无遗,这意味着它将涵盖给定的大部分内容 没有任何重复的范围 它将保证确定性(每次序列都是相同的) 相同)。这可能可以通过一个固定的种子来实现 它将是随机的(我对随机数理论不是很精通,但我想有一系列规则描述随机性。从某种角度来看,像0,1,2..N不是随机的) 我说的范围可以是整数范围,也可以是实数范围 例如,如果我使用标准C#随机生成器生成范围为[0,9]的10个数字,我将得到以下结果: 0 0 1 2 0 1 5

在我的一个项目中,我遇到了在给定范围内生成一组数字的需要,这些数字将是:

  • 详尽无遗,这意味着它将涵盖给定的大部分内容 没有任何重复的范围

  • 它将保证确定性(每次序列都是相同的) 相同)。这可能可以通过一个固定的种子来实现

  • 它将是随机的(我对随机数理论不是很精通,但我想有一系列规则描述随机性。从某种角度来看,像0,1,2..N不是随机的)

我说的范围可以是整数范围,也可以是实数范围

例如,如果我使用标准C#随机生成器生成范围为[0,9]的10个数字,我将得到以下结果:

0 0 1 2 0 1 5 6 2 6  
正如您所见,给定范围的很大一部分仍然是“未勘探”的,并且有许多重复

当然,输入空间可能非常大,因此记住以前选择的值不是一个选项

解决这个问题的正确方法是什么

谢谢

评论之后: 好吧,我同意random不是一个正确的词,但我希望你理解我想要实现的目标。我想探索给定的范围,可以是大的,所以内存列表不是一个选项。如果一个范围是(0,10),我想要三个数字,我想保证这些数字是不同的,它们将“描述范围”(即它们不会都在下半部分等)

决定论部分的意思是,我想使用像标准rng这样的固定种子,这样我就可以完全控制序列

我希望我把事情说得更清楚一点


谢谢。

我的印象是,你要找的是随机排列的数字列表,而不是随机排列的数字列表。您应该能够通过以下伪代码获得这一点。更好的数学专家可能会告诉我这是否是随机的:

list = [ 1 .. 100 ]
for item,index in list:
  location = random_integer_below(list.length - index)
  list.switch(index,location+index)

基本上,浏览列表并从列表的其余部分中选择一个随机项用于您所在的位置。这将随机排列列表中的项目。如果每次需要复制相同的随机顺序,考虑保存数组,或者确保某种形式的随机整数总是以给定的种子以相同的顺序返回数字。

< P>如果你只需要某样东西,那么类似的事情是什么?

maxint = 16
step = 7
sequence = 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, 0
如果选择正确的步骤,它将在重复之前生成整个间隔。您可以使用步骤的不同值来获得“看起来”不错的东西。这里的“种子”是序列中开始的地方

这是随机的吗?当然不是。根据随机性的统计测试,它看起来是随机的吗?这可能取决于步骤,但从统计上看,这可能根本不是随机的。但是,它肯定会选择范围内的数字,而不是按照其原始顺序,并且没有迄今为止所选数字的任何内存

事实上,你可以制作一个因子列表,比如[1,2,3,4,5]、[6,7,8,9,10]、[11,12,13,14,15,16]——并使用这些因子的混洗版本来计算阶跃*因子(mod maxint),从而使这一点看起来更好。假设我们对示例因子列表进行了洗牌,如[3,2,4,5,1]、[6,8,9,10,7]、[13,16,12,11,14,15]。然后我们会得到序列

5, 14, 12, 3, 7, 10, 8, 15, 6, 1, 11, 0,  4, 13, 2, 9
因子列表的大小是完全可调的,因此您可以存储任意多的内存。因子列表越大,随机性越强。无论因子列表大小如何,都不会重复。当您用尽一个因子列表时,生成一个新的因子列表就像计数和洗牌一样简单。

不要使用随机数生成器来选择某个范围内的数字。最终会发生的是,您还有一个数字需要填充,您的随机数生成器将重复循环,直到它选择该数字。根据随机数生成器的不同,无法保证会发生这种情况

您应该做的是生成所需范围内的数字列表,然后使用随机数生成器对列表进行无序排列。这种洗牌被称为Fisher-Yates洗牌,有时也被称为Knuth洗牌。下面是将索引从0到n-1的n个元素的数组x洗牌的伪代码:

对于从n-1到1的i
j=随机整数,使得0≤ J≤ 我

交换x[i]和x[j]

按顺序生成包含范围的数组。因此,数组包含
[0,1,2,3,4,5,…N]
。然后使用a对阵列进行置乱。然后,您可以迭代数组以获得随机数


如果需要重复性,请在随机播放开始时使用相同的值为随机数生成器设定种子。

这里有三个不同折衷的选项:

  • 提前生成一个数字列表,并使用。根据需要从列表中选择。O(n)总内存,以及每个元素的O(1)时间。随机性和你用来洗牌的PRNG一样好。这也是三种选择中最简单的一种
  • 使用a,它将在重复之前精确地生成其序列中的每个值一次。O(logn)总内存,以及每个元素的O(1)时间。但是,基于当前值很容易确定未来值,LFSR最容易为2个周期的幂构造(但您可以选择下一个最大的幂2,并跳过任何超出范围的值)
  • 使用一个。可以使用2个周期的任意幂,并且需要额外的技巧,可以使用任意周期。O(logn)总空间和每个元素的O(1)时间,随机性和分组密码一样好。三者中最复杂的一个需要实现

  • 一个随机数是随机的,如果你不想重复,你不想对10个从1到10的真正随机数进行随机,你会期望有三个重复数和三个缺失数。如果你不想允许重复,你就不要真正的随机数。谷歌生日悖论。
    决定论
    随机论
    不能同时进行。随机意味着你无法预测,而决定论意味着知道