智能方式生成唯一的随机数

Mic*_*hel 27 c# random

我想生成一系列在00000001到99999999范围内的唯一随机数.

所以第一个可能是00001010,第二个可能是40002928等.

简单的方法是生成一个随机数并将其存储在数据库中,并且每次下次再次执行它并检查数据库中是否已存在该数字,如果存在,则生成一个新数据,再次检查等等.但是看起来不对,如果生成的项目数量很大,我可以重新生成一个数字,可能是100次.

有更聪明的方法吗?

编辑总是我忘记说为什么我想要这个,它可能会让事情更清楚,也许可以得到另一种选择,它是:我们想要为预订生成订单号,所以我们可以使用000001,000002等.但是我们不想让竞争对手知道创造了多少订单(因为它不是一个大批量的市场,我们不希望他们知道我们是在2个月后订购30还是订单100.所以我们想要一个随机的订单号(但却是唯一的)

and*_*ora 23

您可以使用线性同余发生器(LCG)或线性反馈移位寄存器(LFSR).谷歌或维基百科了解更多信息.

使用正确的参数,两者都可以在"全周期"(或"完整周期")的基础上运行,这样它们将在一个周期内仅生成一次"伪随机数",并生成该范围内的所有数字.两者都是"弱"发生器,因此对于数字图形学没有好处,但对于明显的随机性可能"足够好".您可能必须将周期限制在"十进制"最大值内,因为需要"二进制"周期.

更新:我应该补充说,没有必要以任何方式预先计算或预先存储以前的值,您只需要保留先前的种子值(单个int)并计算"按需"下一个数字序列.当然,如果需要,您可以将预先计算的数字链保存到数据库中,但这不是必需的.


ser*_*g10 15

如何创建一组所有可能的数字并简单地随机化订单?然后你可以从尾巴中选择下一个数字.

每个数字在集合中只出现一次,当您想要一个新的数字时,它已经生成了,因此在您想要的时候,开销很小.您可以在内存或您选择的数据库中执行此操作.您只需要一个合理的锁定策略来提取下一个可用的数字.

  • @Jeremy:我的特别高规格的机器可以在大约20秒内生成*和*洗牌那些99,999,999整数的数组.(而这只是使用了一些非优化的LINQ,我很快拼凑在一起.) (2认同)

Laz*_*rus 9

您可以构建一个包含所有可能数字的表,为记录提供一个"已使用"字段.

  1. 选择所有尚未"使用"的记录
  2. 选择1和记录计数之间的随机数(r)
  3. 记录号r
  4. 从记录中获取"随机值"
  5. 设置'used'标志并更新db.

这应该比挑选随机数更有效,查询数据库并重复直到找不到,因为这只是为最后几个值乞求永恒.

  • 注意,这是用于混洗n个数字的O(n ^ 2)算法.(识别未使用的集合是O(n),并且你正在进行O(n)次.)这里提供了用于混洗的O(n)和O(n lg n)算法; 如果您要为数据库表保留数百万个条目而烦恼,为什么不首先快速将其洗牌? (3认同)

Bra*_*mir 5

使用伪随机数生成器.

例如 - 线性同余随机数发生器

(如果增量和n是互质,则代码将生成从0到n-1的所有数字):

    int seed = 1, increment = 3;
    int n = 10;

    int x = seed;
    for(int i = 0; i < n; i++)
    {
        x = (x + increment) % n;
        Console.WriteLine(x);
    }
Run Code Online (Sandbox Code Playgroud)

输出:4 7 0 3 6 9 2 5 8 1

基本随机数发生器

Mersenne Twister