2019寒假训练营寒假做业(三) 对Sketch——CM-Sketch的理解(理论题部分)


实验题部分


基本题


一、简述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的算法过程

备注: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算法和总体架构修改起来并不简单,可是看懂以后才会好不少。并且貌似偶尔会致使堆损坏?这个问题很不解,可是免不了对堆的维护,但它不会中断程序(以下截图,其中一次堆损坏)。
相关文章
相关标签/搜索