您的位置:首页 > 大数据

大数据算法课程笔记1:寻找中值算法之随机选取,中值的中值,One Pass算法

2017-10-01 21:08 465 查看
大数据算法的课程笔记,包括四种中值搜索算法。包括最简单的先搜索后检索,平均算法复杂度为O(N)的简单随机选取算法,确定性的中值的中值算法,大概率返回中值的one pass算法。

1. 最简单的方法:先排序再返回中值

排序算法是O(NlogN),返回中值是O(1)。

整体算法复杂度是O(NlogN)。

2. 随机选取算法:RANDOM SELECT

算法简单,并且平均和最好的时间复杂度为O(N),最差的时间复杂度是O(N2)。

2.1. 算法

算法的目的是寻找长度为N的序列array的第k个数字。

具体的操作是随机选取一个数字,然后将序列分为比其小和比其大的两个序列,然后递归。

def find_kth_number(array,N,k):
if N < 5:
sort(array)
return array[k]
index = random_pick_from(0...N)
divide the array into array_L and array_R, where
for al in array_L, al <= array[index]
for ar in array_R, ar > array[index]
array_L + array_R + {array[index]} = array
if |array_L| > k
return find_kth_number(array_L,|array_L|,k)
else
return find_kth_number(array_R,|array_R|,k-|array_L|-1)


2.2. 算法复杂性

先给出结论:T(N)=O(N)。注意这个是平均值,即T(N)的期望。接下来采用两种证明方式对其进行证明:

2.2.1. 课上方法:直接通过公式推算

从上面的算法可以得到如下公式:

T(N,k)=O(N)+1N∑i=0kT(N−i−1,k−i−1)+1N∑i=k+1NT(i,k)

设T(N)=maxkT(N,k)=T(N,N/2),则有

T(N)≤O(N)+2N∑i=N2+1NT(i)

假设T(n)≤Cn for all n<N,则有

T(N)≤O(N)+2N∗N2∗C34N≤O(N)+C34N

只要C​足够大,就有T(N)≤CN​。

2.2.2. 网上方法:分情况讨论+好情况出现的概率推论

考虑上诉算法,在不考虑平均值的情况下,有如下公式:

T(N)=O(N)+T(N′)

其中N′的大小,直接决定了公式推导出的结论。

最差情况下,N′=N−1,则有T(N)=O(N2)。

最好情况下,N′≤q∗N,其中12≤q<1且固定,则有T(N)=O(N)。

现在讨论平均情况,首先放宽最好情况的条件为,在Tr步内将N缩减到q∗N,则有

T(N)≤TrO(N)+T(q∗N)

由上可知,T(N)=O(TrN)。

从而将T(N)的平均情况归约到求取Tr的平均情况。

一次将序列缩减到q∗N长度的概率还是蛮大的,为2∗q−1;若此次未成功,则继续尝试;总共尝试次数的期望为E(Tr),且有

E(Tr)≤(2∗q−1)+(2−2q)∗(E(Tr)+1)E(Tr)≤12∗q−1

E(Tr)为常数值,与N无关,所以有T(N)=O(N)

3. 中值的中值算法

注意到2.2.2. 中的讨论,随机选择算法的平均值是O(N),这已经是理论上的最优值了,但是最坏情况仍然是O(N2)。而这个最坏情况是因为每次选取的分界点都是差情况导致的,而中值的中值算法就是通过计算中值的中值,从而使得每次选取的分界点都是好情况,即∃q,N′≤q∗N。

具体的,我们将序列分为N/5组,每组5个数字。对于每一组,都可以很快的计算一个中值出来,这就得到N/5个中值,然后对这些中值求取中值。并以其作为分界点,将序列分为大于分界点和小于分界点两个序列,进行递归。

这样选取分界点的原因在于:保证有3N/10个数字小于分界点,同时也保证有3N/10个数字大于分界点。原因在于分界点为中值的中值,所以至少有N/10组的中值小于分界点,那么每组至少3个数值小于其组内中值从而小于分界点,最终总共有3N/10个数值小于分界点;大于的情况同理。

通过算法可知

T(N)=O(N)+T(N/5)+T(N′)

其中的O(N)用于分组,并求取每组的中值;T(N/5)用于求取中值的中值;T(N′)用于求取递归后的中值。

注意到N2≤N′≤7N10,从而最坏的情况下

T(N)=O(N)+T(N/5)+T(7N/10)

假设T(n)≤Cn for n<N,则有

T(N)≤O(N)+C9N10

从而在C足够大的情况下,有T(N)=O(N)。即在最坏情况下也有O(N)的复杂度。

对上诉公式推导过程稍加推广,有如下公式:

T(N)=∑αT(αN)+O(N)⋀∑αα≤1⇒T(N)=O(N)

进一步讨论每组的大小为5的原因,首先组的大小应该越小越好,这样可以降低O(N)系数的大小。同时必须为奇数,方便求取中值。这样5的竞争对手只有3,考虑分组大小为3的情况,则有最坏情况下T(N)=O(N)+T(N/3)+T(2N/3),推出T(N)=O(NlogN),远差于O(N)。

4. One Pass算法

one pass并不是算法的种类,而是对算法的要求,通常出现在Online或者数据集很大的情况,要求算法只能对数据扫描一遍。

理论上来说,大部分问题都无法通过one pass求解(比如中值问题),但是在基于一定假设的情况下,通过适当的算法设计,可以保证输出大概率是正确的输出。

具体的,在损失性能(性能包括内存占用, CPU占用等等)的情况下保证输出的准确性,这种随机算法通常叫做Las Vegas Algorithms。这种情况下讨论的时间复杂度是对所有随机数的均值,而不对输入做假设。

而在保证性能前提的情况下,以较高的概率输出正确答案的随机算法通常叫做Monte Carlo Algorithms。其中高概率输出正确答案也可以分为输出的答案有较高概率是正确答案,或者输出的答案在正确答案的领域内。

随机选取算法就是一种Las Vegas算法,在对所有随机数取均值的情况下时间复杂度是O(N)。而one pass算法则是Monte Carlo算法,保证性能的前提下,尽可能高概率的输出正确答案。

one pass的性能要求是只能对数据扫描一遍,并且内存不足以容纳所有数据。

为了得出大概率的结论,通常需要对输入进行假设;此处对输入的假设是序列内部的数字是随机分布的,即出现顺序序列的概率很小。

4.1. 算法

假设内存空间大小为|F|,维护两个数字L和H,分别表示丢弃内存空间内部最大值和最小值的次数。

首先将内存空间读满,读取的过程中维护内存空间内数值的最大值和最小值,初始化L=0且H=0。
while 数据没有扫描完
若读入数据大于最大值,则丢弃读入数据,++H
若读入数据小于最小值,则丢弃读入数据,++L
若读入数据位于最大值和最小值之间,则随机丢弃内存空间内的最大值和最小值,选择丢弃的数值的原则是为了平衡L和R的大小


简单来说,每次读取一个数字,选择内存空间内部的最大值或最小值丢弃,选取的原则是丢弃最大值和最小值数目尽可能平衡。

4.2. 算法复杂度

这个算法复杂度很简单了,是O(N)。

4.3. 内存空间的大小,保证高概率返回正确值

讨论最终内存空间内存在中值的概率,也即返回值正确的概率。

根据算法过程,“L对应的丢弃元素数值”<”内存空间F内的数值 “<”H对应的丢弃元素的数值”。并且内存空间内部的最大值只会逐渐减小,最小值只会逐渐增大。

内存空间内存在中值的充要条件是H≤N/2≤N−L,上诉条件等价于|D|=|H−L|<|F|−1。即只有最终H和L的差值小于|F|-1,才返回正确的中值。

那我们就需要讨论D基于|F|的分布,才方便讨论最终−(|F|−1)<D<|F|−1的概率。

这里就要引入random walk了。

random walk的中文名称是随机游走/漫步,和马尔科夫链有着密切的关系。大致上可以想象一幅图,每个节点的有多个可能输出,每个输出对应于一个概率,每一步根据概率移动当前位置到下一节点。简单的马尔科夫链可以看作一个多层全连接图结构的随机漫步,每一层内的节点表示该位置的可能输出,链接权重对应于概率。讨论单一节点移动过程的random walk问题并不常见,对于随机漫步的讨论往往集中于讨论多个节点同时长时间运动后的稳定情况,以及各个节点的可能分布。关于random walk的详细介绍请参考:

http://mathworld.wolfram.com/RandomWalk1-Dimensional.html

http://www.mit.edu/~kardar/teaching/projects/chemotaxis(AndreaSchmidt)/random.htm

这里需要讨论D的分布,而D的变化又是标准的random walk,即运行一次循环体,D增加或者减少1。其中增加1的概率可以表示为(基于均匀分布概率的假设):

p=⎧⎩⎨HH+|F|+LH+|F|H+|F|+Liff. D≥0iff. D<0

进而有使得D减少1的概率为1−p。

可以发现,使得D远离原点的概率永远是小于等于1/2的。我们需要得到−(|F|−1)<D<|F|−1概率的下界,为了方便讨论,假设D增加和减少1的概率处处相等,均为1/2。

设经过N次循环体之后D的值为DN,我们需要设置恰当的|F|,使得−(|F|−1)<DN<|F|−1的概率足够大。这里简单讨论一下DN的性质,详情参考:Random Walk–1-Dimensional

因为DN=∑Ni=1zi,其中zi∈{-1,1}, p(zi=-1)=p(zi=1)=1/2。则有

E(DN)=0E(D2N)=NE(|DN|)=2Nπ−−−−√

引用an introduction to probability theory and its applications书中的结论(Ⅲ.7 Theorem 3):

∀ϵ>0,∃C, s.t. P(|DCS2|<S−1)≤ϵ

综上|F|的大小为Θ(N−−√)的时候,可以保证有足够大的概率使得算法返回正确的中值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息