【发布时间】:2012-03-18 22:27:50
【问题描述】:
我想生成满足0 <= result <= maxValue 的统一整数。
我已经有一个生成器,它返回内置无符号整数类型的全部范围内的统一值。让我们调用此byte Byte()、ushort UInt16()、uint UInt32() 和ulong UInt64() 的方法。假设这些方法的结果是完美一致的。
我想要的方法的签名是uint UniformUInt(uint maxValue)和ulong UniformUInt(ulong maxValue)。
我在寻找什么:
-
正确性
我希望返回值分布在给定的时间间隔内。
但是如果能显着提高性能,非常小偏差是可以接受的。我的意思是,在给定 2^64 值的情况下,允许区分概率为 2/3 的顺序偏差。
它必须适用于任何maxValue。 -
性能
该方法应该很快。 -
效率
该方法确实消耗很少的原始随机性,因为根据底层生成器,生成原始字节可能很昂贵。浪费几位是可以的,但消耗 128 位来生成一个数字可能是多余的。
还可以在某些成员变量中缓存上一次调用的剩余随机性。
注意 int 溢出和包装行为。
我已经有了一个解决方案(我会将它作为答案发布),但它对我的口味来说有点难看。所以我想获得更好的解决方案的想法。
关于如何使用大 maxValues 进行单元测试的建议也很好,因为我无法生成包含 2^64 个桶和 2^74 个随机值的直方图。另一个复杂的问题是,对于某些错误,只有一些 maxValue 分布有很大的偏差,而其他的只有很小的偏差。
【问题讨论】:
-
不使用
floor(maxValue/maxfordatatype*existingrandom())的理由是什么? -
@EugenRieck 它违反了正确性属性,除非
maxfordatatype明显大于maxValue,在这种情况下它会有效率问题。 -
我从您的 OQ 了解到,小偏差是可以接受的,所以我应该理解,1/maxValue 偏差是不能接受的小?
-
@EugenRieck 因为每个返回值只有
1/maxValue的概率,相同幅度的偏差意味着可能根本无法到达某些字段,而其他字段的频率是应有的两倍。System.Random在Next(maxValue)中使用了类似的算法,我只需使用几个样本就可以将其与真正的随机数区分开来。 -
请注意,我量化了小的偏差,因此即使是一个完美的区分器也需要 2^64 个样本,在 2/3 的情况下,当被问到:这个样本集是真正随机的,还是生成的由具有已知偏差的生成器。所以我的要求是非常严格的,我宁愿完全没有偏见。
标签: c# algorithm random uniform