在实际应用中,我们经常碰到这种情况,即要统计某个对象或者事件独立出现的次数。对于较小的数据量,这很容易解决,我们可以首先在内存中对序列进行排序,然后扫描有序序列统计独立元素数目。其中排序时间复杂度为O(n*log(n)),扫描时间复杂度为O(n),所以总的时间复杂度为O(n*log(n))。当内存非常充裕时,我们还可以考虑使用哈希,将时间复杂度降到O(n)。尤其是当元素只能取有限范围的整数值时,我们还可以使用BitMap节约内存。但是在处理数据流序列时,比如,google的独立访问IP统计,由于序列非常长,元素取值范围可能比较广,单个元素占用内存可能比较多,导致内存中无法容纳整个序列,甚至无法容纳整个独立元素集合。此时,不论是基于排序还是基于哈希的方法都不具备可行性。

Flajolet-Martin(FM)算法能够较好地解决估算数据流序列中独立元素数目的问题。

假设我们有1万个int型数字(可重复的),我们想找出这个数字集合中不重复的数字的个数。怎么办呢?很简单,将这1万个数字读进内存,存放到hashset中,那么hashset的size就是不重复数字的个数。接下来,问题变得更加的复杂,有100亿个数字,怎么办? 全部读取到内存中可能会有问题,如果这其中有1亿个不重复的数字,那么至少需要内存 100M * sizeof(int),内存也许不够。 FM算法就是为了解决这个问题。假设n个object,其中有m个唯一的,那么FM算法只需要log(m)的内存占用(实际操作中会是k*log(m)),以及O(n)的运算时间。当然,FM的问题是,它的结果只是一个估计值,不是精确结果。

具体思路如下:

假定哈希函数H(e)能够把元素e映射到[0, 2^m-1]区间上;再假定函数TailZero(x)能够计算正整数x的二进制表示中末尾连续的0的个数,譬如TailZero(2) = TailZero(0010) = 1,TailZero(8) = TailZero(1000) = 3,TailZero(10) = TailZero(1010) = 1;我们对每个元素e计算TailZero(H(e)),并求出最大的TailZero(H(e))记为Max,那么对于独立元素数目的估计为2^Max。

这种估算的理论依据证明参见  原文

举例来说,给定序列{e1, e2, e3, e2},独立元素数目N = 3。假设给定哈希函数H(e),有:

H(e1) = 2 = 0010,TailZero(H(e1)) = 1

H(e2) = 8 = 1000,TailZero(H(e2)) = 3

H(e3) = 10 = 1010,TailZero(H(e3)) = 1

第1步,将Max初始化为0;

第2步,对于序列中第1项e1,计算TailZero(H(e1)) = 1 > Max,更新Max = 1;

第3步,对于序列中第2项e2,计算TailZero(H(e2)) = 3 > Max,更新Max = 3;

第4步,对于序列中第3项e3,计算TailZero(H(e3)) = 1 ≤ Max,不更新Max;

第5步,对于序列中第4项e2,计算TailZero(H(e2)) = 3 ≤ Max,不更新Max;

第6步,估计独立元素数目为N’ = 2^Max = 2^3 = 8。

在这个简单例子中,实际值N = 3,估计值N’ = 8,误差比较大。此外,估计值只能取2的乘方,精度不够高。

在实际应用中,为了减小误差,提高精度,我们通常采用一系列的哈希函数H1(e), H2(e), H3(e)……,计算一系列的Max值Max1, Max2, Max3……,从而估算一系列的估计值2^Max1, 2^Max2, 2^Max3……,最后进行综合得到最终的估计值。具体做法是:首先设计A*B个互不相同的哈希函数,分成A组,每组B个哈希函数;然后利用每组中的B个哈希函数计算出B个估计值;接着求出B个估计值的算术平均数为该组的估计值;最后选取各组的估计值的中位数作为最终的估计值。

举例来说,对于序列S,使用3*4 = 12个互不相同的哈希函数H(e),分成3组,每组4个哈希函数,使用12个H(e)估算出12个估计值:

第1组的4个估计值为<2, 2, 4, 4>,算术平均值为(2 + 2 + 4 + 4) / 4 = 3;

第2组的4个估计值为<8, 2, 2, 2>,算术平均值为(8 + 2 + 2 + 2) / 4 = 3.5;

第3组的4个估计值为<2, 8, 8, 2>,算术平均值为(2 + 8 + 8 + 2) / 4 = 5;

3个组的估计值分别为<3, 3.5, 5>,中位数为3.5;

因此3.5 ≈ 4即为最终的估计值。

分析FM算法的时间复杂度。假定序列长度为N,哈希函数H(e)的数目为K。初始化K个Max值的时间复杂度为O(K);对N个元素e使用K个哈希函数H(e)计算TailZero(H(e))并更新Max值的时间复杂度为O(N*K);综合K个Max值给出最终估计值的时间复杂度为O(K)。因此总的时间复杂度为O(N*K)。

分析FM算法的空间复杂度。该算法需要存储K个Max值,而每个元素e在进行相关计算后就可以丢掉。因此总的空间复杂度为O(K)。

综上所述,FM算法的时间复杂度为O(N*K),空间复杂度为O(K)。一般来说K比较小,可以认为FM算法的时间复杂度为O(N),空间复杂度为O(1)。

FM算法可以用于估算独立Cookie数目,独立URL数目,独立邮箱地址数目等等。

