概率算法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

return r_select(A[],low,high,k);
1. Type r_select(Type A[],int low,int high,int k) 2. { 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. int i; if (high-low<=k) return A[high]; else { i = random(low,high); swap(A[low],A[i]); i = split(A,low,high); if ((i-low)==k) return A[i]; else if ((i-low)>k) /* 产生 low 到 high 之间的随机数 i */ /* 把元素 A[i]交换到数组的第一个位置*/ /* 按元素 A[low]把数组划分为两个 */ /* 元素 A[i]就是第 k 小元素 */ /* 直接返回 A[i] */ /* 第 k 小元素位于第一个子数组 */ /* 从第一个子数组寻找 */ /* 否则 */ /* 第 k 小元素已位于子数组的最高端 */ /* 直接返回最高端元素 */
随机(概率)算法
算法的特征:确定性。算法对所有可能的输入,都必须能够得到正确的答案。 很多确定性的算法,其性能很坏。 用随机选择的方法来改善算法的性能。 某些方面可能不正确,对特定的输入,算法的每一次运行不一定得到相同结果。 出现这种不正确的可能性很小,以致可以安全地不予理睬。
9.1
随机算法引言
解问题 P 的随机算法定义为:设 I 是问题 P 的一个实例,用算法解 I 的某些时刻,随机 选取 b ∈ I ,由 b 来决定算法的下一步动作。 优点:1、执行时间和空间,小于同一问题的已知最好的确定性算法; 2、实现比较简单,容易理解。
9.2
舍伍德(Sherwood)算法
一、确定性算法的平均运行时间
T A ( x ) :确定性算法 A 对输入实例 x 的运行时间。 X n :规模为 n 的所有输入实例全体。
算法 A 的平均运行时间:
2
T A(n) =
x∈ X n
∑T
A ( x) /
|Xn |
存在实例 x ∈ X n , T A ( x ) >> T A ( n ) 。 例:快速排序算法 当输入数据均匀分布时,运行时间是 Θ ( n log n ) 。 当输入数据按递增或递减顺序排列时,算法的运行时间变坏 二、舍伍德算法的基本思想 消除不同输入实例对算法性能的影响,使随机算法 B 对规模为 n 的每一个实例 x ∈ X n , 都有:
1
9.1.2 随机数发生器
一、产生随机数的公式:
⎧ d0 = d ⎪ ⎨ d n = b d n −1 + c ⎪ a = d / 65536 n ⎩ n n = 1, 2 , L
(9.1.1)
产生 0~65535 的随机数 a1 , a 2 , L 序列,
b 、 c 、 d 为正整数, d 称为所产生的随机序列的种子。
9.1.1 随机算法的类型
一、类型:数值概率算法、拉斯维加斯(Las Vegas)算法、蒙特卡罗(Monte Carlo)算法、 及舍伍德(Sherwood)算法。 1、数值概率算法:用于数值问题的求解。所得到的解几乎都是近似解,近似解的精度 随着计算时间的增加而不断地提高。 2、拉斯维加斯算法:要么给出问题的正确答案,要么得不到答案。反复求解多次,可 使失效的概率任意小。 3、蒙特卡罗算法:总能得到问题的答案,偶然产生不正确的答案。重复运行,每一次 都进行随机选择,可使不正确答案的概率变得任意小。 4、舍伍德算法:很多具有很好的平均运行时间的确定性算法,在最坏的情况下性能很 坏。引入随机性加以改造,可以消除或减少一般情况和最坏情况的差别。 二、时间复杂性的衡量 衡量确定性算法的时间复杂性,是取它的平均运行时间。 衡量随机算法的时间复杂性,是对确定实例 I 的期望运行时间,即反复地运行实例 I , 所取的平均运行时间。 在随机算法里,所讨论的是最坏情况下的期望时间,和平均情况下的期望时间。
C (i )+
∑C (i )
i=k
的值达最大。因此
C (n) ≤ n+
n −1 n −1 ⎤ 1⎡ ⎢ C (i )+ C ( i )⎥ n ⎢ i = n − n / 2 +1 ⎥ i = ⎡n / 2 ⎤ ⎡ ⎤ ⎣ ⎦


根据归纳定义,对所有的 k , 1 ≤ k ≤ n − 1 , C ( k ) ≤ 4 k 成立。所以,有
9.2.1 随机快速排序算法
随机选择枢点的快速排序算法。
算法 9.1 随机选择枢点的快速排序算法
输入:数组 A,数组元素的的起始位置 low,终止位置 high 输出:按非降顺序排序的数组 A 1. template <class Type> 2. void quicksort_random(Type A[],int low,int high) 3. { 4. 5. 6. } random_seed(0); r_quicksort(A,low,high); /* 选择系统当前时间作为随机数种子 */ /* 递归调用随机快速排序算法 */
C (n) ≤ n+
n −1 n −1 ⎤ 1⎡ ⎢ 4i + 4i ⎥ n ⎢ i = n − n / 2 +1 i = n / 2 ⎥ ⎡ ⎤ ⎡ ⎤ ⎦ ⎣


= n+
n −1 n −1 ⎤ 4⎡ ⎢ i + i⎥ n ⎢ i = n − n / 2 +1 i = n / 2 ⎥ ⎡ ⎤ ⎡ ⎤ ⎦ ⎣
swap(A[low],A[k]); k = split(A,low,high); r_quicksort(A,low,k-1); r_quicksort(A,k+1,high);
/* 把元素 A[k]交换到数组的第一个位置*/ /* 按元素 A[low]把数组划分为两个 */ /* 排序第一个子数组 */ /* 排序第二个子数组 */
1. void r_quicksort(Type A[],int low,int high) 2. { 3. 4. 5. int k; if (low<high) { k = random(low,high); /* 产生 low 到 high 之间的随机数 k */
3
6. 7. 8. 9. 10. 11. } }
算法的期望运行时间是 Θ ( n log n ) 。
9.2.3 随机选择算法
从 n 个元素中选择第 k 小元素。
算法 9.2 随机选择算法
输入:从数组 A 的第一个元素下标为 low,最后一个元素下标为 high 中,选择第 k 小元素 输出:所选择的元素 1. template <class Type> 2. Type select_random(Type A[],int low,int high,int k) 3. { 4. 5. 5. 6. } random_seed(0); k = k – 1; /* 选择系统当前时间作为随机数种子 */ /* 使 k 从数组的第 low 元素开始计算 */ /* 递归调用随机选择算法 */
static unsigned long seed; void random_seed(unsigned long d) { if (d==0) seed = time(0); else seed = d; }
unsigned int random(unsigned long low,unsigned long high) { seed = MULTIPLIER * seed + INCREMENT; return ((seed >> 16) % (high – low) + low); }
0 i k-1 n-1 0 k-1 i n-1
i + 1 个元素
n–i -1 个元素 (a)
i 个元素 (b)
n–i
个元素
图 9.1
枢点元素在第 k 小元素之前和之后的情况
算法所执行的元素比较的期望次数为:
C (n) = n+ 1⎡ ⎢ n⎣ ⎢

i =0
k −2
C ( n − i −1) +
∑ C ( i )⎥ ⎥ ⎦
return r_select(A,low,i-1,k); else
return r_select(A,i+1,high,k-i-1); /* 从第二个子数组寻找 */ 4
16. 17. }
}
算法的运行时间 1、最坏的情况:第 i 轮递归调用,所选择的枢点元素,恰是数组的第 i 大、或第 i 小元 素。所执行的元素比较次数为
n + ( n −1) + L +1 = 1 n ( n +1) = Θ ( n 2 ) 2
发生这种情况的概率为 1 / n ! ,微乎其微。 2、元素比较的期望次数小于 4 n 。
C ( n ) :对 n 个元素的数组所执行的元素比较的期望次数。
用数学归纳法证明。 当 n = 2 及 n = 3 时,容易验证: C ( 2 ) ≤ 4 ⋅ 2 = 8 , C ( 3 ) ≤ 4 ⋅ 3 = 12 。 假定,对所有的 k , 1 ≤ k ≤ n − 1 , C ( k ) ≤ 4 k 成立。证明 C ( n ) ≤ 4 n 也成立。 枢点元素的位置 i 是 0 , 1 , L , n − 1 中的任何一位置,并具有相同概率。 因为序号从 0 开始,第 k 小元素相当于数组的第 k − 1 位置。 1) i = k − 1 :枢点元素就是第 k 小元素, 调用一次 split 函数,执行 n 次元素比较操作 2) i < k − 1 :丢弃序号为 0 , 1 , L , i 等 i + 1 个元素, 在其余 n − i − 1 个元素之中继续寻找第 k 小元素, 除调用 split 函数所执行的 n 次元素比较操作外, 还需执行 C ( n − i − 1 ) 次元素比较操作。 3)如果 i > k − 1 ,丢弃序号为 i , i + 1 , L , n − 1 等 n − i 个元素, 在前面 i 个元素之中寻找第 k 小元素, 除调用 split 函数所执行的 n 次元素比较操作外, 还需执行 C ( i ) 次元素比较操作。
i =k
n −1

