获得10000多个独特的随机数(性能)

时间:2011-11-10 11:07:36

标签: performance algorithm random

  

可能重复:
  Create Random Number Sequence with No Repeats

我想写一个只使用数字作为短字符串的URL缩短器。

我不想数数,我希望下一个新数字是随机的(或伪随机)。

首先,思想算法看起来像这样(伪代码):

do 
{
 number = random(0,10000)
}
while (datastore.contains(number))

datastore.store(number, url)

此实现的问题是:由于数据存储包含更多数字,因此循环将多次执行的可能性越大。性能会随着时间的推移而降低。

是否有更好的方法来获取尚未使用的随机数?

3 个答案:

答案 0 :(得分:5)

1)用连续值填充数组

2)shuffle数组

答案 1 :(得分:1)

使用加密。由于加密是可逆的,因此唯一输入会产生唯一输出。对于64位数字,请使用具有64位块大小的密码。对于较小的块大小,例如32位或16位,请查看Hasty Pudding Cypher

无论您需要哪种块大小,只需加密数字0,1,2 ......(以适当的块大小)即可生成所需数量的唯一非序列号。

答案 2 :(得分:0)

一些相关问题:# 2394246# 54059# 158716# 196017# 1608181

正确的方法取决于您将生成多少数字,以及是否需要实时性能。如果您绘制的范围不超过某个范围内可用数字的一小部分,则代码段的平均每个数字时间为O(1),每个后期数字的时间略有增加,但仍为O(1)。例如,请参阅问题#1608181 answer,其中我展示了使用此类代码从k个数字中获取2*k个数字O(k)M<N/2。 (该答案还具有C代码,用于在M>=N/2的O(M)时间内从N个数字的范围生成M个数字,并解释在k时如何将其用于O(M)时间。 )

如果你想要O(1)性能有一个硬时间限制,你可以使用刚刚提到的程序来预加载一个数组,或者可以改组整个范围的整数,如Justin所述。在预处理之后,每次访问都是O(1)。如果你知道你不会从你的1 ... 10000范围内抽取超过3000个数字,并且没有硬限时,那么你所拥有的代码将平均在O(1)时间内运行{{1}}的通过量减少了0.3 ^ k; ,最差约为70%的可能性为1次通过,21%为2次,6%为3次,2%为4次,0.6%为5次,等等。