演算法沒詳細看,有興趣的可以讀原始**: , 不過最頂層的思路get了
首先這個演算法的目的是求一堆元素當中不重複元素的數量,例如, a, b, a, c中不重複的元素只有a, b,c 3個,那麼結果就是3.
在面對巨大資料量時,這個問題的常規解法會變得非常消耗記憶體,即使用計算機儲存的基本單位乙個位元來代表乙個元素,在海量資料時,仍顯得力不從心。
但是仔細想,難道還有比用位元更省空間的嗎?想來是沒有了。
那麼hyperloglog演算法就是一種基於統計學的方法,既然是基於統計學的方法,那麼這種方法就會「有誤差」,只不過通過一些計算可以讓誤差變得更小。
這種統計學方法的思路是什麼呢?網上有各種用拋硬幣來模擬的,我看不用說得那麼複雜,只要一句話就能得到這種方法的頂層思路:
「如果你看見乙個萬中無一的人(即這種人出現的概率為1/10000),那麼你知道這個世界大概率至少有一萬個人」
這是一種見微知著的方法,基於個體樣本的總體反推。
再細化一步,如果我們把所有的元素通過某個hash函式對映成二進位制位(hash函式足夠分散,足夠平均到整個空間),像101011, 011001, 000101這種,然後對任意乙個元素用上面的頂層思路進行反推,可以得到乙個總體不重複樣本數的估算值,例如可以認為直接以1開頭的元素出現的概率是1/2,那麼可以認為總體元素數大概率超過2個,然後出現000101這種元素,前面以3個0開頭,認為這種元素出現的概率是1/8,那麼總體樣本數的估算就認為至少是8個,對所有元素都這麼估一次,取最大值,就可以得到乙個不重複元素數的估計。
當然,以上的說法肯定誤差巨大,並且對hash函式的隨機性要求非常高,所以具體實踐時,還有很多改進細節,例如分組之類的,改進完之後可以做到非常省記憶體,且準確度非常高。
redis有乙個資料結構hyperloglog就是用這種方法實現不重複元素數統計的,大家有興趣可以自己去看看(參考這裡:
細節我就懶得看了,不想花時間去深入研究這個演算法了,就看個思路。
另乙個好的中文帖子介紹如下:
再談基數估計之HyperLogLog演算法
在很久 好像也沒多久,4個月 之前,我曾經寫了一篇和主業無關的有點意思的小文章 基數估計探秘 linear counting與flajolet martin演算法 但是這篇文章講的兩個演算法都已經老掉牙了,實際應用最廣泛的基數估計演算法是hyperloglog hll 演算法。最近筆者基於flink...
基數計數 HyperLogLog
假設元素個數為m,去重後個數為n 時間複雜為o m2 空間複雜度隨元素個數線性增長。資料量一大就崩了。將資料插入到b 樹中達到去重目的,然後順序訪問葉節點鏈從而得到n值。時間複雜的為o lgm n 記憶體亦隨元素個數線性增長。資料量一大就崩了。用位陣列來表示各元素是否出現,每個元素對應一位,所需的總...
基數估算HyperLogLog
hyperloglog 可以接受多個元素作為輸入,並給出輸入元素的基數估算值 估算值 演算法給出的基數並不是精確的,可能會比實際稍微多一些或者稍微少一些,但會控制在合理的範圍之內。hyperloglog 的優點是,即使輸入元素的數量或者體積非常非常大,計算基數所需的空間總是固定的 並且是很小的。在 ...