利用R语言生成双色球全量号码组合
Dustin
2017年7月1日
双色球的有效组合为17721088组,即中奖概率为一千七百七十万分之一。为了提升中奖率,需要将这些组合全部列出来,然后使用排除法,比如将:
1 2 3 4 5 6 XX
28 29 30 31 32 33 XX
这样的组合删除(此处仅为举例,这种顺子组合也是有可能发生,概率也和任何组合相同,不过人们更倾向于相信它不会发生)。本文仅介绍生成全量组合的方法。
最简单的是用FOR循环,使用rbind函数,但效率慢得出奇,跑了一天,才完成11%,这架势,没个10天跑不完了。
allballs=NULLfor (r1 in 1:28) { for (r2 in (r1 +1):29) { for (r3 in (r2 +1):30) { for (r4 in (r3 +1):31) { for (r5 in (r4 +1):32) { for (r6 in (r5 +1):33) { for (b1 in 1:16) {allballs=rbind(allballs,c(r1,r2,r3,r4,r5,r6,b1)) } } } }#显示当前处理进度print(nrow(allballs)/177210.88) } }}
以为是FOR循环效率太低的问题,好吧,我们用lapply改进,代码见下,结果效率还是没有提升,还是需要10天。。。
allballs=NULLlapply(1:28,function(r1){lapply((r1+1):29,function(r2){lapply((r2+1):30,function(r3){lapply((r3+1):31,function(r4){lapply((r4+1):32,function(r5){lapply((r5+1):33,function(r6){lapply(1:16,function(b1) {#此处注意需要使用"<<-"进行赋值allballs<<-rbind(allballs,c(r1,r2,r3,r4,r5,r6,b1))return(NULL) })return(NULL) })return(NULL) })return(NULL) })#显示当前处理进度print(nrow(allballs)/177210.88)return(NULL) })return(NULL) })return(NULL)})
前二个方法都失效了,看来问题出在rbind上,利用矩阵看看能否提升效率:
allballs =matrix(nrow=17721088,ncol=7)startrow=0starttime=Sys.time()for (r1 in 1:28) { for (r2 in (r1 +1):29) { for (r3 in (r2 +1):30) {for (r4 in (r3 +1):31) { for (r5 in (r4 +1):32) { for (r6 in (r5 +1):33) { for (b1 in 1:16) { startrow=startrow+1 allballs[startrow,]=c(r1,r2,r3,r4,r5,r6,b1) } } } }#显示当前处理进度print(startrow/ 177210.88) } }}endtime=Sys.time()print(endtime-starttime)
成功,总共仅需2.279536 mins(如果不显示进度,仅需要59.56677 secs)即完全生成。
虽然FOR已经完成要求,我们还是看看lapply会提升多少时间
allballs=matrix(nrow=17721088,ncol=7)startrow=0starttime=Sys.time()lapply(1:28,function(r1){lapply((r1+1):29,function(r2){lapply((r2+1):30,function(r3){lapply((r3+1):31,function(r4){lapply((r4+1):32,function(r5){lapply((r5+1):33,function(r6){lapply(1:16,function(b1) {#此处注意需要使用"<<-"进行赋值 startrow<<-startrow+1 allballs[startrow,]<<-c(r1,r2,r3,r4,r5,r6,b1)return(NULL) })return(NULL) })return(NULL) })return(NULL) })#显示当前处理进度# print(startrow/ 177210.88)return(NULL) })return(NULL) })return(NULL)})
endtime=Sys.time()print(endtime-starttime)
同样成功,不显示进度,耗时1.959551 mins,这个效率居然不如FOR循环。
大功告成,查看一下生成的结果:
colnames(allballs)=c("R1","R2","R3","R4","R5","R6","Blue")head(allballs)
## R1 R2 R3 R4 R5 R6 Blue## [1,] 1 2 3 4 5 6 1## [2,] 1 2 3 4 5 6 2## [3,] 1 2 3 4 5 6 3## [4,] 1 2 3 4 5 6 4## [5,] 1 2 3 4 5 6 5## [6,] 1 2 3 4 5 6 6
tail(allballs)
## R1 R2 R3 R4 R5 R6 Blue## [17721083,] 28 29 30 31 32 33 11## [17721084,] 28 29 30 31 32 33 12## [17721085,] 28 29 30 31 32 33 13## [17721086,] 28 29 30 31 32 33 14## [17721087,] 28 29 30 31 32 33 15## [17721088,] 28 29 30 31 32 33 16
生成的数据没有问题,直接存盘,好了,可以做进一步的分析了。
write.csv(allballs,"allballs.csv",row.names=FALSE)
文件有343M,这数据量不少啊。
本文来源:https://www.2haoxitong.net/k/doc/47cde056a200a6c30c22590102020740be1ecda1.html
文档为doc格式