如何将一个范围内的数字映射到同一范围内的另一个数字而不会发生冲突?



实际上,我正在寻找的是一个输出到预定义范围的函数f(x)。调用f(f(x))也应该是有效的。该函数应该是循环的,因此调用f(f(...(x)))调用次数等于范围大小时,应提供原始数字,并且f(x)不应与时间相关,并且始终提供相同的输出。

虽然我可以看到,获取所有可能值的列表并对其进行洗牌会给我一些接近我想要的东西,但我更喜欢它,如果我可以简单地一次将值插入一个函数中,这样我就不必一次计算整个范围。

我已经研究了最小完美哈希函数,但找不到不使用外部库的函数。我可以使用它们,但宁愿不这样做。

如果需要实际范围来帮助回答我的问题,我认为它不需要大于[0, 2^24-1],但起始值和结束值并不重要。

你可能想看看线性同余生成器。您应该查看全周期生成器(例如,m=224(,这意味着参数应满足赫尔-多贝尔定理。

调用 f(

f(x(( 也应该是有效的。

应该工作

通话次数等于范围的大小应该给你原来的号码

是的,对于参数满足赫尔-多贝尔定理的LCG,您将获得一次完整的周期,并且"m + 1"调用将使您回到起点。 这种LCG的周期正好等于m

不应与时间相关,并且将始终提供相同的输出

LCG 是 O(1( 算法,它是 100% 可重现的

LCG 也是可逆的,通过扩展的欧几里得算法,查看可逆伪随机序列生成器了解详细信息

最小的完美哈希函数是矫枉过正的,你所要求的只是一个函数 f,即,

  1. 双射,以及
  2. "周期性"(即fN=f(

为了使排列以这种方式具有循环性,其顺序必须除以N(或者是N,但在某种程度上只是除以N的特例(。这反过来意味着子周期阶数的LCM必须除以N。一种方法是只有一个 N 阶的"子"循环。对于两个 N 的幂,也很容易有很多其他一些二次幂阶的小周期。一般置换不一定满足循环要求,当然它们是双射的,但子周期阶的LCM可能超过N。

在下文中,我将隐含所有归约模 N。在不损失一般性的情况下,我将假设范围从 0 开始并上升到 N-1,其中 N 是范围的大小。

对于一般 N 我唯一能立即想到的是f(x) = x + c在哪里gcd(c, N) == 1.GCD 条件确保只有一个循环,该循环必须具有 N 阶。

对于 N 的二次方,我有更多的灵感:

  • f(x) = cxc奇怪的地方。双射,因为gcd(c, N) == 1所以c有一个模乘法逆。同样 cN=1,因为 φ(N(=N/2(因为 N 是 2 的幂(,所以 c φ(N(=1(欧拉定理(。
  • f(x) = x XOR cc < N的地方.平凡双射和平凡循环,周期为 2,除以 N。
  • f(x) = clmul(x, c)其中c是奇数,clmul是无进位乘法。双射,因为任何奇数c都有一个无进位乘法逆。具有一些二次幂周期长度(小于 N(,因此它除以 N。我不知道为什么。这是一个奇怪的,但它有不错的特殊情况,例如x ^ (x << k).通过对称,"镜像"版本也可以工作。
    例如x ^ (x >> k).
  • f(x) = x >>> k>>>位旋转。显然是双射的,fN(x( =x >>> Nk,其中Nk mod N = 0,所以它一直旋转回未旋转的位置,而不管k是什么。

最新更新