在标准库的至少一个实现中,第一次调用 std::uniform_int_distribution<> 不返回随机值,而是返回分布的最小值。也就是说,给定代码:
default_random_engine engine( any_seed() );
uniform_int_distribution< int > distribution( smaller, larger );
auto x = distribution( engine );
assert( x == smaller );
... x实际上会是 smaller对于 any_seed() 的任何值, smaller , 或 larger .
要在家一起玩,您可以尝试 code sample在 gcc 4.8.1 中演示了这个问题。
我相信这是不正确的行为?如果这是正确的行为,为什么随机分布会返回这个明显非随机的值?
最佳答案
这就是uniform_int_distribution如果可能结果的范围小于 rng 产生的数字范围,则将随机位映射到数字:
const __uctype __uerange = __urange + 1; // __urange can be zero
const __uctype __scaling = __urngrange / __uerange;
const __uctype __past = __uerange * __scaling;
do
__ret = __uctype(__urng()) - __urngmin;
while (__ret >= __past);
__ret /= __scaling;
哪里__urange是larger - smaller和 __urngrange是 rng 可以返回的最大值和最小值之间的差值。 (代码来自 libstdc++ 6.1 中的 bits/uniform_int_dist.h)
在我们的例子中,rng default_random_engine是 minstd_rand0 , 产生 __scaling == 195225785对于您测试的 [0,10] 范围。因此,如果 rng() < 195225785 ,分布将返回 0。
第一个数字a minstd_rand0返回是
(16807 * seed) % 2147483647
(其中 seed == 0 被调整为 1 顺便说一句)。因此我们可以看到 minstd_rand0 产生的第一个值用小于 11615 的数字播种将产生 0 与 uniform_int_distribution< int > distribution( 0, 10 );你用过。 (修改我的错误。;))
您提到了较大种子会消失的问题:一旦种子变得足够大以实际使 mod 操作执行某些操作,我们就不能简单地将整个范围的值按除法分配给相同的输出,因此结果将看起来更好。
没有。您总是选择较小的随机 32 位种子,从而引入了明显的偏差。结果中出现的这种偏见并不令人惊讶或邪恶。对于随机种子,即使是你的 minstd_rand0将产生一个相当均匀随机的第一个值。 (尽管之后的数字序列的统计质量不高。)
情况1:您想要统计质量高的随机数。
为此,您可以使用更好的 rng,例如 mt19937并播种其整个状态空间。对于 Mersenne Twister,这是 624 个 32 位整数。 (作为引用,here 是我尝试通过答案中的一些有用建议正确地做到这一点。)
情况 2:您确实只想使用那些小种子。
我们仍然可以从中得到不错的结果。问题是伪随机数生成器通常“有点持续”地依赖于它们的种子。为了解决这个问题,我们丢弃了足够多的数字,让最初相似的输出序列发散。所以如果你的种子必须很小,你可以像这样初始化你的 rng:
std::mt19937 rng(smallSeed);
rng.discard(700000);
为此使用像 Mersenne Twister 这样好的 rng 是至关重要的。我不知道有什么方法可以从播种不良的种子中获得体面的值(value) minstd_rand0 ,例如参见 this train-wreck .即使播种得当,mt19937 的统计特性远远优于。
您有时会听到的对大状态空间或缓慢生成的担忧在嵌入式世界之外通常是无关紧要的。根据boost和 cacert.at , MT 甚至比 minstd_rand0 快得多.
虽然您的结果肉眼看起来不错,但您仍然需要使用丢弃技巧。在我的系统上用时不到一毫秒,而且您不会经常播种 rng,所以没有理由不这样做。
请注意,我无法准确估计我们需要的丢弃物数量,我从 this answer 中获取了该值, 它链接 this paper为理性。我现在没有时间解决这个问题。
关于C++ uniform_int_distribution 总是在第一次调用时返回 min(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40020657/
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在学习Rails,并阅读了关于乐观锁的内容。我已将类型为integer的lock_version列添加到我的articles表中。但现在每当我第一次尝试更新记录时,我都会收到StaleObjectError异常。这是我的迁移:classAddLockVersionToArticle当我尝试通过Rails控制台更新文章时:article=Article.first=>#我这样做:article.title="newtitle"article.save我明白了:(0.3ms)begintransaction(0.3ms)UPDATE"articles"SET"title"='dwdwd
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我写了一个非常简单的rake任务来尝试找到这个问题的根源。namespace:foodotaskbar::environmentdoputs'RUNNING'endend当在控制台中执行rakefoo:bar时,输出为:RUNNINGRUNNING当我执行任何rake任务时会发生这种情况。有没有人遇到过这样的事情?编辑上面的rake任务就是写在那个.rake文件中的所有内容。这是当前正在使用的Rakefile。requireFile.expand_path('../config/application',__FILE__)OurApp::Application.load_tasks这里
-if!request.path_info.include?'A'%{:id=>'A'}"Text"-else"Text"“文本”写了两次。我怎样才能只写一次并同时检查path_info是否包含“A”? 最佳答案 有两种方法可以做到这一点。使用部分,或使用content_forblock:如果“文本”较长,或者是一个重要的子树,您可以将其提取到一个部分。这会使您的代码变干一点。在给出的示例中,这似乎有点矫枉过正。在这种情况下更好的方法是使用content_forblock,如下所示:-if!request.path_info.inc
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“