Hash 将整数和整数范围映射(或散列)到索引中的有效函数

Hash 将整数和整数范围映射(或散列)到索引中的有效函数,hash,map,integer,range,Hash,Map,Integer,Range,我们正在寻找计算上最简单的函数,它可以通过分布广泛的整数和整数范围的高频输入流来确定函数的索引查找 如果哈希/映射函数选择本身根据特定的整数和范围要求而变化,并且与选择此算法的代码部分相关联的性能并不重要,则可以。在大多数情况下,感兴趣的整数/范围的数量很小(0到几千)。性能关键部分是处理传入流和选择适当的函数 作为一个简单的例子,请考虑下面的伪代码: switch (highFrequencyIntegerStream) case(2) : func1(); case

我们正在寻找计算上最简单的函数,它可以通过分布广泛的整数和整数范围的高频输入流来确定函数的索引查找

如果哈希/映射函数选择本身根据特定的整数和范围要求而变化,并且与选择此算法的代码部分相关联的性能并不重要,则可以。在大多数情况下,感兴趣的整数/范围的数量很小(0到几千)。性能关键部分是处理传入流和选择适当的函数

作为一个简单的例子,请考虑下面的伪代码:

switch (highFrequencyIntegerStream)
    case(2)      : func1();
    case(3)      : func2();
    case(8)      : func3();
    case(33-122) : func4();

    ...

    case(10,000) : func40();
在一个典型的例子中,上面显示的“案例”只有几千个,其中可能包括一个完整的32位整数值和范围。(在33-122以上的伪代码中表示33到122之间的所有整数。)将有大量对象包含这些“switch语句”

(请注意,实际的实现将不包括switch语句。它将是一个跳转表(它是一个函数指针数组),或者可能是命令和观察者模式的组合,等等。实现细节与请求无关,但用于帮助可视化。)

许多对象将包含“switch语句”,其中只有几个条目。感兴趣的值可能会发生实时更改,但与管理这些更改相关的性能并不重要。哈希/映射算法可以在每次更新时根据特定的整数和感兴趣的范围(对于给定时间的给定对象)缓慢地重新生成

我们在互联网上搜索过Bloom过滤器、Wikipedia“hash function”页面上列出的各种hash函数以及其他地方、相当多的堆栈溢出问题、抽象代数(主要是Galois理论,其计算简单的操作数吸引人)、各种密码等。,但目前还没有找到一个解决方案,似乎是针对这个问题。(我们甚至找不到将这些类型的范围视为输入的哈希或映射函数,更不用说高效的了。也许我们找不到正确的位置或使用了正确的方言。)

当前的计划是创建一个自定义算法,对感兴趣的整数和范围列表进行预处理(对于给定时间的给定对象),寻找可以应用于输入流以帮助描绘范围的移位和掩码。请注意,大多数传入的整数都是无趣的,对于尽可能大比例的流,快速做出决定至关重要(这就是为什么Bloom过滤器一开始看起来很有趣的原因)(在我们开始思考它们的实现需要比其他解决方案更高的计算复杂性之前)

因为第一个决定非常重要,我们也在考虑使用多个表,其中第一个表是反向掩码(用于选择无趣数字的掩码),以便轻松查找未包含在给定“switch语句”中的大范围数据,然后是扩展较小范围的后续表格。我们认为,对于大多数输入流的情况,这将比范围边界上的二进制搜索产生更快的结果


请注意,输入流可以被认为是随机分布的。

有一个非常广泛的最小完美散列函数理论,我认为可以满足您的要求。最小完美散列的思想是,一组不同的输入以1-1的方式映射到一组密集的整数。在您的例子中,是一组N 32位integer和ranges将分别映射到一个大小为N的小倍数的唯一整数。Gnu有一个名为
gperf
的完美哈希函数生成器,用于字符串,但可能对您的数据有效。我一定会尝试一下。只需添加一个长度字节,使整数为5字节字符串,范围为9字节。Th这里有一些正式的参考文献。在ACM和IEEE文献中进行文献搜索肯定会找到更多

我只是偶然发现了以前从未见过的东西

添加

我现在看到,您正在尝试将范围中的所有整数映射到同一个函数值。正如我在评论中所说的,这与哈希不太兼容,因为哈希函数故意尝试“擦除”位位置上的大小信息,以便具有类似大小的值不太可能映射到同一个哈希值

因此,我认为您不会比最佳二叉搜索树做得更好,或者等效地说,不会比生成“if-else”语句的最佳“树”的代码生成器做得更好

如果我们想要构造一个你想要的类型的函数,我们可以尝试使用实数,其中单个域值映射到co域中的连续整数,范围映射到co域中的单位间隔。因此,一个简单的floor操作将为你提供你要找的跳转表索引

在您提供的示例中,您将具有以下映射:

2 -> 0.0
3 -> 1.0
8 -> 2.0
33 -> 3.0
122 -> 3.99999
...
10000 -> 42.0 (for example)
诀窍是找到一个对这些点进行插值的单调递增多项式。这当然是可能的,但对于数千个点,我确信最终的计算速度会比最佳搜索慢得多。

也许我们的方法能帮上一点忙。你还会发现一个哈希库(hashlib.zip)基于Bob Jenkins以智能方式处理整数的工作。
我建议在散列机制拒绝单个案例后处理更大的范围。

诱使gperf认为我们的数据是一个字符串是一个有趣的想法。我们还在研究CMPH