需要解决流式算法的问题,我们有两种思路,一种是乘法近似,一种是加法近似
![[Pasted image 20250614130820.png]]
接下来介绍第一个问题

# Majority 问题

这个问题需要解决的是,在一个流式输入的过程中,是否有哪个元素的出现次数 > m/2
或者是一个变量,比如 1/k 的 m
为了解决这个问题,我们可以用以下算法

  1. Misra-Gries algorithm
    这个算法的定义是,由于我们只有很小的一个空间用来存放数据,所以我们可以使用一种算法,例如我们只有 1/ε 的空间,所以,我们在每个元素流过时执行以下的操作:
    1. 如果这个元素还未存在,且我们的空间还没满,那么将他加入空间并记录次数 + 1
    2. 如果这个元素已经存在了,那么对他的计数 + 1
    3. 如果这个元素没有存在且空间已经满了,那么对所有的现存元素 - 1
    复杂度
    ![[Pasted image 20250614133805.png]]
    ![[Pasted image 20250614133817.png]]

# Approximate Counting 近似计数问题

现在,我们想要用更小的空间来记录数据,logm 还是太大了,所以,我们不需要那么准确,只需要近似等于即可,

Morris Counter 原始算法(近似计数)
他通过限制数量增长的趋势来控制空间,![[Pasted image 20250614135235.png]]
由于概率是 1/2 的 x 次 - 1,所以他需要的空间就从原本的 n 变成了 logn,而需要存储的空间的 bits 就变成了 log log n,大大降低了存储的空间
这里,我们用到了条件期望
![[Pasted image 20250614135407.png]]
通过对比
![[Pasted image 20250614140718.png]]![[Pasted image 20250614143131.png]]
方差较大,这不是我们想要的,所以,我们有一些别的方法来阻止这个问题
![[Pasted image 20250614143230.png]]
这里讲一下中位数版本的
![[Pasted image 20250614143615.png]]
但是我们真的需要这么多方法来确定这个值吗?
只有在确定需要将概率放大到什么值得时候再使用

但是朴素得 Morris Counter 仍然有一些问题,他的增长太快了,可能会有一些误差,所以我们可以替代原有的这个比率,重新选择一个比率来缓解这个问题

![[Pasted image 20250614144112.png]]

# 第三个问题 Distinct Elements(不同元素计数)

这个问题就是,有多少个不同的元素在这个数据流过去的过程中。
第一种算法: Tidemark (AMS) algorithm
这个方法很聪明,由于我们无法存下所有的元素,所以,我们可以使用一个哈希函数,来将元素映射到一个二进制表中。由于使用了二进制表来存储,最后获得的数学期望越大,说明元素越多。而由于可能存在一些极端值影响,所以我们可以使用多个哈希函数取中位数或者平均值。
![[Pasted image 20250614144910.png]]

优化:BJKST algorithm
与前面类似,我们也可以使用哈希函数,思路都完全相同,只是在这边我们只保留前 k 个元素
![[Pasted image 20250614145410.png]]