从没有重复的另一个人中产生确定性的INT
我希望创建一个确定的数字生成函数,其中输入号始终会生成相同的数字,但是没有两个数字最终会生成相同的结果。
例如:
1 -> 3
2 -> 5
3 -> 4
4 -> 2
5 -> 1
但是,我需要为所有可以用特定数据类型表示的数字(例如INT64)代表的所有数字工作。
这感觉像是应该很简单或完全不可能的东西。是否有一些随机数生成方案可以保证这种分布,而无需我创建所有可能数字的数组,然后随机排序,然后使用索引(并在此期间让我用尽我的内存)?
非常感谢 f
I'm looking to create a deterministic number generation function where the input number will always generate the same number, but no two numbers will end up generating the same result.
E.g.:
1 -> 3
2 -> 5
3 -> 4
4 -> 2
5 -> 1
However I need this to work for all numbers that can be represented by a specific datatype, e.g. an int64.
This feels like something that should either be really straightforward, or completely impossible. Is there some random number generation scheme that guarantees this sort of distribution without me having to create an array of all possible numbers, randomly sort, and then use the index (and making me run out of memory in the meantime)?
Many thanks
F
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您需要的转换公式是:
这是仿射密码。
mod
确保它在所需的范围内,s
是一个简单的偏移,m
应该为 coprime 带有n
。企业简单地表示
n
和m
不应共享任何常见因素。由于
n
是2^64,其唯一的因素是2
- som
基本上不应偶尔(即2):2):因此,对于
uint64
范围:这可能看起来很魔术,但是您可以说服自己,它可以与
uint16
:https://go.dev/play/p/ekb6sh3-sgu
uint64 将需要大量资源来运行:-)
更新 :
对于签名的数字(即
int64
)逻辑没有什么不同。由于我们知道我们使用uint64
的唯一一对一映射,一种方法就是转换输入&输出从UINT64
到INT64
,反之亦然:再次是
int16
示例证明没有碰撞:https://go.dev/play/p/fkw5flmk0fu
The transformation formula you need is:
This is modular arithmetic as used in the Affine cipher.
The
mod
ensures it is within desired range,s
is a simple shift andm
should be coprime withn
.Coprime simply means
n
andm
should not share any common factors.Since
n
is 2^64 its only factors are the number2
- som
should basically not be even (i.e. not divisible by 2):So for
uint64
range:This may appear magic, but you can convince yourself it works with
uint16
:https://go.dev/play/p/EKB6SH3-SGu
(as
uint64
would take quite some resources to run :-)Update:
For signed numbers (i.e.
int64
) the logic is no different. Since we know we have a unique one-to-one mapping withuint64
one approach would simply be to convert inputs & outputs fromuint64
toint64
and vice versa:again here's a
int16
example proving there's no collisions:https://go.dev/play/p/Fkw5FLMK0Fu
要添加到 colm.anseo 答案,这种映射也被称为线性一致生成器。
x n+1 =(ax n +c)mod m
当c≠0时,正确选择的参数允许所有种子值等于m的周期。这种情况才会发生,并且仅在以下情况下:
。 –Dobell定理。
对于64位LCG a = 6364136223846793005和C = 1442695040888963407,来自Knuth看起来不错。
请注意,LCG映射为1-1,它将整个[0 ... 2 64 -1]区域映射到本身。如果需要,可以倒置。作为RNG,它具有独特的跳跃能力。
To add to colm.anseo answer, this kind of mapping is also known as Linear congruential generator.
Xn+1 = (aXn+c) mod m
When c ≠ 0, correctly chosen parameters allow a period equal to m, for all seed values. This will occur if and only if:
These three requirements are referred to as the Hull–Dobell Theorem.
For 64bit LCG a=6364136223846793005 and c=1442695040888963407 from Knuth looks good.
Note, that LCG mapping is 1-to-1, it maps whole [0...264-1] region to itself. You could invert it if you want. And as RNG it has distinctive ability for jump-ahead.