實驗題部分
基本題
一、簡述sketch:
- 對於數據流中大量的元素要統計其特徵(出現頻率,數據流大小),對數據流屢次使用哈希函數將事件映射到頻率,在合理的誤差內估計其大小,並顯著減小內存佔用,是一種可靠性較高的機率統計數據結構。
二、Count-min Sketch:
- 預備知識1:經過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度,這個映射函數叫作哈希函數或散列函數。主要操做是對數據進行加法、乘法和移位運算。
- 預備知識2:Hash函數的基本特性:
- 1.通過hash後可以獲得相應輸入的散列值。若是兩個散列值是不相同的(根據同一函數),那麼這兩個散列值的原始輸入也是不相同的;
- 2.散列函數的輸入和輸出不是一一對應的,若是兩個散列值相同,兩個輸入值極可能是相同的但不絕對確定必定相等(可能出現哈希碰撞)。
算法過程:數組
使用d個hash函數,每一個hash函數的取值範圍都在[1,w]內,從而能夠組成一個d * w的二維數組(hash table),該二維數組的長度大小固定。對於每一個二元組(k, v),表明元素k須要更新v次,則分別使用d個hash函數對k進行hash操做,獲得d個mapped counters,而後對它們所有增長v(即須要更新的數據)。(count含義)
當須要查詢某個元素的頻率估計值時,也是先根據hash函數獲得mapped counters,而後取其中的最小值便可,由於最小表明了衝突次數最少,相對最精確。(min含義)
-- 摘引自他人博客《Sketch調研[https://blog.csdn.net/u012332103/article/details/79702495]》,有刪改
數據結構
開放題部分
理論部分
一、解釋爲何 sketch 能夠省空間
Count-min-sketch在處理數據時引入了hash函數,可以把一個大範圍映射到一個固定大小的小範圍(簡單來講,就是將任意長度的二進制值映射爲固定長度的、大小惟一的較小二進制值),每每是爲了節省空間、加快存取,使得數據容易保存。該函數是CM-Sketch可以極大節省空間的一個關鍵。
可是相應的代價是:因爲上述hash函數的特性,多個key的散列值可能相同(哈希碰撞),從而致使探測計數器的估計值偏大。
所以爲了減小哈希碰撞的機率:架構
- 一、可以使用多個哈希函數;
- 二、可以使用一個相對於數據足夠大的素數進行hash操做;(例如2的32次方附近)
- 三、提升d和w的大小(越大精度越高),可是相應的在估計中使用空間也會增大。
二、用流程圖描述Count-min sketch的算法過程
![](http://static.javashuo.com/static/loading.gif)
備註:app
- 一、Ai->Bi,就是IP和對應的請求大小;
- 二、update(Ai, Bi)包括了接下來的hash操做,是給Ai的原對應值上再添加Bi的值;
- 三、estimate(Ai),獲得各個探測計數器中的最小值並返回最小值;
- 四、邊輸入邊算,這種流程圖的方法,可能會屢次重複輸出已經輸出過的Ai->Bi。
三、拿它和你改進後方法進行對比,分析優劣
優勢:
- 一、只需利用相對獨立的hash函數就可以解決內存佔用問題,對龐大的數據流能夠實時處理,直接經過hash函數也能夠直接找到的對應的value,無需遍歷,下降時間空間複雜度。
- 二、不須要精確估計數據包大小,適用於範圍性問題,雖然結果可能偏大,可是理論上能夠控制在合理偏差範圍內。
- 三、拓展性強,因爲不容易受數據長度大小的影響,加上鍵-值對應,在此基礎上能夠發展成統計其餘數據特徵的數據結構。本人的原始代碼只能處理一種定長格式的數據的其中一種特徵。
劣勢:
- 一、CM-Sketch的實現難度明顯高於本人的代碼,須要更深的知識掌握(例如兩兩獨立的hash函數要如何建立),若是要求更高的精度,代碼將會越複雜。
- 二、對於低頻的數據估計值偏差會偏大,可能不適用於須要太過精確判斷的問題中。
四、吐槽Count-min sketch
- 一、外國人寫個代碼還好基本對函數和基本單元進行了封裝,否則真的看不懂;
- 二、低頻數據的準確度有時差到驚人,甚至有內存分配出錯的狀態發生(或許是我改動完之後的問題)(二更:不是個人問題, 代碼自身的hash算法其中的大數運算致使的,已修改);
- 三、hash算法和總體架構修改起來並不簡單,可是看懂以後纔會好不少。並且貌似偶爾會致使堆損壞?這個問題很不解,可是免不了對堆的維護,但它不會中斷程序(以下截圖,其中一次堆損壞)。
![](http://static.javashuo.com/static/loading.gif)