5
= n+
n −1 n −1 ⎤ 1⎡ C (i )+ C ( i )⎥ ⎢ n⎣ ⎢ i = n − k +1 ⎥ i =k ⎦


n −1 ⎡ 1 ⎡ n −1 ⎤⎤ ≤ n + max ⎢ ⎢ C (i )+ C ( i )⎥ ⎥ k ⎢ n ⎢ ⎥ i=k ⎦⎥ ⎣ ⎣ i = n − k +1 ⎦
常数 b 、 c ,对所产生的随机序列的随机性能有很大的关系, b 通常取一素数。 二、随机数发生器 函数 random_seed 提供给用户选择随机数的种子, 函数 random 计算新的种子,并产生一个范围为 low ~ high 的新的随机数。
#define #define MULTIPLIER 0x015A4E35L; INCREMENT 1;
∑ ∑
n −1
∑ ∑
≤ n+
1⎡ ⎢max n⎢ k ⎣
n −1 ⎡ n −1 ⎤⎤ C (i )+ C ( i )⎥ ⎥ ⎢ ⎢ ⎥ i=k ⎣ i = n − k +1 ⎦⎥ ⎦
因为 C ( n ) 是 n 的非降函数,所以,当 k = ⎡ n / 2 ⎤ 时,方程
i = n − k +1

n −1
TB ( x ) = T A ( n ) + s ( n )
三、期望运行时间:
T B(n) =
x∈ X n
∑T
B ( x) /
|XnLeabharlann Baidu|
T B ( n ) = T A ( n ) + s ( n ) 。当 s ( n ) 与 T A ( n ) 相比很小可以忽略时,舍伍德算法有很好的
性能。 对所有输入实例而言, 运行时间相对均匀。 时间复杂性与确定性算法的时间复杂性相当


≤ n+
n −1 n −1 ⎤ 4⎡ ⎢ i + i⎥ n ⎢ i = n / 2 +1 i = n / 2 ⎥ ⎡ ⎤ ⎦ ⎣ ⎣ ⎦


≤ n+
n −1 n −1 ⎤ 4⎡ ⎢ i + i⎥ n ⎢ i= n / 2 i = ⎡n / 2 ⎤ ⎥ ⎣ ⎡ ⎤ ⎦


= n+
8 n
i = ⎡n / 2 ⎤
相关文档
最新文档