当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 一种快速可预制的随机数组产生方法

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 一种快速可预制的随机数组产生方法


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 97 ::
收藏到网摘: n/a

一种快速可预制的随机数组产生方法

作者:重庆大学光电学院311实验室 袁刚

下载源代码

本文介绍了一种简单、快捷、实用的随机数组产生方法,经调试通过。附件为全部程序代码请审阅。

  在工程软件的设计和安全系统设计中,建立模型、产生密码经常需要使用到随机数组。然而计算机不会产生绝对随机的随机数,计算机只能产生“伪随机数”。其实绝对随机的随机数只是一种理想的随机数,即使计算机怎样发展,它也不会产生一串绝对随机的随机数。计算机只能生成相对的随机数,即伪随机数。
  伪随机数并不是假随机数,而是指有规律的数,事实上都是由计算机经过一定的算法计算得到的。大家常用的方法是根据一个给定的数作为种子,如采用变化的时间作为种子,调用srand((unsigned)time(NULL))后执行rand()从而获得一个随机数。很显然,相同或相近的种子得到的随机数将会是完全一样或互相接近。
  因此要产生真正意义的随机数,那么种子首先必须是随机的。随机的种子可以通过外接的硬件随机发生器产生,据说最新的intel处理器即采用了读取cpu上热噪声的方法来获取随机数。当无法利用硬件的随机发生器时,我们常采用的办法是,在两次调用srand((unsigned)time(NULL))之间加入一定时间的延时。但当需要产生一个很大的随机数组时,这种延时是漫长而不可忍受的。而且事实上由于延时具有规律性,产生的随机数也不那么随机。
  一种容易想到的产生随机数组的方法是设计出复杂的算法,从而减小数组结果的规律性。这种方法需要很高的技巧,也不太适合一般程序的调用。
  此外,在很多情况下,我们不仅要求产生随机的数组,同时还对产生的数组有统计规律上的要求。如必须服从正态分布,均匀分布等。简单的调用srand和rand函数无法满足需要。
Matlab是一种功能强大的工程数学软件,利用其随机数组产生模块,我们能很容易的得到服从各种分布形式的大数组,其随机数产生的原理即是基于复杂的算法的。因此我们自然想到利用matlab产生的随机数表来作为随机数池,从中获得我们所需要的随机数组。
  本随机数组产生方法由三部分组成:其一是txt文件的随机数池,这里我利用matlab产生1000个服从正态分布的随机数,10个一排,每两个数字之间间隔3个空格,行首3个空格存为文本文档,第一个数序号为0,然后按先行后列序号依次排列到999;其二和三分别是从随机数池中捞取随机数的函数类的.h文件和.cpp文件。
  在捞取随机函数的函数类中,定义CStdioFile的file1,打开作为随机数池的txt文档。首先以时间作为种子,产生一个0-999的随机数,读取随机数池中从以这个值为序号的开始的数,直到读够所需的随机数组。序号如果超出数池的范围则跳到数池的开始,继续读取。
  调用本函数类,需要输入int m_Collect_Times,double *a_Random,int m_Txt_Line,int m_Txt_Row,int m_Txt_Spacing分别代表取点个数、取得的随机数组的存储位置、随机数池行数、列数、数池中两数间空格个数。并将"C:\\Yg\\Debug\\ramdom1000txt"改为你的随机数池文件的位置," "中的空格数改为你所使用的空格数。

下面为本函数类中的主要函数代码:

void CRandomArrayFromTxt::GetRandomArrayFromTxt(int m_Collect_Times,	double *a_Random,	int m_Txt_Line, int m_Txt_Row,	int m_Txt_Spacing){ int m,mx,my,cl; srand((unsigned)time(NULL)); // 生成时间种子 m=rand()%m_Txt_Line; // 返回一个0-m_Txt_Line-1的随机数,即查表的起始位置 mx=m%m_Txt_Row; // 查表起始位置的列号,文件头为0行0列 my=m/m_Txt_Row; // 查表起始位置的行号 cl=(m_Collect_Times+mx-1)/m_Txt_Row+1; // 需要从数表中读取的行数 // 打开txt文本的数表。 CStdioFile file1( "C:\\Yg\\Debug\\ramdom1000.txt",	CFile::modeNoTruncate | CFile::modeRead | CFile::typeText); CString strc; int ct=0; // 用于记录当前已经取得的随机数个数 for(m=0;m<my;m++) { file1.ReadString(strc); } // 取出有用的行,直到取够为之 for(int n=0;n<cl;n++) {	if(n+my==m_Txt_Line)	file1.SeekToBegin();	// 数表不够长,重新定位到文件头	file1.ReadString(strc); if(n==0) // 如果是取得的第一行	{	int aw1,aw2; aw1=strc.GetLength(); for(m=0;m<mx+1;m++) // 过掉前面无用的空格	{ aw1=strc.GetLength(); aw2=strc.Find(" "); // 找到作为间隔的前三个空格所在位置 strc=strc.Right