我想手动生成随机数.我知道每种语言都有rand或随机函数,但我很想知道它是如何工作的.有人有代码吗?
看看以下内容:
随机数生成
线性同余生成器 - 一种在Java中也使用的流行方法
随机数发生器列表
这里是另一个链接,详细阐述了在Java的Random类中使用LCG
POSIX.1-2001给出的实施方式的下面的例子rand()
和srand()
,当需要在两个不同的机器相同的序列可能有用的.
static unsigned long next = 1; /* RAND_MAX assumed to be 32767 */ int myrand(void) { next = next * 1103515245 + 12345; return((unsigned)(next/65536) % 32768); } void mysrand(unsigned seed) { next = seed; }
我假设你的意思是伪随机数.我所知道的最简单的一个(从旧机器上编写电子游戏游戏)的工作方式如下:
种子=种子*5 + 1;
每次调用随机数时都会这样做,然后你会使用你想要的许多低位.*5 + 1具有不错的属性(IIRC),无论你看多少位,都可以在重复之前击中每种可能性.
当然,缺点是它的可预测性.但这在游戏中并不重要.对于各种各样的事情,我们抓住了疯狂的随机数字,你永远都不知道下一个会是什么数字.
并行完成这样的事情,并结合结果.这是一个线性同余生成器.
http://en.wikipedia.org/wiki/Random_number_generator
描述了不同类型的随机数生成器及其创建方式.
阿罗哈!
手动你的意思是"不使用计算机"或"编写我自己的代码"?
如果不使用计算机就可以使用上看到的电视机在一个袋子里的东西像骰子,数字和所有这些方法时,他们选择的球队,赢得宾果系列等拉斯维加斯充满了针对这类方法的过程(场)使用给你不好的赔率和投资回报率.您还可以获得精彩的兰德书并转向随机选择的页面:
http://www.amazon.com/Million-Random-Digits-Normal-Deviates/dp/0833030477
(另外,为了娱乐,请阅读评论)
要编写自己的代码,您需要考虑为什么不使用RNG提供的系统不够好.如果您使用的是现代操作系统,它将为用户程序提供RNG,这些程序应该足以满足您的应用需求.
如果你真的需要实现自己的,那么有很多可用的发电机.对于非安全性使用,您可以查看LFSR链,同余生成器等.无论您需要哪种分布(统一,正常,指数等),您都应该能够找到算法描述和带有实现的库.
为了安全使用,您应该查看Yarrow/Fortuna,NIST SP 800-89指定的PRNG和RFC 4086,以获得为PRNG提供所需的良好熵源.或者甚至更好,使用OS中应该满足安全RNG要求的那个.
RNG的实施可能是一项有趣的练习,但很少需要.除非是玩具应用,否则不要发明自己的算法.不要,重复不要为安全应用程序发明RNG(例如生成加密密钥),至少除非你做一些seripus阅读和调查.你会感谢我的(我希望).
static void Main() { DateTime currentTime = DateTime.Now; int maxValue = 100; int hour = currentTime.Hour; int minute = currentTime.Minute; int second = currentTime.Second; int milisecond = currentTime.Millisecond; int randNum = (((hour + 1) * (minute + 1) * (second + 1) * milisecond) % maxValue); Console.WriteLine(randNum); Console.ReadLine(); }
上面显示了一段非常简单的代码来生成随机数.它是一个用C#编写的控制台程序.如果您知道任何类型的基本编程,这应该是可以理解的,并且易于转换为任何其他所需的语言.
DateTime只接受当前的日期和时间,大多数编程语言都有这样做的工具.
小时,分钟,秒和毫秒变量将日期时间值分解为其组成部分.我们只对这些部分感兴趣,所以可以忽略一天.同样,在大多数语言中,日期和时间通常表示为字符串.在.Net中,我们拥有可以轻松解析这些信息的工具.但是在大多数其他时间以字符串形式呈现的语言中,解析所需部分的字符串并将其转换为数字并不困难.这些设施通常以最古老的语言提供.
种子本质上给了我们一个始终改变的起始数字.传统上,您只需将此数字乘以0到1之间的十进制值,这样可以减少该步骤.
upperRange定义最大值.因此,生成的数字永远不会超过此值.它也永远不会低于0.所以没有ngeatives.但如果你想要否定,你可以手动否定它.(将其乘以-1)
实际变量randNum是什么保存您感兴趣的随机值.
诀窍是在将种子除以上限之后得到余数(模数).余数总是小于除数,在这种情况下是100.简单的数学告诉你,你的余数不能超过除数.因此,如果除以10,则不能有大于10的余数.在这种情况下,这个简单的法则可以得到0到100之间的随机数.
console.writeline只是将其输出到屏幕.
console.readline只是暂停程序,以便您可以看到它.
这是生成随机数的一段非常简单的代码.如果你每天在完全相同的工作间运行这个程序(但你必须在同一时,分,秒和毫秒),超过1天,你会开始一次又一次地生成相同的数字组额外的一天.这是因为它与时间紧密相关.那是发电机的分辨率.因此,如果您知道该程序的代码及其运行时间,您可以预测生成的数字,但这并不容易.这就是我使用毫秒的原因.使用秒或分钟只看我的意思.因此,您可以编写一个表格,显示1何时进入,0出现,2进入0时出现,依此类推.然后,您可以预测每秒的输出以及生成的数字范围.增加分辨率(通过增加更改的数字)越多,它就越难以获得可预测的模式所需的时间越长.这种方法足以满足大多数人的需求.
这是用于基本游戏的随机数生成的旧学校方式.它需要快速,简单.它是.这也突出了为什么,随机数字genaerators不是真正随机的,而是随机的psudo.
我希望这是对你的问题的合理答案.