简体   繁体   English

使用Boost.Random从种子生成多精度整数

[英]Using Boost.Random to generate multiprecision integers from a seed

I am attempting to use the Boost multiprecision libraries for C++ to generate large random numbers. 我正在尝试使用C ++的Boost多精度库来生成较大的随机数。 I have been unable to create a generator which is seeded by the time or another random number, so my generator produces the same numbers on every run. 我无法创建按时间或其他随机数作为种子的生成器,因此我的生成器在每次运行时都会生成相同的数字。 How do I seed the generator with a changing value to produce different values on each run? 如何为发生器生成变化值的种子,以便在每次运行中产生不同的值? Here is the code which works but produces the same values on each run: 这是有效的代码,但每次运行都会产生相同的值:

 using namespace boost::multiprecision;
 using namespace boost::random;

 typedef independent_bits_engine<mt19937, 512, mpz_int> generator_type;
 generator_type gen;

 std::cout << gen() << "\n\n";

I have seeded the std mersenne twister before with success: 我已经成功播种了标准梅森纳捻线机:

std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 410);
std::cout << dis(gen);

but I am not sure how to seed the multiprecision mt. 但我不确定如何播种多精度mt。 I get an error if I try to attach any arguments to the generator_type declaration. 如果尝试将任何参数附加到generator_type声明,则会收到错误消息。

Just be sure to include the right headers in the right order. 只要确保以正确的顺序包含正确的标题即可。 Make sure boost/multiprecision/random.hpp is included before eg boost/random.hpp . 确保例如boost/random.hpp 之前包含boost/multiprecision/random.hpp boost/random.hpp [1] [1]

Here's a working sample: 这是一个工作示例:

Live On Coliru 生活在Coliru

#include <boost/multiprecision/gmp.hpp>
#include <boost/multiprecision/random.hpp>
#include <iostream>

int main() 
{
    namespace mp = boost::multiprecision;
    using Int = mp::mpz_int;

    boost::mt19937 rng(3); // fixing seed for demo
    boost::uniform_int<Int> gen(-pow(Int(2), 400), pow(Int(2), 400));

    for (int i=0; i<10; ++i)
        std::cout << gen(rng) << "\n";
}

Prints: 打印:

-1933652715378833784248363501979652496795524829874743132697181322648247480952527478485970668716806865063045317090084841622
-1468881213423638668843172777487968633185322950671475476288214928834762957270366851213470028408822700452414112732095789399
-438410269130756764874038685663894375462191729266787898021001121529040612201593866121171654735148672212107859934777249455
1640218057904403949431629353470797958943403389857715009204662011172706206212175540336638682612917363014646204359229208161
2080556950904231221688486212902649050443577133350992840521950777901511719409216800649680002332270542856870490906586634021
-2462847552934789794366130512379986584363897268428607239076390917679673552257507232435012961043902569359791960286013555735
1862125165202309929540318106374963238582997665808535945941185531430178511983671609033768595314282085775703389782906055681
-2252919975572088150601736662143078753669379374770846936106371833826830834376177961242332270710557376868189820866644291936
986998873018694187216384502983789929097242088320473495018118860428802373488463609060400540575932015408503979156759366945
111638721010166959954664901006097000984357549061159193446548907668369849648549091048841517202745565156043524728780018634

[1] For rationale see the header: [1]有关原理,请参见标题:

namespace boost{ namespace random{ namespace detail{
//
// This is a horrible hack: this declaration has to appear before the definition of
// uniform_int_distribution, otherwise it won't be used...
// Need to find a better solution, like make Boost.Random safe to use with
// UDT's and depricate/remove this header altogether.
//
template<class Engine, class Backend, boost::multiprecision::expression_template_option ExpressionTemplates>
boost::multiprecision::number<Backend, ExpressionTemplates> 
   generate_uniform_int(Engine& eng, const boost::multiprecision::number<Backend, ExpressionTemplates>& min_value, const boost::multiprecision::number<Backend, ExpressionTemplates>& max_value);

}}}

You can seed an independent_bits_engine in the following way: 您可以通过以下方式播种independent_bits_engine

gen.seed(a_value_used_as_seed)

See this . 看到这个

EDIT 编辑

The mt19937 produces uint32_t integers and uses the same type as seed. mt19937产生uint32_t整数,并使用与种子相同的类型。 However, it accepts also a seed sequence, wich can be used to create seeds that are beter distributed across the entire 32-bit range. 但是,它也接受种子序列,它可以用来创建更好地分布在整个32位范围内的种子。 The seed sequence can be any class, as long as it defines some functions. 种子序列可以是任何类,只要它定义了某些功能即可。 One of them is the following: 其中之一是以下内容:

void generate(type*,type*)

These two different ways of seeding are represented by two template functions. 这两种不同的播种方式由两个模板函数表示。

The type that is used in the independent_bits_engine is the mpz_int integer. independent_bits_engine使用的类型是mpz_int整数。 When the engine is seeded, it passes the seed to the base engine, the mersenne twister. 发动机播种后,它将种子传递给基本发动机,即梅森捻线机。 For the mt19937 the mpz_int , is not its base type, so the compiler selects the second template function and interprets the seed as a seed sequence. 对于mt19937mpz_int ,不是它的基类型,所以编译器选择所述第二模板函数和解释种子作为种子序列。 This causes an error because the mpz_int class, doesn't have a generator function. 因为mpz_int类没有generator函数,所以会导致错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM