C# 随机索引数组的最快方法
我有一个双值“vals”数组,我需要随机索引到该数组并获取一个值。 GenRandomNumber() 返回 0 到 1 之间的数字,但绝不是 0 或 1。我使用 Convert.ToInt32 基本上将所有内容都放在小数点左侧,但必须有更有效的方法来执行此操作吗?
这是我的代码:
public double GetRandomVal()
{
int z = Convert.ToInt32(GenRandomNumber() * (vals.Length));
return vals[z];
}
感谢
更新
感谢所有回复的人,但我只能使用提供的 MersenneTwister 随机数实现,该实现具有方法 rand.NextDouble()
更新 2
再考虑一下,所有我需要做的是生成一个 0 到 array.length-1 之间的随机数,然后使用它随机索引到数组。 vals 长度为 2^20 = 1048576,因此生成随机 int 就足够了。 我注意到我的 MersenneTwister 有一个方法:
public int Next(int maxValue)
如果我像 vals[rand.Next(vals.length-1)] 那样调用它,应该这样做吗? 我还看到 MersenneTwister 有一个构造函数:
public MersenneTwister(int[] init)
不确定它的用途是什么,我可以使用它来预填充我为其提供 0 到 vals.length 的数组的可接受的随机数吗?
FYI vals 是一个长度为 1048576 的双精度数组,用于划分正态分布曲线。 我基本上使用这种机制来尽可能快地创建正态分布数字,蒙特卡洛模拟每天使用数十亿个正态分布随机数,所以一点点都有帮助。
I have an array of double values "vals", I need to randomly index into this array and get a value. GenRandomNumber() returns a number between 0 and 1 but never 0 or 1. I am using Convert.ToInt32 to basically get everything to the left of my decimal place, but there must be a more efficient way of doing this?
Here's my code:
public double GetRandomVal()
{
int z = Convert.ToInt32(GenRandomNumber() * (vals.Length));
return vals[z];
}
Thanks
Update
Thanks to all those who have replied, but I am constrained to use a supplied MersenneTwister random number implementation that has method rand.NextDouble()
Update 2
Thinking about this some more, all I need to do is gen a random number between 0 and array.length-1 and then use that to randomly index into the array. vals length is 2^20 = 1048576 so generating a random int is sufficient. I notice my MersenneTwister has a method:
public int Next(int maxValue)
If I call it like vals[rand.Next(vals.length-1)] that should do it right? I also see the MersenneTwister has a constructor:
public MersenneTwister(int[] init)
Not sure what this is for, can I use this to prepopulate the acceptable random numbers for which I provide an array of 0 to vals.length?
FYI vals is a double array of length 1048576 partitioning the normal distribution curve. I am basically using this mechanism to create Normally distributed numbers as fast as possible, the monte carlo simulation uses billions of Normally distributed random numbers every day so every little bit helps.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
尝试使用随机整数代替:
Try using a random integer instead:
其中 rng 是
Where rng is
我认为您已经确定了最简单、最直接的实现。
但是,如果您正在寻求随机索引算法的性能提升,您也许可以将 IEEE 754 编码的双精度“破解”为其指数和分数 - 并使用以数组大小为模的分数:随机索引。
这种技术不太可能在密码学上安全 - 所以如果这是一个考虑因素 - 不要这样做。
另外,这种方法不会使代码更加明显 - 我会坚持使用原来的实现,除非考虑最大化性能。 顺便说一句,此处理中最慢的部分很可能是 Mersenne Twister 生成随机数。
这是代码:
I think you have the simplest most direct implementation already identified.
But if you are looking for performance gains in your random indexing algorithm, you may be able to just 'crack' the IEEE 754 encoded double into its exponent and fraction - and use the fraction modulo the array size as a random index.
This technique IS NOT likely to be cryptographically secure - so if that is a consideration - don't do it.
Also, this approach DOES NOT make the code more obvious - I would stick with your original implementation unless maximizing performance is the consideration. As an aside, the slowest part of this processing is most likely the Mersenne Twister generation of random numbers.
Here's the code:
您是否考虑过使用 .NET Random 类?
Have you considered using the .NET Random class?
我会使用 Random.Next(Int32),它返回一个值小于输入且 >= 零。 将数组长度作为输入传递,您将获得一个随机的有效索引。
I would use Random.Next(Int32), which returns a value less than the input and >= zero. Pass your array length as the input, and you've got a random valid index.
正如其他人已经指出的那样,System.Random 有一个 Next 重载,它将执行您已经要求的操作。
至于您对
Convert.ToInt32
和更有效的替代方案的评论,您可以直接将double
转换为int
:As other people have already noted, System.Random has a Next overload that will do what you're asking already.
As to your comment about
Convert.ToInt32
and a more efficient alternative, you can directly cast adouble
to anint
:如果您不限制使用随机函数,请使用
Random
类。否则,我只会使用强制转换,因为它提供了正确的行为 - 四舍五入到零,而不是像
Convert.ToInt32()
那样舍入到最接近的整数。If you are not constraint to use your random function, use the
Random
class.Else I would just use a cast because it gives the right behavior - rounding towards zero instead of the closest integer as
Convert.ToInt32()
does.