数学中国

 找回密码
 注册
搜索
热搜: 活动 交友 discuz
楼主: 白新岭

[原创]请教vfbpgyfk先生一个编程问题

  [复制链接]
 楼主| 发表于 2019-3-10 07:02 | 显示全部楼层
有三生素数(0,2,4)的表产生四生素数(0,2,4,2),如果是拿三生素数表中的数作为判断依据,那就是去掉mod(-2,素数)=mod(三素,素数),即去掉与-2同余的数,模素数p;如果用三生素数表中三素+2作为新的判断,则去掉余数为0的;在第一次制作四生素数时,因为没有用到最大值的根号前素数,结果误判些四生素数出来,共计5005个,这比实际值要多。余数条件是相对的,一定把这个道理搞清楚。新的用时11分3.13秒,产生了5000个,少了5个,看来正好差2是素数平方的数很少。截止范围106694663
 楼主| 发表于 2019-3-10 07:25 | 显示全部楼层
用四生素数表产生五生素数表正(0,2,4,2,4)用时1分37.40秒,产生了723组;产生五生素数表逆(0,4,2,4,2)用时1分39.67秒,产生了721组;看来两种正逆五生素数的数量基本一致
 楼主| 发表于 2019-3-10 07:35 | 显示全部楼层
用五生素数表逆(0,4,2,4,2)产生六生素数表(0,4,2,4,2,4)用时10.66秒,共计82组,很短,所以筛选k生素数,一定要找好的方法,硬来是要花费好长时间的
 楼主| 发表于 2019-3-10 20:58 | 显示全部楼层
用时5分29.21秒,产生逆三生素数生成元,(0,4,2),共计323323*2=646646个数,经过5次筛选,获得9699690以内全部逆三生素数生成元,2*(7-3)*(11-3)*(13-3)*(17-3)*(19-3)=640*224=143360个。
CLEAR ALL
SELECT 1
USE  e:\用vfp求k生素数数量\素数表2.DBF ALIAS 素数表
SELECT 2
USE  e:\用vfp求k生素数数量\三生素数生成元逆19.DBF ALIAS 三生成元19
    kssj=SECONDS()                      &&取出开始时间
   For N=1 to 323323
    @ 3,6 say N
        FOR M=13 TO 19 STEP 6
        @ 5,8 say M
         X=M+(N-1)*30
           SELECT 素数表
           go 3
            FOR I=1 TO 5 &&内循环开始。这个循环实质上是从小到大顺序,依次读取素数。
            @ 2,5 say  素数   
                IF  X%素数=0 OR X%素数=2 OR X%素数=6
                  EXIT         
                ENDIF
                SKIP            &&素数表指针向下移动一个
            ENDFOR
            IF I>5
                SELECT   三生成元19         &&打开盛放素数的表
                APPEND BLANK                &&增加一条空记录
                REPLACE 三生元逆19 WITH X     &&将N值付给素数
            ENDIF
        ENDFOR
   ENDFOR
   =MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是逆三生素数生成元程序,仅仅改了表和初始值及求模条件
 楼主| 发表于 2019-3-10 21:37 | 显示全部楼层
Pi5(n)→→10.1318018169296000 →→(0,2,4,2,4)
Pi5(n)→→10.1318018169296000 →→(0,4,2,4,2)
Pi7(n)→→53.9720251184226000 →→(0,2,6,4,2,4,2)
Pi7(n)→→53.9720251184226000 →→(0,2,4,2,4,6,2)
可以看出7生素数一个是在5生素数逆元前边加了两个素数,一个是在5生素数后边加了两个素数,这样我们可以拿5生素数作为基础数据,来获得7生素数。
用时3.30秒,获得13组。
CLEAR ALL
SELECT 1
USE e:\用vfp求k生素数数量\素数62个周期.DBF ALIAS 素数表
SELECT 2
USE e:\用vfp求k生素数数量\五生素数表正.DBF ALIAS 五素表
SELECT 3
USE e:\用vfp求k生素数数量\七生素数表.DBF ALIAS 七素表
    kssj=SECONDS()                      &&取出开始时间      
        SELECT 五素表
        go 1
        DO WHILE NOT EOF()
        @ 2,5 say 五素
            bpz=五素+8
            Kf=INT(SQRT(bpz))       &&求出奇数的开方根
            SELECT  素数表             &&打开素数表
            LOCATE FOR 素数>=kf      &&根据开方根,查找最大素数
            DO CASE
                CASE EOF()          &&如果超出素数表最后一条记录
                        GO BOTTOM
                CASE 素数>kf     &&如果找到的素数比开方根值大,就将记录指针退回一个,保证使用的最大素数在开方根内
                        SKIP -1
            ENDCASE
            SSS=RECNO()-2   &&记录下最大素数(开方根内)记录位置(如果找到的素数等于开方根,则直接读取这个素数的位置)
            GO 3           &&从第一条记录开始读取素数(3)
            FOR j=1 TO SSS       &&内循环开始。这个循环实质上是从小到大顺序,依次读取素数。循环值是记录序号
                IF  MOD(bpz,素数)=0 OR MOD(bpz,素数)=2 &&以读取的素数为条件,对被判断值求模 【qmz=MOD(bpz,素数)】文本号括着的原在此行语句体部分.特别需要注意的是在用标点符号时,一定改成英文模式及半角状态
                        EXIT         
                ENDIF
                SKIP            &&素数表指针向下移动一个
            ENDFOR
            IF j>sss
                SELECT  七素表      &&打开盛放素数的表
                APPEND BLANK                        &&增加一条空记录
                REPLACE 七素 WITH bpz           &&将N值付给素数
          ENDIF
         SELECT  五素表
        skip
       ENDdo
   =MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
CLEAR ALL
这里最主要的是要反清股,不要能反了,置前的余数为正,置后的余数为负,它们正好相反,一定不要弄错,否则结果是错误的。
 楼主| 发表于 2019-3-10 21:58 | 显示全部楼层
用时3.53秒,用逆5生素数表产生逆7生素数表,获得21组,最起码第一个19属于误判。
CLEAR ALL
SELECT 1
USE e:\用vfp求k生素数数量\素数62个周期.DBF ALIAS 素数表
SELECT 2
USE e:\用vfp求k生素数数量\五生素数表逆.DBF ALIAS 五素表
SELECT 3
USE e:\用vfp求k生素数数量\七生素数表逆.DBF ALIAS 七素表
    kssj=SECONDS()                      &&取出开始时间      
        SELECT 五素表
        go 1
        DO WHILE NOT EOF()
        @ 2,5 say 五素
            bpz=五素-18
            Kf=INT(SQRT(bpz))       &&求出奇数的开方根
            SELECT  素数表             &&打开素数表
            LOCATE FOR 素数>=kf      &&根据开方根,查找最大素数
            DO CASE
                CASE EOF()          &&如果超出素数表最后一条记录
                        GO BOTTOM
                CASE 素数>kf     &&如果找到的素数比开方根值大,就将记录指针退回一个,保证使用的最大素数在开方根内
                        SKIP -1
            ENDCASE
            SSS=RECNO()-2   &&记录下最大素数(开方根内)记录位置(如果找到的素数等于开方根,则直接读取这个素数的位置)
            GO 3           &&从第一条记录开始读取素数(3)
            FOR j=1 TO SSS       &&内循环开始。这个循环实质上是从小到大顺序,依次读取素数。循环值是记录序号
                IF  MOD(bpz,素数)=0 OR MOD(bpz,素数)=2 &&以读取的素数为条件,对被判断值求模 【qmz=MOD(bpz,素数)】文本号括着的原在此行语句体部分.特别需要注意的是在用标点符号时,一定改成英文模式及半角状态
                        EXIT         
                ENDIF
                SKIP            &&素数表指针向下移动一个
            ENDFOR
            IF j>sss
                SELECT  七素表      &&打开盛放素数的表
                APPEND BLANK                        &&增加一条空记录
                REPLACE 七素 WITH bpz+18          &&将N值付给素数
          ENDIF
         SELECT  五素表
        skip
       ENDdo
   =MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
