Algorithm Course Review(14.1)
第14章,随机算法,random algorithm。
随机算法,当算法在执行过程中面临一个选择时,随机行选择常比最优选择快,因此随机算法可以在一定程度上降低算法的复杂度。
由于随机过程的存在,对所求解问题的同一个输入,可能得到完全不同的输出。
随机算法一般分为四类,数值随机算法,蒙特卡罗(Monte Carlo)算法,拉斯维加斯(Las Vegas)算法和舍伍德(Sherwood)算法。
数值概率算法常用于数值问题的求解。这类算法所得到的往往是近似解。而且近似解的精度随计算时间的增加不断提高。在许多情况下,要计算出问题的精确解是不可能或没有必要的,因此用数值概率算法可得到相当满意的解。
蒙特卡罗算法用于求问题的准确解。对于许多问题来说,近似解毫无意义。例如,一个判定问题其解为“是”或“否”,二者必居其一,不存在任何近似解答。又 如,我们要求一个整数的因子时所给出的解答必须是准确的,一个整数的近似因子没有任何意义。用蒙特卡罗算法能求得问题的一个解,但这个解未必是正确的。求 得正确解的概率依赖于算法所用的时间。算法所用的时间越多,得到正确解的概率就越高。蒙特卡罗算法的主要缺点就在于此。一般情况下,无法有效判断得到的解 是否肯定正确。
拉斯维加斯算法不会得到不正确的解,一旦用拉斯维加斯算法找到一个解,那么这个解肯定是正确的。但是有时候用拉斯维加斯算法可能找不到解。与蒙特卡罗算法 类似。拉斯维加斯算法得到正确解的概率随着它用的计算时间的增加而提高。对于所求解问题的任一实例,用同一拉斯维加斯算法反复对该实例求解足够多次,可使 求解失效的概率任意小。
舍伍德算法总能求得问题的一个解,且所求得的解总是正确的。当一个确定性算法在最坏情况下的计算复杂性与其在平均情况下的计算复杂性有较大差别时,可在这个确定性算法中引入随机行将它改造成一个舍伍德算法,消除或减少问题的好坏实力间的差别。舍伍德算法的精髓不会避免算法的最坏情况,而是设法消除这种最坏情况与特定实例之间的关联性。
这段内容可以参考《计算机算法设计与分析》(第三版)。
因为需要产生随机数,先看看随机数的生成。
在现实计算机上无法产生真正的随机数,只是在一定程度上是随机的,即为随机数(pseudo-random)。线性同余法是产生伪随机数最常用的方法。由线性同余法产生的随机序列a1,a2,...,an...满足
a0=d; an=(b * an-1 + c) mod m, n=1,2,...
d称为随机序列的种子,b,c,m关系到随机序列的随机性能。通常m为机器大数,b为一素数。在上面提到的参考书中,给除了一个示例程序,
randseed = time(0) unsigned short random(unsigned short n) { randseed = m * randseed + b; return (unsigned short) ((randseed>>16)%n); }
上面与示例程序稍微有些差别,示例程序中n为unsigned long,但是它是要产生[0,n)的随机数,返回类型和n的类型应该是一致的。由于randseed在函数内部也要使用,所以把它作为一个class的成员变量,而上面的函数就作为成员函数。
C/C++提供了两个与随机数相关的函数,<stdlib>
void srand ( unsigned int seed );设置随机数的种子 int rand ( void );生成随机数,范围0~RAND_MAX的整数。 value= rand() % p + b;生成在[b,b+p)范围内的随机数。
rand生成的序列是伪随机数,在seed确定的情况下,一个随机程序执行两遍,生成的随机序列是一样的。一般会采用srand将当前时间设置为seed。
代码如下,
#include <iostream> #include <ctime> #include <cstdlib> using namespace std; int main() { int N = 10; int P = 100; srand(time(NULL)); for(int i=0;i<N;i++) { cout << rand() % P << endl; } return 0; }
对随机算法的应用,数值随机算法典型的有,计算pi,定积分等。舍伍德算法的典型应用,如随机快速排序,随机选择算法等。拉斯维加斯算法可以用来解n皇后问题,整数因子分解等。蒙特卡罗比较典型问题有主元素问题,素数测试等。下次再来详细整理各应用。