内射配对功能

时间:2012-03-04 20:23:47

标签: algorithm math mapping integer

我正在寻找配对函数f:ZxZ - > Z,具有以下特点:

  • 它不需要是可逆的。我只需要它是注入的(不同的对映射到不同的整数),我从来不需要计算这对。
  • 它是通过Z(有符号整数)
  • 定义的
  • 可高效计算

目前,我正在使用f(x,y)= x +(max(x)-min(x)+1)* y

它有效,我只是想知道是否可以有更高效地使用结果空间的另一个函数,考虑到:

  • x,y是最多64位的有符号整数
  • f(x,y)是一个整数,最多64位
  • len(f(x,y))< = 64位很容易计算

我知道这意味着我无法映射所有x,y组合而不会导致溢出。 我很高兴能够确定转换是否适合64位。 因此,理想的映射函数将尽可能高效地使用可用的64位。

任何提示?

2 个答案:

答案 0 :(得分:1)

CRC polynomials计算速度快,扩散速度快。我相信你会得到你最喜欢的语言库。 Concat都是128位的整数并计算CRC。

请记住,在没有冲突的情况下,不能以64位映射128位。

答案 1 :(得分:0)

要将两个64位整数编码为唯一的单个数字,可能会有2^64 * (2^64 -1)个输入组合,因此,显而易见的Pigeonhole Principle,我们需要一个至少为2^64 * (2^64 -1)的大小输出,等于2^128 - 2^64,换句话说,你需要一个128位的容量来保存所有可能的输出。


  

我知道所有价值观都不存在。但这取决于值,而不是数据类型。例如。 f(4,5)仍然可以完成,即使4和5存储为64位整数。根据所使用的函数,很容易检查溢出(在这种情况下我不会使用映射)。

你知道的。也就是说,正如您所说,您可以为64位输入设置最大值上限。然后输出可以是64位有符号或无符号整数。

正在签署的输出,C#中的实现:

public static long GetHashCode(long a, long b)
{
    if (a < int.MinValue || a > int.MaxValue || b < int.MinValue || b > int.MaxValue)
        throw new ArgumentOutOfRangeException();

    var A = (ulong)(a >= 0 ? 2 * a : -2 * a - 1);
    var B = (ulong)(b >= 0 ? 2 * b : -2 * b - 1);
    var C = (long)((A >= B ? A * A + A + B : A + B * B) / 2);
    return a < 0 && b < 0 || a >= 0 && b >= 0 ? C : -C - 1;
}

输出是无符号的,是C#中的一个实现:

public static ulong GetHashCode(long a, long b)
{
    if (a < int.MinValue || a > int.MaxValue || b < int.MinValue || b > int.MaxValue)
        throw new ArgumentOutOfRangeException();

    var A = (ulong)(a >= 0 ? 2 * a : -2 * a - 1);
    var B = (ulong)(b >= 0 ? 2 * b : -2 * b - 1);
    return A >= B ? A * A + A + B : A + B * B;
}

由于计算量较少,无符号实现会稍快一些。唯一配对的下限和上限是int.MaxValue( - 2147483648)和int.MaxValue(2147483647)。原始函数是taken from here。链接中提到的优雅配对功能是最节省空间的,因为它映射到可用空间中的每个点。有关类似方法的更多信息,请参阅Mapping two integers to one, in a unique and deterministic way