python 彩票建议
我知道Python有一个叫做random的模块,可以用来做一些简单的抽奖。比如说,random.shuffle()这个方法就很好用。
不过,我想自己做一个简单的抽奖程序。我应该关注哪些方面呢?抽奖背后有没有什么特别的数学原理?
假设我们有100个名字,然后随机选出20个名字。
我不想用shuffle,因为我想学习自己怎么做。
我需要一些建议来开始。谢谢。
5 个回答
我很赞赏你想自己动手做这个的决心。
回到1950年代,普通人很难获得随机数,除非他们有当时的超级计算机。RAND公司出版了一本书,叫做一百万个随机数字和十万个正态偏差,里面真的就有随机数字。这本书太棒了,因为它让普通人也能用高质量的随机数进行研究。
现在,回到你的问题。
我建议你先看看这本书的使用说明(没错,它是有说明的),然后试着在你的Python代码中实现这些内容。虽然这样做可能不够高效或优雅,但你会理解你最终选择的算法的含义。我特别喜欢其中一段,教你如何:
随便翻到数字表中的一页,盲目选择一个五位数;这个数字的第一个数字取模2后决定起始行;然后在最初选择的五位数右边的两个数字取模50,决定起始行中的起始列。
读那个数字表真是一门艺术!
当然,我并不是鼓励你为了生产代码而重新发明轮子。我是想让你通过实现一个聪明的、虽然不太高效的随机数生成器,来学习随机性的艺术。
我的工作需要使用高质量的随机数,偶尔我发现网站www.random.org是一个很好的资源,既能提供见解也能提供材料。从他们的网站上:
RANDOM.ORG为互联网上的任何人提供真正的随机数。这些随机性来自于大气噪声,对于许多用途来说,比通常在计算机程序中使用的伪随机数算法要好。人们使用RANDOM.ORG来进行抽奖、彩票和抽奖活动,驱动游戏和赌博网站,进行科学应用,以及艺术和音乐创作。
现在,去实现你自己的抽奖吧。
看看这个Fisher-Yates洗牌算法,它在Knuth的《计算机程序设计的艺术》中也有描述。
你可以自己生成伪随机数,这背后有很多理论,想了解的话可以从这里开始。不过,当然你生成的随机数在质量和速度上都比不上Python的random
库里的“Mersenne twister”(在我给你链接的维基百科页面中间部分有解释)。不过为了理解这个过程,自己动手做也是个不错的选择。或者,你也可以从物理上获取随机数,比如在Linux机器上可以用/dev/random
或/dev/urandom
(Windows机器也有自己的方法)——前者的随机性更强,后者的性能更好。
一旦你有了(或者借用了random
的功能;-))一个伪随机(或者真正的随机)数生成器,从100个项目中随机挑选20个仍然是个有趣的问题。虽然洗牌是一种更通用的方法,但更容易理解的方式可能是,假设你的myrand(N)
函数返回一个在0到N之间的随机整数(包含0但不包含N):
def pickfromlist(howmany, thelist):
result = []
listcopy = list(thelist)
while listcopy and len(result) < howmany:
i = myrand(len(listcopy))
result.append(listcopy.pop(i))
return result
这个方法可能不是效率最高的,但我希望它能让你更清楚!-) 用简单的话说:只要需要并且可行,就从剩下的项目中随机挑选一个(辅助列表listcopy
在每一步给我们提供“剩下的项目”,并通过.pop
进行修改,而不会改变输入参数thelist
,因为它是一个浅拷贝)。