关于 随机

关于随机

前言:上了好久网课,好久没发文了......这些都是当时的笔记~

一、随机化

随机化是一种常见的解决实际问题的算法,是利用一定的策略进行随机使得得到正确答案或者作出正确操作的概率尽量大。

这样的算法的执行结果是”有一定概率正确“的,因此理论上讲是有可能输出错误的结果。或许有同学会认为这种算法很不靠谱,会担心在比赛时使用了随机化的算法,导致自己在比赛中失分。

但事实上,当我们能保证自己的算法错误概率较低时,这样的担心是完全没有必要的。

这就好比你去买彩票,中奖的概率挺低的,中 5 块钱都觉得挺不错了~

我们的算法也一样,当算法出错的概率极低时,就几乎不可能在测试中出错了。

所以当我们的算法发生错误的概率足够低时,输出错误答案的事件几乎不可能发生,也就不必担心会因此失分了。

二、 rand()函数

c++中,rand()是一个随机生成的函数。可以返回一个伪随机数。

#include 
#include  
#include  
using namespace std;
int main(){
    printf("%d %d\n",rand(),rand());
}

上面的代码实现了利用 rand() 输出两个随机数。

但如果同学们多次执行上面的程序,会发现每次输出的两个数字都是一样的,这可太假了。

事实上,这也是为什么我们称 rand() 函数返回的数为"伪随机数"。

rand() 函数一般来说要和 srand() 函数配合使用。

#include
using namespace std;
int main(){
    srand(10);
    printf("%d %d\n",rand(),rand());
}

加入这句话之后, rand 函数返回的数字和刚才不一样了吧。

但是,重复执行上面的程序,发现永远只输出这两个相同的数字。

如果将 srand() 函数的参数换成其他数字,输出结果又会不同,但重复执行并不会有不同的结果。

我们不禁猜想,或许 rand 函数返回的结果是和 srand() 函数的参数有关的。

确实是这样, rand() 函数的返回值是借助于 srand() 的参数(被称为随机种子)生成出来的,每个随机种子会对应生成一个在分布上均匀的序列, rand() 函数会在第 i 次被调用时返回该序列中第 i 个数字,因此我们只要使得 srand 的参数随机,就能使得 rand() 的返回值随机。

那么,如何才能使得 srand() 的参数随机呢?

在 C++ 中,有这样一个函数 time(0) ,它的返回值是自 1970−01−01  00:00:00  UTC 到调用函数时经过的秒数。

只要打开程序的时间是随机的,那么 time() 的返回值就可以看作是一个随机的数字,因此只要把 time() 作为随机种子即可实现”真正的“随机。

#include
using namespace std;
int main(){
    srand(time(0));
    printf("%d %d\n",rand(),rand());
}

三、 爬山算法

爬山算法是一类特殊的随机化算法,之前我们看到的随机化算法的应用,其解法看起来毫无章法。但是爬山算法,则是有章法、有规律的随机化算法,是武林中的正统功法。

不过要注意的是,爬山算法虽然有规律、有章法,但也得具体问题具体分析。在分析题目时一定要先判断是否适合使用爬山算法,适合使用再套用爬山算法求解。

爬山算法是一个局部择优的方法,采用启发式方法,是对搜索的一种改进,它利用了当前反馈的信息来调整寻找解的方向和策略。具体来说,爬山算法会时刻维护一个当前解 x ,判断 x 和附近的解 x′ 谁更优秀,如果这个 x′ 更优,那么转移到 x′ ,否则不变。

显然,当我们要求最大解或者最小解时,以 x 为横坐标、对应的解的大小为纵坐标得到一个单峰函数时,爬山算法一定会得到正确解,因为每个非最优的 x 靠近最优解的方向都会有一个更优的解。

对于一些非单峰函数的问题,例如解与其优劣性对应的函数图像为下图的:

关于 随机_第1张图片

绿色箭头:爬山算法同样有概率找到最优解。

红色箭头:但也有可能最终找到的是一个局部的最优解。

降温

在之前我们提到,爬山算法会找一个当前解 x 附近的解 x′ ,这个 x′ 要有多"附近",也即距离 x 有多远,可以通过"温度"来决定。在最开始时靠近最优解的概率较小,因此这个距离可以大一点;在执行一段时间后,更可能接近最优解,因此这个距离不能太大,以免找的附近的点太远,更加远离最优解。

因此我们可以用一个变量 t 来表示温度,也即这个"附近"的程度。起初将 t 设为 1 ,可以在当前解附近 t·D 的距离内找下一个解( D 是根据题目决定的一个值),在下一次找附近的解之前,要进行"降温",即给 t 乘上一个小于 1 的数,使得下一次找附近解的范围变小。

为了使爬山算法尽量的可靠,我们会重复进行多次爬山算法来增大其正确的概率。

结语


最好的爱,是有你相伴,最暖的情,是有你相惜。懂得,是最长情的告白,告白,便是心与心的懂得。但愿此生有你,来世有你,生生世世,相伴相依,不厌,亦不倦。

你可能感兴趣的