王朝网络
分享
 
 
 

一种随机抽题的简单算法

王朝vc·作者佚名  2006-01-17
宽屏版  字体: |||超大  

一种随机抽题的简单算法

作者:贵州大学 王 凯

随机抽题是很多有关考试软件经常会遇到的问题,设相关题库中有n道题,要从中抽取m ( m<=n ) 道题,这要首先产生m个随机数。在C语言中,一般的做法是:int *intArray;

int i;

time_t t;

intArray = malloc(m*sizeof(int));

/*time(&t)将获取当前时间,srand把当前时间作为随机数的种子*/

srand((unsigned) time(&t));

/*依次产生m个随机数*/

for(i=0; i<m; i++)

intArray[i] = rand() %n;

……

free(intArray);

这样,就可以产生m个随机数,方法很简单,并且利用了当前时间作为随机数的种子,尽量地避免了出现重复抽题。但仔细一分析,重复抽题并未完全避免,同时是否已抽题不影响今后的抽取,将导致各个试题被抽取的几率不等。修正的方法有检查新抽取的题是否重复,若重复则重抽,这样做的方法很简单,仅仅在上面的程序中加入判断重复的语句,但各个试题被抽取的几率仍然不等。怎样办呢?

我们可以将1到n的n个数看成是n个人围成一个圆形,先产生一个随机数round,从1开始数(超过n有将是1),当数到round时,round号人退出(以后数到round时将跳过);接着又产生一个随机数round1,从前面的round一直数到round1(依次往下数,若经过round时将跳过),…,如此下去,一直到m个题都被抽取。

此方法表面看来很难,要设一个有n个元的集合,已被数到的元素将被删除,直到m个元素都被抽取为止,这样要有一个n(一般n>>m)个元的集合,将消耗较多的时间和空间资源。有没有更简单的方法呢?

先分析“退出”的影响。round退出后,小于round的编号不变,大于round的编号减一;round1退出后,小于round1的编号不变,大于round1的编号又要减一;…,这样就可以很简单的分析出一个简单的算法:依旧按前面所述的方法抽取随机数roundk,将roundk按n求余数,再将roundk与round1,

round2, …, roundk-1(此k-1个数已增序排列,roundk-1为前k-1次得到的随机数最大者)相比较,然后进入比较程序,先与round1比较,若roundk>=

round1,则roundk增一,再与round2比较,若roundk>= round2,则roundk再增一,…,这样就可以很简单地实现了无重复而且各个试题被抽取的几率相同的随机抽题算法。具体的做法是:int *intArray;

int i,j,k,temp;

time_t t;

intArray = malloc(m*sizeof(int));

srand((unsigned) time(&t));

/*依次产生m个随机数*/

for(i=0; i<m; i++){

temp= rand() %n;

/*查找temp原先的“真实”编号*/

for(j=0; j<i; j++)

if(temp= intArray[j])

temp++;

else{

/*temp应插在k位置处, 这样数组intArray就实现了排序,同时得到了temp原先的编号*/

k=j-1;

break;

}

for(j=i-1;jk;j--)

intArray [j+1]= intArray [j];

intArray [k] =temp; ①

/*以下根据题号产生题库部分省略*/

……

}

free(intArray);

上述做法的好处在于,没有任何附加存储空间,运算的复杂性大致上等于一个插入排序算法,但原始产生的题号顺序已经“被忽略了”,添加一个有m个元素的附加数组,就可以保留原始产生的题号顺序,例如intRandArray是一个有m个元素的附加数组,将①改为:

intRandArray[i] =intArray [k]= temp;

如此我们就可以已很小的时间与空间代价,实现了无重复而且各个试题被抽取的几率相同的随机抽题算法。但C语言中rand()一直饱受垢病,专业人员一直寻求更好的随机数生成算法,这方面有很多参考资料,请读者查阅,本文不再赘述。读者可考虑将随机数生成算法整合到本文的随机抽题算法中,以获得更好的随机抽题算法。

作者信息:

王 凯 (贵州省贵阳市花溪贵州大学数学系,邮编:550025)

邮箱:e_listen@163.com

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有