Swift-播种arc4random_uniform?还是另类? [英] Swift - Seeding arc4random_uniform? Or alternative?

查看:71
本文介绍了Swift-播种arc4random_uniform?还是另类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我首先说明我要完成的工作:

Let me start by stating what I'm trying to accomplish:

  1. 我需要随机生成一个范围内的数字
  2. 我希望这些数字可以均匀分布
  3. 我需要能够为随机数生成提供种子,以便在获得种子的情况下,所得的随机数将始终相同.

在对drand48(),rand()和arc4random()进行了大量实验之后,我目前决定使用rand()获得随机数,并使用srand()进行播种.这是一个简化的示例,

After experimenting quite a bit with drand48(), rand() and arc4random(), I have currently settled on using rand() for obtaining a random number, and srand() for seeding. Here is a small example simplified from what I am doing:

let seed: UInt32 = 10
srand(seed)
let start = 0
let end = 100
let randomNumber = Double(rand()) % (end + 1 - start) + start

这有效.给定相同的种子,就会产生相同的随机数.执行多个randomNumber计算会导致出现多个不同的随机数.通过srand重新播种会再次开始随机性".

This works. Given the same seed, the same random number comes out. Performing multiple randomNumber calculations results in multiple, different random numbers coming out. Re-seeding via srand starts the "randomness" over again.

唯一的缺点是rand()不是均匀分布的.的确,我几乎总是得到一组在很大程度上线性增长的数字.

The only downside is rand() is not uniformly distributed. Indeed I pretty much always end up with a set of numbers that are linearly increasing for the most part.

听起来arc4random_uniform会生成更多均匀的随机输出,但是根据我的研究,不可能播种arc4random,因为它是在第一次调用时本身就播种的,不一定要设计"为种子外部.

It sounds like arc4random_uniform will generate more of a uniform random output, however from my research it isn't possible to seed arc4random, as it seeds itself the first time it is invoked and isn't necessarily "designed" to be seeded externally.

所以我的问题;除了srand()/rand()之外,还有更好的替代方法,它仍然可以为给定的种子提供相同的输出,但是这些输出分布更均匀吗?

So my question; is there a better alternative to srand() / rand() that will still give me the same outputs for a given seed, but those outputs are more uniformly distributed?

谢谢, -亚当

推荐答案

事实证明,srand/rand组合符合我的需要,导致结果不均匀分布"的问题是我自己的逻辑错误.

It turns out, srand / rand combined do suit my needs, the issue causing the results to not appear "uniformly distributed" was a bug in my own logic.

作为参考,本质上我是在做这件事(实际上,它要复杂得多,但出于演示目的):

For reference, essentially what I was doing was this (in reality it was much more complex, but for demonstration purposes):

let start = 0
let end = 100

for x in 0..<10 {

   let seed = UInt32(x)
   srand(seed)
   let randomNumber = Double(rand()) % (end + 1 - start) + start

   // Do something with random number

}

上面以更简单的形式编写的问题变得很明显.我在循环的每次迭代中都重新播种,种子值只是线性增加.因此,随机结果也呈线性增加.

Written in the much more simpler form above, the problem becomes obvious. I was re-seeding every iteration of the loop, and the seed value was just incrementing linearly. Because of this, the random results were also incrementing linearly.

简单的解决方案是不重新种子每次循环迭代,而是在循环之前种子一次.例如:

The simple solution is to not re-seed each loop iteration, but to instead seed once before the loop. For example:

let start = 0
let end = 100
let seed = UInt32(100)
srand(seed)

for x in 0..<10 {

   let randomNumber = Double(rand()) % (end + 1 - start) + start

   // Do something with random number

}

通过此简单更改,结果值似乎在示例中使用的0到100范围内确实均匀分布.我不能确定是否有更统一"的方式来做到这一点,但我想是因为自从我读到arc4random优于drand/rand/erand/etc函数后,就产生了统一的随机数,但是至少这似乎可以满足我的需求.

With this simple change, the resulting values do appear to be somewhat uniformly distributed across the 0 to 100 range used in the example. I can't be sure if there is a "more uniform" way of doing this, but I assume there is since I have read arc4random is "far superior" to drand / rand / erand / etc functions for uniform random number generation, but at least this seems to be working for my needs.

如果其他人想出一种更好的方法来实现我所追求的目标,那么我将把这个问题搁置一会儿.

I will leave this question open for a while longer in the event that someone else comes up with a better approach to accomplishing what I am after.

这篇关于Swift-播种arc4random_uniform?还是另类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