繁体   English   中英

我应该如何为给定的人口优化哈希表?

[英]How should I go about optimizing a hash table for a given population?

假设我有一组键值对,我计划存储在哈希表中。 人口是固定的,永远不会改变。 我可以使用哪些优化来尽可能快地创建哈希表? 我应该集中精力进行哪些优化? 这假设我有很多空间。 将有合理数量的对(例如不超过100,000)。

编辑:我想优化查找。 我不在乎构建需要多长时间。

我会确保你的密钥的哈希值为唯一值。 这将确保每次查找都是恒定的时间,因此尽可能快。

由于您的密钥永远不会超过100,000,因此完全可以拥有100,000个哈希值。

此外,请确保使用带有int的构造函数指定初始容量(将其设置为100,000),并使用float来设置加载因子。 (使用1 )此外,这样做需要您的密钥具有完美的哈希函数。 但是,这将以最少的内存量导​​致最快的查找。

通常,为了优化哈希表,您希望在确定哈希值时最大限度地减少冲突,因此您的存储桶不会包含多个项目,并且哈希搜索将立即返回。

大多数情况下,这意味着您应该在问题空间上测量哈希函数的输出。 所以我想我会建议调查一下

确保没有碰撞。 如果没有碰撞,则保证O(1)持续查找时间。 然后,下一个优化将是查找。

使用分析器逐个优化。 没有它,很难。

如果可以制作一个大型哈希表,使其根本没有冲突,那么它将是理想的。 由于您的插入和查找将在恒定时间内完成。

但是如果这是不可能的,请尝试选择一个哈希函数,以便您的密钥在哈希表中均匀分布。

完美的散列算法可以解决问题,但可能无法扩展到100k对象。 我找到了一个Java MPH包 ,但还没有尝试过。

如果在编译时已知群体,则最佳解决方案是使用最小完美散列函数(MPH)。 关于此主题的Wikipedia页面链接到几个可以生成这些的Java工具。

必须在密钥classhashCode方法中完成优化。 要记住的是实现此方法以避免冲突。

获得完美的哈希算法,为100K对象提供完全独特的值可能几乎是不可能的。 考虑一下生日悖论。 人们出生的日期可以被认为是一种完美的哈希算法,如果你有超过23个人,你很可能会发生碰撞,那就是365个日期的表格。

那么你需要多大的表才能在100K中没有碰撞?

如果您的键是字符串,那么您的最佳策略是树,而不是二进制,而是每个字符的n分支。 如果键是小写的,那么只要你创建一个分支时你只需要26就更容易了。

我们从26键开始。 按照第一个字符,说ff可能有一个与之关联的值。 它可能有子树。 查找o的子树。 这导致更多的子树然后查找下一个o。 (你知道那是领先的地方!)。 如果没有与之关联的值,或者我们在途中遇到了一个空子树,我们就知道找不到该值。

您可以优化树上您达到唯一性的空间。 假设你有一个关键的1月,它在第4个角色变得独一无二。 此时,您分配值,您还存储与其关联的实际字符串。 在我们的例子中,可能有一个与foo相关的值,但它与之相关的关键可能是食物,而不是foo。

我认为谷歌搜索引擎使用的技术类似于此。

关键问题是你的关键是什么。 (没有双关语。)正如其他人所指出的那样,目标是最大限度地减少哈希冲突的数量。 如果您可以将散列冲突的数量设置为零,即您的散列函数为实际传递给它的每个键生成唯一值,那么您将获得完美的散列。

请注意,在Java中,哈希函数实际上有两个步骤:首先,密钥通过其类的hashCode函数运行。 然后我们通过将此值作为哈希表的大小的模数来计算哈希表中的索引值。

我认为讨论完美哈希函数的人往往会忘记第二步。 即使您编写了一个hashCode函数,该函数为传递给它的每个键生成一个唯一值,但如果以哈希表大小为模的这个值不唯一,您仍然可能得到一个绝对可怕的哈希值。 例如,假设你有100个密钥,你的hashCode函数返回值1,1001,2001,3001,4001,5001,... 99001.如果你的哈希表有100,000个插槽,这将是一个完美的哈希。 每个密钥都有自己的插槽。 但如果它有1000个插槽,它们都会散列到相同的插槽。 这将是最糟糕的哈希。

所以考虑构建一个好的哈希函数。 以极端的情况为例。 假设您的密钥是日期。 您知道日期将在同一年的1月份。 然后使用当月的日期作为哈希值应该与它将获得的一样好:所有内容都将散列为小范围内的唯一整数。 另一方面,如果你的日期是本月的第一个多年和几个月,那么每月的日期将是一个糟糕的哈希值,因为每个实际的密钥都会映射到“1”。

我的观点是,如果您真的想要优化哈希值,您需要知道数据的性质。 您将获得的实际值范围是多少?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM