由于最后一节课明确提到,概率算法这一部分会出一道上课讲过的原题,因此以blog的形式对上课讲过的例题进行记录,仅作复习之用。
称一个序列为几乎有序是指:序列中至少90%的数据是有序的,即可删除其中不超过10%的数据使得剩下的序列有序。例如序列 { 1 , 2 , 3 , 4 , 5 , 10 , 6 , 7 , 8 , 9 } \{1,2,3,4,5,10,6,7,8,9\} {1,2,3,4,5,10,6,7,8,9}是几乎有序的,而序列 { 1 , 2 , 5 , 3 , 4 , 10 , 6 , 7 , 8 , 9 } \{1,2,5,3,4,10,6,7,8,9\} {1,2,5,3,4,10,6,7,8,9}中需要删除5和10才有序。仅80%数据有序,不满足几乎有序。现在需要设计算法检查一个序列是否几乎有序,输入为一个不包含重复元素的序列A,其输出如下:如果序列已经完全排序,总是返回True;如果序列没有90%排序,则以至少2/3的概率返回False。
问题描述: 假设箱子中总共有 n n n个球,其中至少10%的球是蓝色球,剩下的球是红色球。现在有放回地随机抽球,则需要抽取多少次才能以不少于 2 3 2\over3 32的概率抽到一个蓝色的球?
这个子问题可以说非常的关键,它直接对应于“如果序列没有90%排序,则以至少2/3的概率返回False”。
解法:
其解法也非常的简洁,假设至少需要抽取k次球,有:
令 p = 0.1 ,假设抽取 k 次: 令p=0.1,假设抽取k次: 令p=0.1,假设抽取k次:
1 − ( 1 − p ) k ≥ 2 3 ( 1 − p ) k ≤ ( 1 − p ) log 1 − p 1 3 k ≥ log 0.9 1 3 \begin{align*} 1- (1-p)^k & \geq{2\over3}\\ (1-p)^k & \leq (1-p)^{\log_{1-p}{1\over3}}\\ k & \geq \log_{0.9}{1\over3} \end{align*} 1−(1−p)k(1−p)kk≥32≤(1−p)log1−p31≥log0.931
故至少抽取 log 0.9 1 3 \log_{0.9}{1\over3} log0.931次,即可以不少于 2 3 2\over3 32的概率抽到一个蓝球。
问题描述: 给定如下二分搜索算法Binary-Search的pseudo-code:
Binary_Search(A, key, left, right):
if left == right:
return left
else:
mid = (left+right+1)/2 //向上取整
if key < A[mid]:
return Binary_Search(A, key, left, mid-1)
else:
return Binary_Search(A, key, mid, right)
假设在序列A中查找的 k e y key key值为 k e y 1 key_1 key1时算法返回下标 i i i,查找 k e y 2 key_2 key2值时算法返回下标 j j j,且A 并非完全有序 。证明以下结论:若 i < j , k e y 1 ≤ k e y 2 i\lt{j},\ key_1\leq{key_2} i<j, key1≤key2。
解法:
尽管问题看起来可能非常的复杂(第一眼看来好像无从下手),但是它的证明过程却非常简单。
当 i < j i\lt{j} i<j时,存在 A [ m i d ] A[mid] A[mid]使 k e y 1 ≤ A [ m i d ] , k e y 2 ≥ A [ m i d ] key_1\leq{A[mid]}, key_2\geq{A[mid]} key1≤A[mid],key2≥A[mid],所以当 i < j i\lt{j} i<j时,有 k e y 1 ≤ k e y 2 key_1\leq{key_2} key1≤key2,证毕。
问题描述: 现有如下概率算法IS_ALMOST_SORTED判断一个序列是否几乎有序:
IS_ALMOST_SORTED(A, n, k):
for r=1 to k:
i = RANDOM(1,n) //第2行
j = BINARY_SEARCH(A, A[i], 1, n)
if i != j:
return false //第5行
else:
return true
其中 R A N D O M ( 1 , n ) RANDOM(1, n) RANDOM(1,n)函数用于在闭区间 [ 1 , n ] [1, n] [1,n]中独利均匀地随机选择一个数。试依次证明如下结论从而说明算法的正确性:
a. 如果序列已经完全排序,则算法总是返回True;
b. 定义算法第2行随机选择的下标 i i i对应的元素 A [ i ] A[i] A[i]为“好数”或“坏数”:若 i = B i n a r y _ S e a r c h ( A , A [ i ] , 1 , n ) i=Binary\_Search(A, A[i], 1, n) i=Binary_Search(A,A[i],1,n)则称为“好数”,否则称为“坏数”。注意:“好数”和有序并不直接对应。需要证明的结论是: 若序列A并非90%排序,则至少10%的数为“坏数”(提示:反证法假设少于10%的数为“坏数”,剔除这些“坏数”后证明剩下的“好数”序列有序,从而导出矛盾);
c. 若序列没有90%排序,则以至少 2 3 2\over3 32的概率返回False。
Reference:
这道问题的解答参考自https://blog.csdn.net/hxz_qlh/article/details/18419571。
解答:
a. 若序列已经完全排序,则不会执行到算法的第5行,一定返回True,证毕;
b. 反证法:假设少于10%的数为“坏数”,将这些“坏数”从序列中剔除,剩下90%的“好数”序列。任取序列中的两个数,都有 i < j i\lt{j} i<j时, A [ i ] < A [ j ] A[i]\lt{A[j]} A[i]<A[j],说明剩下的数都是有序的“好数”,这与序列A并非90%有序矛盾,故原命题成立。
c. 若A并非90%有序,则至少有10%的“坏数”。由 子问题 1 子问题1 子问题1可知,当 k ≥ log 0.9 1 3 k\geq\log_{0.9}{1\over3} k≥log0.931时,找到一个“坏数”的概率,即使得概率算法返回false的概率至少为 2 3 2\over3 32,证毕。