boost::mt19937 gen(43);
这工作得很好,但如果我在使用随机数生成器之前需要超过32位的种子怎么办?有没有一种简单的方法可以将64位或128位种子放入Mersenne Twister中?
我发现了一些在生成结果之前加载多个值的示例,但没有一个代码可以工作.
这段代码有几个问题:
std::vector<unsigned int> seedv(1000,11); std::vector<unsigned int>::iterator i=seedv.begin(); boost::mt19937 gen2(i,seedv.end());
首先,调用gen2()始终返回相同的值.我不知道我是怎么搞砸的.
其次,我不想要1000个种子,但是当我将它降低到600时,它会“抛出一个std :: invalid_argument的实例,并在调用种子时注释足够的元素”
这种方法可以缩短为少数种子吗?
这是另一个看起来很简单的代码示例:
std::string seedv("thisistheseed"); std::seed_seq q(seedv.begin(),seedv.end()); boost::mt19937 gen2(q);
但它不会编译.我终于发现std :: seed_seq仅在c 11中可用.我坚持使用gcc 4.7,直到我依赖的库是稳定的.
我想我可以坚持使用32位种子,但我想要更多一点.
我读过这篇文章:
Boost Mersenne Twister: how to seed with more than one value?
我喜欢初始化整个矢量的想法:
mersenne_twister(seed1) ^ mersenne_twister(seed2)
但是如果不修改Mersenne_Twister.hpp,我就没有办法做到这一点
有什么建议?
更新:还有一种方法不做!
unsigned long seedv[4]; seedv[0]=1; seedv[1]=2; seedv[2]=3; seedv[3]=4; boost::mt19937 gen2(seedv,4);
使用正确的强制转换,这应该可行,但是我尝试过的每个强制转换都不会超过编译器.我可以在C中投出任何东西,但C仍然有时会让我感到困惑……
解决方法
更新:使用
boost::random_device rd; boost::mt19937 eng(rd);
boost :: mt19937允许您使用宽度最大为32位的单个值(底层boost :: mersenne_twister_engine的w参数)或624值的序列(基础模板的n参数)来播种. 624是mt19937内部状态中的元素数.
如果您阅读文档,您将看到这两种机制以不同的方式为引擎状态设定种子.
>使用单个值的种子设置使用该单个值的复杂函数设置引擎状态的每个元素.
>使用624个值序列进行种子设定将引擎状态的每个元素设置为完全相应的种子值.
关键是boost :: mt19937本身并不包含将任意数量的种子值映射到其内部状态中固定数量的元素的机制.它允许您直接设置状态(使用624个值),为方便起见,它提供了从单个32位值到完整的624个元素状态的内置映射.
如果要使用任意数量的输入种子值,则需要实现从任意大小的序列到624个元素状态的映射.
请记住,映射的设计应使得生成的内部状态是mersenne Twister算法的“良好”状态.该算法基于移位寄存器,可以生成产生relatively predictable output的内部状态.单值的内置映射旨在最大限度地减少此问题,您应该实现的任何内容.
实现这种映射的最佳方式,而不是自己进行数学分析,可能就是简单地使用标准的mersenne twister预热算法.根据this answer的评论,C 11 std :: seed_seq被指定执行这样的预热. Boost包括boost :: seed_seq,可能会做同样的事情.
更新:您可以简单地使用624个随机值,而不是使用一些任意数量的值来计算624个值的序列.如果这些值是无偏的并且均匀分布在32位值的范围内,那么你就不需要任何预热(好吧,除非你天文学上不幸).
boost::random_device rd; boost::mt19937 eng(rd);
注意,C 11< random>图书馆不支持这种播种方式.