CLEAR ALL
 楼主| 发表于 2019-3-10 22:30 | 显示全部楼层
Pi8(n)→→178.26229268981000 →→(0,2,4,2,4,6,2,6),显然有正7生素数加一个素数而来(后边加)
Pi8(n)→→475.36611383949400 →→(0,2,4,6,2,6,4,2),它自对称不能有以前的k生素数获得,但是可以有三生素数获得,仍然比较经济(比起用自然数来好的多)
Pi8(n)→→178.26229268981000 →→(0,6,2,6,4,2,4,2),显然有逆7生素数加一个素数而来(前边加)
用时0.63秒,有7生素数表获得8生素数表。4条记录。
CLEAR ALL
SELECT 1
USE e:\用vfp求k生素数数量\素数62个周期.DBF ALIAS 素数表
SELECT 2
USE e:\用vfp求k生素数数量\八生素数正.DBF ALIAS 八素表
SELECT 3
USE e:\用vfp求k生素数数量\七生素数表.DBF ALIAS 七素表
    kssj=SECONDS()                      &&取出开始时间      
        SELECT 七素表
        go 1
        DO WHILE NOT EOF()
        @ 2,5 say 七素
            bpz=七素+6
            Kf=INT(SQRT(bpz))       &&求出奇数的开方根
            SELECT  素数表             &&打开素数表
            LOCATE FOR 素数>=kf      &&根据开方根,查找最大素数
            DO CASE
                CASE EOF()          &&如果超出素数表最后一条记录
                        GO BOTTOM
                CASE 素数>kf     &&如果找到的素数比开方根值大,就将记录指针退回一个,保证使用的最大素数在开方根内
                        SKIP -1
            ENDCASE
            SSS=RECNO()-2   &&记录下最大素数(开方根内)记录位置(如果找到的素数等于开方根,则直接读取这个素数的位置)
            GO 3           &&从第一条记录开始读取素数(3)
            FOR j=1 TO SSS       &&内循环开始。这个循环实质上是从小到大顺序,依次读取素数。循环值是记录序号
                IF  MOD(bpz,素数)=0  &&以读取的素数为条件,对被判断值求模 【qmz=MOD(bpz,素数)】文本号括着的原在此行语句体部分.特别需要注意的是在用标点符号时,一定改成英文模式及半角状态
                        EXIT         
                ENDIF
                SKIP            &&素数表指针向下移动一个
            ENDFOR
            IF j>sss
                SELECT  八素表      &&打开盛放素数的表
                APPEND BLANK                        &&增加一条空记录
                REPLACE 八素 WITH bpz        &&将N值付给素数
          ENDIF
         SELECT  七素表
        skip
       ENDdo
   =MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
CLEAR ALL
这些程序基本上一致,只做少量更改
 楼主| 发表于 2019-3-10 22:43 | 显示全部楼层
提示开方数不能为负(19-26=-7),所以有此提示,我把这条记录删除了。用时0.43秒,获得7组。
CLEAR ALL
SELECT 1
USE e:\用vfp求k生素数数量\素数62个周期.DBF ALIAS 素数表
SELECT 2
USE e:\用vfp求k生素数数量\八生素数逆.DBF ALIAS 八素表
SELECT 3
USE e:\用vfp求k生素数数量\七生素数表逆.DBF ALIAS 七素表
    kssj=SECONDS()                      &&取出开始时间      
        SELECT 七素表
        go 1
        DO WHILE NOT EOF()
        @ 2,5 say 七素
            bpz=七素-26
            Kf=INT(SQRT(bpz))       &&求出奇数的开方根
            SELECT  素数表             &&打开素数表
            LOCATE FOR 素数>=kf      &&根据开方根,查找最大素数
            DO CASE
                CASE EOF()          &&如果超出素数表最后一条记录
                        GO BOTTOM
                CASE 素数>kf     &&如果找到的素数比开方根值大,就将记录指针退回一个,保证使用的最大素数在开方根内
                        SKIP -1
            ENDCASE
            SSS=RECNO()-2   &&记录下最大素数(开方根内)记录位置(如果找到的素数等于开方根,则直接读取这个素数的位置)
            GO 3           &&从第一条记录开始读取素数(3)
            FOR j=1 TO SSS       &&内循环开始。这个循环实质上是从小到大顺序,依次读取素数。循环值是记录序号
                IF  MOD(bpz,素数)=0  &&以读取的素数为条件,对被判断值求模 【qmz=MOD(bpz,素数)】文本号括着的原在此行语句体部分.特别需要注意的是在用标点符号时,一定改成英文模式及半角状态
                        EXIT         
                ENDIF
                SKIP            &&素数表指针向下移动一个
            ENDFOR
            IF j>sss
                SELECT  八素表      &&打开盛放素数的表
                APPEND BLANK                        &&增加一条空记录
                REPLACE 八素 WITH bpz+26       &&将N值付给素数
          ENDIF
         SELECT  七素表
        skip
       ENDdo
   =MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
