我有一个使用 rand() 和 srand() 的优化算法。为了能够测试行为,我将种子设置为特定数字,以便在程序的不同运行中获得相同的随机数序列。
#define RN rand()/(RAND_MAX+1.0)
int main(int argc, char **argv)
{
unsigned int seed=47456536;
srand(seed);
// a lot of stuff including RN
}
问题是在不同的运行中我得到不同的数字序列。这可能吗?
最佳答案
首先:Do not use rand . There are enough better alternatives .
即使是 2011 版的 C 标准1 在脚注 295 中说:
There are no guarantees as to the quality of the random sequence produced and some implementations are known to produce sequences with distressingly non-random low-order bits. Applications with particular requirements should use a generator that is known to be sufficient for their needs.
如果没有说服你,请让我强调一下:
There are no guarantees as to the quality of the random sequence produced and some implementations are known to produce sequences with distressingly non-random low-order bits. Applications
with particular requirementsshould use a generator that is known to be sufficient [read: not this one] for their needs.
但是,如果您无故决定使用它,
C99 7.20.2.2 和 C11 7.22.2.2 都定义了 srand 函数如下:
(2) The srand function uses the argument as a seed for a new sequence of pseudo-random numbers to be returned by subsequent calls to rand. If srand is then called with the same seed value, the sequence of pseudo-random numbers shall be repeated. If rand is called before any calls to srand have been made, the same sequence shall be generated as when srand is first called with a seed value of 1.
(3) [...] The implementation shall behave as if no library function calls the srand function.
这意味着2您的标准库已损坏,您正在调用未定义的行为(例如,写入您不应该写入的内存)或者确实有其他一些非确定性来源。您肯定知道,最常见的非确定性来源是线程和读取输入(键盘、时间等)。请注意,从多线程调用 rand/srand 本质上是不安全的3,不仅仅是执行顺序。
由于rand 随机数生成工具只有一个中央状态,您还应该知道that libraries used by your code can modify it as well ,因此您的问题可能隐藏在对库函数(标准库除外)的一些无辜调用中。
我还要重申,rand 使用的算法未指定。因此,不同的编译器(更具体地说是不同的标准库)可以并且将会产生不同的随机数。
最后再说一遍你should not use rand如果可能的话。
如果对您现在应该做什么还有任何疑问,请查看以下完全符合标准的 srand 和 rand 实现:
#define RAND_MAX 32767
static int _rand_state = 1;
void srand(unsigned int seed) { _rand_state = (int)(seed % 32768); }
int rand() { return (++_rand_state) % 32768; }
<子> 脚注:
<子>
1. 如果您使用的是 linux,手册页 rand(3)同意:“在较旧的 rand() 实现中,以及在不同系统上的当前实现中,低位比特的随机性远低于高位比特。当需要良好的随机性时,请勿在旨在可移植的应用程序中使用此功能”
<子>
2. 结合 C99 7.20.2.1/3 或 C11 7.22.2.1/3 保证实现的行为就好像 srand 和 rand 从未被任何标准库调用功能。
<子> 3. C11 在使用这些函数时明确允许数据竞争(C11 7.22.2.1/3 和 C11 7.22.2.2/3),如果 C99 知道线程和线程安全的概念,它也会这样做。
子>子>子>子>
关于c++ srand 不给出相同的随机数序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28374800/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat
给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
如何将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.你能做的最好的事情是:
让多条路线去同一条路的最优雅的方式是什么ControllerAction?我有:get'dashboard',to:'dashboard#index'get'dashboard/pending',to:'dashboard#index'get'dashboard/live',to:'dashboard#index'get'dashboard/sold',to:'dashboard#index'这很丑陋。有什么“更优雅”的建议吗?一个类轮的奖励积分。 最佳答案 为什么不只有一个路由和一个Controller操作,并根据传递给它的参数来
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
假设我必须(小型到中型)阵列:tokens=["aaa","ccc","xxx","bbb","ccc","yyy","zzz"]template=["aaa","bbb","ccc"]如何确定tokens是否以相同的顺序包含template的所有条目?(请注意,在上面的示例中,应忽略第一个“ccc”,从而由于最后一个“ccc”而导致匹配。) 最佳答案 这适用于您的示例数据。tokens=["aaa","ccc","xxx","bbb","ccc","yyy","zzz"]template=["aaa","bbb","ccc"]po
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么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”]、[“苹果”、“
在我的路线文件中我有:match'graphs/(:id(/:action))'=>'graphs#(:action)'如果是GET请求(工作)或POST请求(不工作),我想匹配它我知道我可以使用以下方法在资源中声明POST请求:post'/'=>:show,:on=>:member但是我怎样才能为比赛做到这一点呢?谢谢。 最佳答案 如果你同时想要POST和GETmatch'graphs/(:id(/:action))'=>'graphs#(:action)',:via=>[:get,:post]编辑默认值可以设置如下match'g