我的老师告诉我在同一个脚本的连续运行之间在awk中使用随机非相关数字的唯一方法是保存用于存档的最后一个种子,然后在开始另一次执行时再次读取它。
到目前为止,我正在尝试这个:
BEGIN {
getline seed < "myseed.txt";
srand(seed);
print rand();
print rand();
print srand() > "myseed.txt";
}
但myseed.txt
的唯一内容始终为0,每次执行时都会得到相同的随机数。
关于如何保存内部随机数生成器的状态然后恢复生成随机数的任何想法,确切地说它是在相同脚本的不同执行之间停止的位置?
答案 0 :(得分:3)
关于种子实际上是什么似乎有些混乱。它是一个用作初始化随机数生成器的参数的值,就是这样;它不包含随机数生成器的当前状态。如果您使用任何N调用srand(N)
,然后生成一些随机数,然后再次调用srand()
(使用任何种子),返回值将是原始N,无论您有多少随机数在此期间产生了。
如果目标是拥有可重现的数字串,允许中断,那么您不仅需要保存种子,还需要保存自播种以来生成的随机数的数量,并在开始时生成并丢弃许多下一次运行。这是一个糟糕的黑客,你可能会更好地实现自己的RNG,或者更可能的是,使用除了awk以外的东西。
如果目标是确保即使在一秒钟内运行两次也不会生成相同的序列,那么您应该阅读the link Ed Morton posted in his comment处的讨论。
答案 1 :(得分:1)
要么我误解了你的问题,要么你正在完成与你想要实现的完全相反的问题。如果您从文件中读取种子,请使用它,将相同的种子写回文件以便下次重复使用,您将始终拥有相同的种子,因此始终生成相同的数字。
$ awk 'BEGIN{srand(1234);print rand()}' && sleep 1 && awk 'BEGIN{srand(1234);print rand()}'
0.240849
0.240849
如果您没有为srand()
提供种子,它将使用自纪元以来的秒数:
$ awk 'BEGIN{srand();print rand()}' && sleep 1 && awk 'BEGIN{srand();print rand()}'
0.2776
0.668099
...因此它每秒只会产生一次新数字。您可以使用$RANDOM
(如果您的shell支持它;每次使用时更改)或者自纪元(如果您的date
支持它)的纳秒数作为种子来解决此问题,例如:
$ awk -v seed="$RANDOM" 'BEGIN{srand(seed);print rand()}' && awk -v seed="$RANDOM" 'BEGIN{srand(seed);print rand()}'
0.661197
0.325718
$ awk -v seed="$(date +%N)" 'BEGIN{srand(seed);print rand()}' && awk -v seed="$RANDOM" 'BEGIN{srand(seed);print rand()}'
0.588395
0.911353
答案 2 :(得分:1)
srand(seed)为“seed”
取整数值rand()返回一个十进制数&gt; = 0和&lt; 1。
因此,保存rand()的输出以直接用作下一个种子将导致srand()始终使用零种子。看(记得调用srand()会返回使用的PREVIOUS种子):
$ awk -v s=0.1 'BEGIN{srand(s); print rand(); print srand()}'
0.566305
0
$ awk -v s=0.9 'BEGIN{srand(s); print rand(); print srand()}'
0.566305
0
因此,如果你想使用rand()的输出作为下一个种子,你需要将它乘以你希望种子小于的数量,例如: 1000000:
$ awk 'BEGIN{
if ( (getline s < "myseed.txt") > 0 ) {
print "seed read from file =", s
srand(1000000*s)
}
else {
print "using default seed of seconds since epoch"
srand()
}
r = rand()
print r > "myseed.txt"
print "seed actually used by srand() was:", srand()
print "rand() =", r
}'
using default seed of seconds since epoch
seed actually used by srand() was: 1368282525
rand() = 0.331514
$ awk 'BEGIN{
if ( (getline s < "myseed.txt") > 0 ) {
print "seed read from file =", s
srand(1000000*s)
}
else {
print "using default seed of seconds since epoch"
srand()
}
r = rand()
print r > "myseed.txt"
print "seed actually used by srand() was:", srand()
print "rand() =", r
}'
seed read from file = 0.331514
seed actually used by srand() was: 331514
rand() = 0.677688
$ awk 'BEGIN{
if ( (getline s < "myseed.txt") > 0 ) {
print "seed read from file =", s
srand(1000000*s)
}
else {
print "using default seed of seconds since epoch"
srand()
}
r = rand()
print r > "myseed.txt"
print "seed actually used by srand() was:", srand()
print "rand() =", r
}'
seed read from file = 0.677688
seed actually used by srand() was: 677688
rand() = 0.363388
第一次执行时,文件“myseed.txt”不存在。