CLEAR ALL
 楼主| 发表于 2019-3-11 05:08 | 显示全部楼层
1131分10.32秒 产生了58668个逆三生素数
CLEAR ALL
SELECT 1
USE e:\用vfp求k生素数数量\素数表2.DBF ALIAS 素数表
SELECT 2
USE e:\用vfp求k生素数数量\三生素数生成元逆19.DBF ALIAS 三生成元19
SELECT 3
USE e:\用vfp求k生素数数量\三生素数表逆.DBF ALIAS 三生素数
    kssj=SECONDS()                      &&取出开始时间
   For N=0 to 10
    @ 12,15 say  N      
        SELECT 三生成元19
        go 1
        DO WHILE NOT EOF()
        @ 14,18 say 三生元逆19
            bpz=三生元逆19+N*9699690
            Kf=INT(SQRT(bpz))       &&求出奇数的开方根
            SELECT  素数表             &&打开素数表
            LOCATE FOR 素数>=kf      &&根据开方根,查找最大素数
            DO CASE
                CASE EOF()          &&如果超出素数表最后一条记录
                        GO BOTTOM
                CASE 素数>kf     &&如果找到的素数比开方根值大,就将记录指针退回一个,保证使用的最大素数在开方根内
                        SKIP -1
            ENDCASE
            SSS=RECNO()    &&记录下最大素数(开方根内)记录位置(如果找到的素数等于开方根,则直接读取这个素数的位置)
            GO 8          &&从第一条记录开始读取素数(3)
            FOR j=1 TO SSS-7    &&内循环开始。这个循环实质上是从小到大顺序,依次读取素数。循环值是记录序号
                qmz=MOD(bpz,素数)   &&以读取的素数为条件,对被判断值求模 【qmz=MOD(bpz,素数)】文本号括着的原在此行语句体部分.特别需要注意的是在用标点符号时,一定改成英文模式及半角状态。
                IF qmz=0 or qmz=2 or qmz=6
                    EXiT         
                ENDIF
                SKIP            &&素数表指针向下移动一个
            ENDFOR
            IF j>sss-7
                SELECT  三生素数      &&打开盛放素数的表
                APPEND BLANK                        &&增加一条空记录
                REPLACE 三素 WITH bpz            &&将N值付给素数
           ENDIF
         SELECT  三生成元19
        skip
       ENDdo
   endfor
   =MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
CLEAR ALL
 楼主| 发表于 2019-3-11 09:43 | 显示全部楼层
上面的运行时间是我理解错了,STR()函数是在在前边留空格放正负号的,而LTRIM()函数仅去掉左边的空格(有专一去掉右边的空格,还有去掉前后空格的,中间的空格没有能去的),所以从头24时开始,到第二天早起用时是一个负数,显示-1131分10.32秒,转化成正数为24*60-1131分10.32秒=1440分-1131分10.32秒=308分49.28秒,这才是实际时间,因为电脑运行时是23点左右,早晨5点时已经停止运行,最多6个小时,怎么会1100多分钟,很纳闷,原来是这里给了个陷阱,谁让自己不知道函数的用法。这样折合成小时,用了5个小时多点。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|数学中国 ( 京ICP备05040119号 )

GMT+8, 2025-5-13 15:03 , Processed in 0.094850 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表