簡體   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