代码之家  ›  专栏  ›  技术社区  ›  Martin Andersson

需要一个C++的快速随机生成器

  •  44
  • Martin Andersson  · 技术社区  · 16 年前

    我正在尝试在TSP生成器上对欧几里德距离进行一些opt-3交换,因为我在很多情况下有500多个节点,所以我需要随机选择至少一个要尝试交换的3个节点。

    快速的 . (普通的rand()太慢了)它不一定要很棒,只要很好 .

    编辑: 我忘了提到,我所处的环境中,除了标准语言库(如STL、iostream等),我无法添加任何库。所以没有助推=/

    10 回复  |  直到 16 年前
        1
  •  75
  •   Michael Myers KitsuneYMG    16 年前

    另一个线程提到了Marsaglia的xorshf生成器,但没有人发布代码。

    static unsigned long x=123456789, y=362436069, z=521288629;
    
    unsigned long xorshf96(void) {          //period 2^96-1
    unsigned long t;
        x ^= x << 16;
        x ^= x >> 5;
        x ^= x << 1;
    
       t = x;
       x = y;
       y = z;
       z = t ^ x ^ y;
    
      return z;
    }
    

    我到处都用过这个。它唯一失败的地方是当我试图生成随机二进制矩阵时。在大约95x95个矩阵之后,它开始生成太少或太多的奇异矩阵(我忘了是哪个)。结果表明,该发生器相当于一个线性移位反馈寄存器。但是,除非你在做密码学或认真的蒙特卡罗工作,否则这个生成器会崩溃。

        2
  •  33
  •   Scott Stensland    8 年前

    英特尔网站上有两个很好的替代方案:

    inline int fastrand() { 
      g_seed = (214013*g_seed+2531011); 
      return (g_seed>>16)&0x7FFF; 
    } 
    

    2) SSE版本(见下面的链接)的速度约为std rand()的5.5倍,但它一次生成4个随机值,需要一个带有SSE的处理器(几乎所有处理器都有),而且更复杂。

    http://software.intel.com/en-us/articles/fast-random-number-generator-on-the-intel-pentiumr-4-processor/

        3
  •  12
  •   John D. Cook    16 年前

    看见 these generators 来自随机数生成器专家George Marsaglia。它们以C宏的形式实现,速度极快,每生成一个数只需执行几个操作。

        4
  •  7
  •   Serge Rogatch    8 年前

    Ivy Bridge RdRand RdRand CPU指令,以获取所述的16位、32位或64位随机数 here . 滚动到页面中间,查看代码示例。在该链接中还有一个代码示例,用于检查当前CPU对RdRand指令的支持,另请参见Wikipedia,以了解如何使用CPUID指令执行此操作。

    相关问题: Making use of sandy bridge's hardware true random number generator? 兰德 教学最早出现在常春藤桥上,但不是那个问题所说的桑迪桥建筑。)

    基于C++的代码示例 _rdrand64_step() :

    #include <immintrin.h>
    
    uint64_t randVal;
    if(!_rdrand64_step(&randVal)) {
      // Report an error here: random number generation has failed!
    }
    // If no error occured, randVal contains a random 64-bit number
    
        5
  •  6
  •   lhf    16 年前

    这个 Mersenne Twister 有一些快速的实现。

        6
  •  3
  •   ovanes    7 年前

    尽管这篇文章已经有年历史了,但它在我寻找类似答案时出现了,而我最终使用的答案甚至不在其中。所以我加上了我找到的那个;

    #include <random> msdn entry

    这种方法将构建一个自包含的随机生成器,我发现它比 rand()%x rand()% 如果每隔65k次尝试,则不会连续投掷16+个正面/反面。这台不仅能做到,而且能在四分之一的时间内做到。

    这就是我如何实现的 #包括<随机>

    //create rng_gen, using mt technique, with range 0,1 (coin) and 1,6(dice);
    std::random_device rd; //seed
    std::mt19937 gen(rd()); //seed for rd(Mersenne twister)
    std::uniform_int_distribution<> rng_coin(0, 1); //rng1 range
    std::uniform_int_distribution<> rng_dice(1, 6); ///rng2 range
    
    rng_coin(gen); //will apply rng1 range on (gen) object. Is very fast
    rng_dice(gen); //will apply rng2 range, returns int.
    
    //will output 1000 cointosses to console
    for (int i=0;i<1000;++i)std::cout<<rng_coin(gen)<<"\n";
    //will generate 1000 dice throws
    for (int i=0;i<1000;++i)rng_dice(gen);
    
        7
  •  2
  •   Kirill V. Lyadvinsky    8 年前

    Boost库有一组随机生成器。可以找到性能图表 here .

    编辑:这个答案在编辑原始问题之前就在这里了。但我希望它仍然有帮助,所以我把它留在这里。

        8
  •  1
  •   Mikeb    16 年前

        9
  •  0
  •   abelenky    16 年前

    我建议预先用随机数填充一个长列表 ,然后当您需要一个时,只需从列表中选择一个,而不是生成一个。您可以使用后台线程重新填充列表。

        10
  •  0
  •   user2700021 user2700021    13 年前

    http://www.iro.umontreal.ca/~panneton/WELLRNG.html 44497A井当时也很复杂。但是,WELL生成一个介于0和1之间的数字。