随机函数rand Floyd算法

1.rand(void)函数简介

  • 功能:产生随机数,最大值为0X7FFFH
  • 返回值:返回所产生的随机数
  • 表头文件:<stdlib.h>
  • 无参数

 srand(seed)函数简介

  • 原型:void srand(unsigned seed);
  • 功能:是随机数发生器函数(rand)的初始化函数,给rand函数提供一个随机数开始的初始值(最小值)
  • 参数:参数是无符号整型数据,只要满足无符号整型数据的表示范围即可
  • 表头文件:<stdlib.h>
  • 返回值为空

一般是先使用srand函数为rand函数提供一个初始值即rand函数从rsrand (seed)中指定的seed开始,返回一个[seed, RAND_MAX(0x7fff))间的随机整数。

 

2.rand函数单独使用

当rand函数单独使用时,系统会在rand函数前用一次srand(1),即rand函数返回的随机数从[1, RAND_MAX]。

此时randrand函数会产生规定的随机数,但是每次产生的随机数序列都是一样的。下面举例子说明这一点:

<span style="font-size:14px;">#include <stdio.h>
#include <stdlib.h>

int main(void)
{
        int i, re;

        i       = 0;

        while(i < 10){
                re      = rand();
                i++;

                printf("%d ", re);
        }
        printf("\n");

        return 0;
}
</span>

然后使用命令 gcc rand.c -o rand编译源文件,再运行生成的可执行文件

./rand     得到结果如下

1804289383    846930886     1681692777     1714636915     1957747793     424238335     719885386     1649760492     596516649     1189641421


再次运行可执行文件得到结果如下

1804289383     846930886    1681692777    1714636915    1957747793    424238335     719885386    1649760492    596516649    1189641421

也就是说只要运行过一次可执行文件之后,以后每次执行结果都是一样的。

 

3.在使用rand函数之前使用srand(seed)函数

3.1使用常数作为seed值

修改代码如下后

<span style="font-size:14px;">#include <stdio.h>
#include <stdlib.h>

int main(void)
{
        int i, re;

        i       = 0;

        //使用srand函数为rand函数提供种子
        srand(1189641421);

        while(i < 3){
                re      = rand();
                i++;

                printf("%d ", re);
        }
        printf("\n");

        return 0;
}
</span>

通过编译和执行步骤后得到一下结果:

645298965    371103934   491315407


再次运行可执行文件得到结果如下

645298965   371103934 4  91315407

也就是说使用固定值seed初始化rand函数后每次得到的随机序列也是一样的。只是范围发生变化而已,范围变为[seed, RAND_MAX]

 

3.2使用不断变化的seed作为srand参数

将以上代码改为以下形式:

<span style="font-size:14px;">#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

int main(void)
{
        int i, re;

        i       = 0;

        //使用srand函数为rand函数提供种子
        srand((unsigned)time(NULL));

        while(i < 3){
                re      = rand();
                i++;

                printf("%d ", re);
        }
        printf("\n");

        return 0;
}
</span>

经编译后初次运行后的结果为:

861061899  480645075   280256411


再次运行的结果为

1793735524   811069568   731560706


再次运行得到的结果为

475626611   1524657326   1104320056


这就是说只要种子发生生了变化则随机数返回的随机序列就会不同。srand((unsigned)time(NULL))表明每次运行程序时都是一个变量。关于time系列的函数留到以后的篇章中笔记。

 

4.随机得到[L,U]之间的整数

  • rand() / double(RAND_MAX)可以取得0~1之间的浮点数
  • rand() / (double)(RAND_MAX/10)取更大范围的随机浮点数1~10,至于100,1000的情况,如此类推
  • rand() % (U+1 - L) + L 随机得到得到[L,U]之间的整数。

 

5.总结

随机数函数的主要用途是用在switch或者if..else中。随机的决定一些选项,若rand(seed)在系统每次启动时都会发生变化,则相同算法产生的结果就会不同。

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

int main(void)
{
        int i, re;

        i       = 0;

        //使用srand函数为rand函数提供种子
        srand((unsigned)time(NULL));

        while(i < 3){
                re      = rand();
                i++;

                printf("%d ", re);
        }
        printf("\n");

        return 0;
}

 

6 Floyd 算法

Floyd算法用以产生不重复的随机整数。先笔记产生(1, n)的m个不重复的随机整数的方法。


6.1 基本算法

s = empty
size = 0
while size < m do
    T = randint(1, n)
    if T not in S then
        insert T in s
        size++

randint(1, n)是调用rand函数以产生1 ~ n的一个整数。


此算法潜在的问题:

  • m > n时,会永远执行此段代码。
  • m <= n时且m值又较大时,由于randint函数的随机性也可能导致此算法久久的执行()。

6.2 Floyd算法

(1) 递归实现

function sample (m, n)
    if m = 0 then
        return
    else s = sample(m-1, n-1)
           T = randint(1, n)
           if T is not in s then
               insert T in s
           else insert n is s
return s
此段代码时用Awk伪码的方式表示Floyd算法的。


从1 ~ n - m中产生一个随机整数,若此整数已经存在于s中则将n-m存储于s中,这样就避免了上一个算法潜在的第二个问题。


(2) Floyd的非递归实现

 递归是代码耗时的一个典型,在实际应用中,若程序的大多数运行时间都在Floyd算法之上的话可以将Floyd递归算法优化为非递归的形式以提高程序的效率。

s = empty
for j = n-m +1 to n do
    T = randint(1, j)
    if T is not in s then
        insert T in s
    else insert T in s
这样就实现了Floyd算法。哈哈。

2014-02-16

Note Over。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值