2012-03-04 28 views
3

我正在寻找一个配对函数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位。

任何提示?

+0

哈罗德,正如我所说,我知道它不可能存在所有的价值。但这取决于值,而不是数据类型。例如。 f(4,5)仍然可以完成,即使当4和5存储为64位整数时也是如此。根据所使用的函数来检查溢出是很容易的(在这种情况下,我不会使用映射)。我只是想知道是否放松的可逆性可以带来空间使用方面的任何好处 – cornuz 2012-03-04 20:36:37

+0

你知道有'(2 ^(2^128))^ 64'不同的功能满足您的要求吗?附:没有组成一个大数字 - 这是从128位到64位的功能数量。 – amit 2012-03-04 20:52:51

+0

然后,只要它不溢出,那么'((x + y)*(x + y)+ x - y)/ 2'怎么样。 – harold 2012-03-04 21:10:33

回答

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

1

CRC polynomials计算速度快,扩散性好。我相信你会得到你最喜欢的语言的图书馆。以128位对两个整数进行Concat并计算CRC。

请记住,无法映射64位中的128位而没有发生冲突。

+0

感谢您的提示。碰撞是不可接受的,我需要检测是否有任何给定的输入值会溢出64位,如果是这样,采取不同的行动。 – cornuz 2012-03-06 15:05:25

+0

什么是输入分布?哪些输入值最适合? – 2012-03-06 16:18:18

+0

我所瞄准的算法的动机是,在信息检索应用中最有用,'(x,y)'通常是'(term,doc)'。两者都是无符号数字标识符,术语中有[Zipfian](http://en.wikipedia.org/wiki/Zipf's_law)分布(很少有词条非常频繁)。但是,我不能真正假设任何分布或无符号数字,因为这意味着成为一般关系处理的一部分。 – cornuz 2012-03-06 16:45:09