(转)预估大数据量下UV的方法的更多相关文章

  1. 大数据量下MySQL插入方法的性能比较

    不管是日常业务数据处理中,还是数据库的导入导出,都可能遇到需要处理大量数据的插入.插入的方式和数据库引擎都会对插入速度造成影响,这篇文章旨在从理论和实践上对各种方法进行分析和比较,方便以后应用中插入方 ...

  2. c#中@标志的作用 C#通过序列化实现深表复制 细说并发编程-TPL 大数据量下DataTable To List效率对比 【转载】C#工具类:实现文件操作File的工具类 异步多线程 Async .net 多线程 Thread ThreadPool Task .Net 反射学习

    c#中@标志的作用   参考微软官方文档-特殊字符@,地址 https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/toke ...

  3. 大数据量下的SQL Server数据库自身优化

    原文: http://www.d1net.com/bigdata/news/284983.html 1.1:增加次数据文件 从SQL SERVER 2005开始,数据库不默认生成NDF数据文件,一般情 ...

  4. mysql大数据量下的分页

    mysql大数据量使用limit分页,随着页码的增大,查询效率越低下. 测试实验 1.   直接用limit start, count分页语句, 也是我程序中用的方法: select * from p ...

  5. 大数据量下,分页的解决办法,bubuko.com分享,快乐人生

    大数据量,比如10万以上的数据,数据库在5G以上,单表5G以上等.大数据分页时需要考虑的问题更多. 比如信息表,单表数据100W以上. 分页如果在1秒以上,在页面上的体验将是很糟糕的. 优化思路: 1 ...

  6. mysql百万级别重排主键id(网上的删除重建id在大数据量下会出错)

    网上教程: 先删除旧的主键 再新建主键 :数据量少时没问题,不会出现主键自增空缺间隔的情况(如:1,2,3,5):但是大数据量时会出现如上所述问题(可能是内部mysql多进程或多线程同时操作引起问题) ...

  7. boost的asio接收单路大数据量udp包的方法

    开发windows客户端接收RTP视频流,当h264视频达到1080P 60fps的时候,按包来调用recvfrom的函数压力比较大,存在丢包的问题,windows的完成端口的性能效果当然可以解决这个 ...

  8. 大数据量下的集合过滤—Bloom Filter

    算法背景 如果想判断一个元素是不是在一个集合里,一般想到的是将集合中所有元素保存起来,然后通过比较确定.链表.树.散列表(又叫哈希表,Hash table)等等数据结构都是这种思路,存储位置要么是磁盘 ...

  9. (转)大数据量下的SQL Server数据库优化

     在SQL Server中,默认MDF文件初始大小为5MB,自增为1MB,不限增长,LDF初始为1MB,增长为10%,限制文件增长到一定的数目:一般设计中,使用SQL自带的设计即可,但是大型数据库设计 ...

随机推荐

  1. hyper-v安装ubuntu18的全过程+踩过的坑(win10家庭版)

    一.背景介绍(作者的闲言闲语,可跳过) 最近新购入小米笔记本pro15增强版,想在笔记本上装ubuntu18的系统. 最开始尝试了双系统的方法,但是安装完之后不能wifi上网,显卡MX250不能适配, ...

  2. IDEA下配置JavaWeb项目

    前提 已安装IDEA专业版 已安装Tomcat 已安装JDK 创建JavaWeb项目 File --> New --> Project... 设置工程名字: 创建完成后工程结构如下: 设置 ...

  3. VLAN和子网之间的区别与联系

    通常来说,子网和VLAN的相似之处在于它们都处理网络的一部分的分段或分区.但是,VLAN是数据链路层(OSI L2)的构造,而子网是网络层(OSI L3)的IP构造,它们解决网络上的不同问题.尽管在V ...

  4. [CF1311A] Add Odd or Subtract Even

    Solution a<b, delta=odd, ans=1 a<b, delta=even, ans=2 a=b ans=0 a>b, delta=odd, ans=2 a> ...

  5. 极具性价比优势的工业控制以及物联网解决方案-米尔MYD-C8MMX开发板测评

    今天要进行测评的板子是来自米尔电子的MYD-C8MMX开发板.MYD-C8MMX开发板是米尔电子基于恩智浦,i.MX 8M Mini系列嵌入式应用处理器设计的开发套件,具有超强性能.工业级应用.10年 ...

  6. mac电脑怎么投屏?教你选择适合自己的Mac投屏软件

    mac上有什么好的投屏软件嘛?苹果手机ios投屏到mac用哪款投屏软件,mac投屏ipad该用哪款软件怎么操作,macdown小编给大家介绍的这几款Mac投屏软件,各有各的特色,总有一款适合你投屏. ...

  7. Linux系统的启动原理

    Linux系统的启动原理 RHEL的启动原理BIOS自检-MBR-启动GRUB-加载内核-systemd的init进程 systemd的初始化进程加载需要的服务,挂载文件系统/etc/fstabsys ...

  8. python全栈学习 day03

    换行符: \n 制表符: \t 字符串截取:顾头不顾尾 s[首:尾:步长] 首--->尾走向 和 步长方向一致 s[0:4:2] s[4:0:-2] a = "qwertyui&quo ...

  9. 【卸载Pycharm】

    一.卸载软件及安装目录 1. 控制面板中卸载 二.删除注册表信息 1. 备份注册表信息 2. 删除注册表信息

  10. 接口测试(http 和 rpc)

    接口测试主要分HTTP和RPC两类,RPC类型里面以Dubbo较为知名.互联网微服务架构,两种接口都需要做接口测试的,不管是业务测试还是回归测试: Dubbo:Java栈的互联网公司比如阿里.美团.5 ...