本文介绍了两个区间之间的双精度随机数生成[a,b]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我需要生成 X 在两个区间[a,b]之间均匀分布的随机双数,其中 a X 数字需要在类函数内部生成,例如 myclass :: doSomething(a,b)。事情是每次传递给 doSomething(a,b)函数的间隔 [a,b] doSomething(a,b)函数由另一个类函数调用,例如 doThat()。 我想要一个解决方案,允许我: 1.有一个引擎 ,理想情况下,每次应用程序运行时只应该为种子设置一次。 2. X 在每次调用 doSomething()函数,应该是均匀分布的。 我的解决方案不允许 engine ,似乎生成的数字不一定是均匀分布的。 file:utilities.h template< typename Generator> double randomDoubleEngine(Generator& engine,double low_bound,double high_bound) { if(low_bound> high_bound){ std :: swap(low_bound,high_bound); } return std :: uniform_real_distribution<>(low_bound,high_bound)(engine); } // file:myclass.h void myclass :: doThat(param1,param2){ for(int i = 0; i< myclass.iter; i ++){ ... ... doSomething(a,b); ... } } void myclass :: doSomething(double a,double b) { std :: random_device rd; static std :: mt19937 engine(rd()); ..... double curThreshold = randomDoubleEngine(engine,a,b); ... } 解决方案我想你希望引擎成为myclass的静态成员。我不确定会有什么真正的区别,从你有,除非你需要使用引擎在其他方法。我已经在下面粘贴了一个可能的解决方案。 注意,gcc看起来比标准错误(见代码注释中的链接),所以如果你使用它可能解释为什么你应用于这些数字(检查均匀分布)的任何测试是失败。据我理解,gcc希望引擎返回[0,1]中的数字,而标准说它应该是在一定范围内的整数。 恐怕我只能测试这与gcc 4.4,因为我运行一个较旧的Ubuntu版本和ideone似乎不允许std :: random_device。 #include< random> #include< iostream> / *在GCC 4.4中,uniform_real_distribution被称为uniform_real;重命名为4.5 * *然而,GCC的描述为 * * http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-api-4.6/a00731。 html * *与这里的期望不匹配 * * http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution * *似乎匹配N3337的26.5.8.2.2 * * / #if defined(__ GNUC_MINOR__)&& (__GNUC_MINOR__ #define uniform_real_distribution uniform_real #endif template< typename Generator> double randomDoubleEngine(Generator& engine,double low_bound,double high_bound) { if(low_bound> high_bound){ std :: swap(low_bound,high_bound); } return std :: uniform_real_distribution< double>(low_bound,high_bound)(engine); } class myclass { double curThreshold; static std :: mt19937 engine; void doSomething(double a,double b) { curThreshold = randomDoubleEngine(engine,a,b); } public: myclass():curThreshold(0){} void doThat(){ doSomething(0,10) std :: cout<< 阈值是< curThreshold<< std :: endl; } }; std :: mt19937 myclass :: engine = std :: mt19937(std :: random_device()()); int main() { myclass m; m.doThat(); m.doThat(); return 0; } I need to generate X random double numbers uniformly distributed between two intervals [a,b], where a and b are also double numbers.Those X numbers need to be generated inside of a class function, say myclass::doSomething(a,b). The thing is that the intervals [a,b] passed to the doSomething(a,b) function change each time the doSomething(a,b) function is called by another class function, say doThat().I would like a solution that allows me to:1. Have an engine with a higher scope, ideally, it should be seeded only once per application run.2. The X random double numbers generated inside of each single call to the doSomething() function, should be uniformly distributed.My solution below does not allow a higher scope for the engine and it seems that the generated numbers are not necessarily uniformly distributed.//file: utilities.htemplate <typename Generator>double randomDoubleEngine(Generator& engine, double low_bound, double high_bound ){ if (low_bound > high_bound){ std::swap(low_bound, high_bound); } return std::uniform_real_distribution<>( low_bound, high_bound )( engine );}//file: myclass.h void myclass::doThat(param1, param2){ for(int i=0; i < myclass.iter; i++){ ... ... doSomething(a,b); ... } } void myclass::doSomething(double a, double b) { std::random_device rd; static std::mt19937 engine(rd()); ..... double curThreshold = randomDoubleEngine(engine, a, b); ... } 解决方案 I think you want engine to be a static member of myclass. I'm not sure that will make any real difference from what you have, unless you need to use the engine in other methods. I've pasted a possible solution below.Note also that gcc's looks wrong compared to the standard (see links in code comments), so if you're using that it might explain why whatever test you're applying to these numbers (to check for uniform distribution) is failing. As I understand, gcc wants the engine to return numbers in [0,1), while the standard says it should be uniform integers over some range.I'm afraid I could only test this with gcc 4.4, since I'm running an older Ubuntu release and ideone doesn't seem to allow std::random_device.#include <random>#include <iostream>/* In GCC 4.4, uniform_real_distribution is called uniform_real; renamed in 4.5 * * However, GCC's description here * * http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-api-4.6/a00731.html * * doesn't match expectation here * * http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution * * which seems to match 26.5.8.2.2 of N3337 * */#if defined(__GNUC_MINOR__) && (__GNUC_MINOR__ <= 4)# define uniform_real_distribution uniform_real#endiftemplate <typename Generator>double randomDoubleEngine(Generator& engine, double low_bound, double high_bound){ if (low_bound > high_bound){ std::swap(low_bound, high_bound); } return std::uniform_real_distribution<double>(low_bound, high_bound)(engine);}class myclass{ double curThreshold; static std::mt19937 engine; void doSomething(double a, double b) { curThreshold= randomDoubleEngine(engine, a, b); }public: myclass(): curThreshold(0) {} void doThat(){ doSomething(0,10); std::cout << "threshold is " << curThreshold << std::endl; }};std::mt19937 myclass::engine=std::mt19937(std::random_device()());intmain(){ myclass m; m.doThat(); m.doThat(); return 0;} 这篇关于两个区间之间的双精度随机数生成[a,b]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-20 10:30