数学中国

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

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

  [复制链接]
 楼主| 发表于 2019-6-17 18:40 | 显示全部楼层
计算到9699690的66个周期时,共有33309336个素数。(其中含有1,但不包括2,3,5,7,11,13,17,19这8个素数,这是用生成元制作素数的原因)
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-6-27 10:18 | 显示全部楼层
CLEAR ALL
SELECT 1
USE f:\k生素数\等差4生素数30新.DBF ALIAS 素数表
SELECT 2
USE f:\k生素数\等差4生素数不能合成的偶数.DBF ALIAS 偶数表
SELECT 3
USE f:\k生素数\单等差4生素数2倍合成数.DBF ALIAS 拆偶数表
    kssj=SECONDS()                      &&取出开始时间
        for n=1  to 12529
        @  2,3 say n
        SELECT  偶数表
        x=偶数
       JL=recno()
          SELECT 素数表
               GO 1
                count next 4687 for x/2=四素 to js1
             IF js1=1
                SELECT  拆偶数表     &&打开盛放素数的表
                APPEND BLANK                        &&增加一条空记录
                REPLACE 偶数 WITH x          &&将N值付给素数
                REPLACE 记录号 WITH JL
            ENDIf
            SELECT 偶数表
            skip
       ENDfor
   =MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是查找那些被误判的偶数,其实它们是等差4生素数的2倍。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-6-27 10:18 | 显示全部楼层
CLEAR ALL
SELECT 1
USE f:\k生素数\等差4生素数30新.DBF ALIAS 素数表
SELECT 2
USE f:\k生素数\等差4生素数不能合成的偶数.DBF ALIAS 偶数表
SELECT 3
USE f:\k生素数\单等差4生素数2倍合成数.DBF ALIAS 拆偶数表
    kssj=SECONDS()                      &&取出开始时间
        for n=1  to 12529
        @  2,3 say n
        SELECT  偶数表
        x=偶数
       JL=recno()
          SELECT 素数表
               GO 1
                count next 4687 for x/2=四素 to js1
             IF js1=1
                SELECT  拆偶数表     &&打开盛放素数的表
                APPEND BLANK                        &&增加一条空记录
                REPLACE 偶数 WITH x          &&将N值付给素数
                REPLACE 记录号 WITH JL
            ENDIf
            SELECT 偶数表
            skip
       ENDfor
   =MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是查找那些被误判的偶数,其实它们是等差4生素数的2倍。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-14 14:50 | 显示全部楼层
CLEAR ALL
SELECT 1
USE c:\visualfoxpro项目\偶数素数对.DBF ALIAS 偶数表
SELECT 2
USE c:\visualfoxpro项目\s3165万内素数.DBF ALIAS 素数表
    kssj=SECONDS()                      &&取出开始时间
  for OU=100000000 to 100000000 STEP 2
     @ 3,6 say OU
             JS=0
            For N=3 to ou/2 step 2
            Kf1=INT(SQRT(N))       &&求出奇数的开方根
            SELECT  素数表            &&打开素数表
            LOCATE FOR 素数>=kf1      &&根据开方根,查找最大素数
            DO CASE
                CASE EOF()          &&如果超出素数表最后一条记录
                        GO BOTTOM
                CASE 素数>kf1     &&如果找到的素数比开方根值大,就将记录指针退回一个,保证使用的最大素数在开方根内
                        SKIP -1
            ENDCASE
            SSS1=RECNO()    &&记录下最大素数(开方根内)记录位置(如果找到的素数等于开方根,则直接读取这个素数的位置)
            GO 1           &&从第一条记录开始读取素数(3)
            FOR j1=1 TO SSS1       &&内循环开始。这个循环实质上是从小到大顺序,依次读取素数。循环值是记录序号
                qmz1=MOD(N,素数)   &&以读取的素数为条件,对被判断值求模 【qmz=MOD(bpz,素数)】文本号括着的原在此行语句体部分.特别需要注意的是在用标点符号时,一定改成英文模式及半角状态。
                IF qmz1=0
                        EXIT         
                ENDIF
                SKIP            &&素数表指针向下移动一个
            ENDFOR
          IF j1>SSS1
             Kf2=INT(SQRT(OU-N))       &&求出奇数的开方根
            SELECT  素数表            &&打开素数表
            LOCATE FOR 素数>=kf2     &&根据开方根,查找最大素数
            DO CASE
                CASE EOF()          &&如果超出素数表最后一条记录
                        GO BOTTOM
                CASE 素数>kf2    &&如果找到的素数比开方根值大,就将记录指针退回一个,保证使用的最大素数在开方根内
                        SKIP -1
            ENDCASE
            SSS2=RECNO()    &&记录下最大素数(开方根内)记录位置(如果找到的素数等于开方根,则直接读取这个素数的位置)
            GO 1           &&从第一条记录开始读取素数(3)
            FOR j2=1 TO SSS2       &&内循环开始。这个循环实质上是从小到大顺序,依次读取素数。循环值是记录序号
                qmz2=MOD(OU-N,素数)   &&以读取的素数为条件,对被判断值求模 【qmz=MOD(bpz,素数)】文本号括着的原在此行语句体部分.特别需要注意的是在用标点符号时,一定改成英文模式及半角状态。
                IF qmz2=0
                        EXIT         
                ENDIF
                SKIP            &&素数表指针向下移动一个
            ENDFOR
             IF j2>SSS2
               JS=JS+1
             ENDIF
           endif
          ENDFOR
                SELECT  偶数表      &&打开盛放素数的表
                APPEND BLANK                        &&增加一条空记录
               REPLACE 偶数 WITH OU  
               REPLACE 素数对 WITH JS           &&将N值付给素数
   endfor
   =MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
CLEAR ALL
这是用vfp程序直接筛选素数对的程序,只不过运行有点慢,算1亿的偶数用时122分钟,太慢了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-29 20:04 | 显示全部楼层
SELECT 1
USE F:\最密k生素数\t23素数式.dbf ALIAS 素数式至23
SELECT 2
USE F:\最密k生素数\最密素数式.dbf ALIAS 密素数式
kssj=SECONDS()                      &&取出开始时间
FOR I=1 TO 36495360-39
&& @ 5,12 say I
SELECT 1
  go  I
      A=素数式23
      skip 39
      B=素数式23
    if B-A=186
          SELECT  1
          go I
         FOR J=1 TO 40
        D=RECNO()
        C=素数式23
          SELECT 2
          APPEND BLANK
          REPLACE 素数式段 WITH C
           SELECT  1
           GO D+1
        ENDFOR
      endif'
ENDFOR
=MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是直接从素数式至23中摘抄最密40生素数式的vfp程序
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-2 12:48 | 显示全部楼层
SELECT 1
USE F:\最密k生素数\t23素数式.dbf ALIAS 素数式至23
SELECT 2
USE F:\最密k生素数\最密素数式.dbf ALIAS 密素数式
kssj=SECONDS()                      &&取出开始时间
FOR I=1 TO 36495360-71
&& @ 5,12 say I
SELECT 1
  go  I
      A=素数式23
      skip 71
      B=素数式23
    if B-A=380
          SELECT  1
          go I
         FOR J=1 TO 72
        D=RECNO()
        C=素数式23
          SELECT 2
          APPEND BLANK
          REPLACE 素数式段 WITH C
           SELECT  1
           GO D+1
        ENDFOR
      endif'
ENDFOR
=MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
与上面的程序基本一致,只需改变间距和k生素数中的k值即可。
回复 支持 反对

使用道具 举报

发表于 2019-8-6 19:38 | 显示全部楼层
通常筛选比较大数内的素数的程序度需要比较长的时间,筛选素数对也是如此。
从你的运算中可以看出,常常是运算几天时间。这需要很大的毅力啊!

我所使用的由网友赠予的素对筛选程序则是速度比较快的程序。
对于偶数 9699690 开始的连续10个偶数的素对筛选,几乎是即刻得出了:
G(9699690) = 124180
G(9699692) = 28588
G(9699694) = 28853
G(9699696) = 56629
G(9699698) = 31437
G(9699700) = 37677
G(9699702) = 56566
G(9699704) = 33976
G(9699706) = 28220
G(9699708) = 56493

count = 10, algorithm = 2, working threads = 2, time use 0.004 sec
据说是用C++语言编写的,好厉害啊!
我使用Basic 语言筛选一个偶数 9699690的素数对,用了26分钟。正是没法比较啊!
CPU为:AMD Athlon(tm) xp2000+、操作系统:Win-xp;时间:26分 ; 2005/11/07

All keys of dividing  9699690  into two prime numbers:
4849723 + 4849967  4849639 + 4850051  4849631 + 4850059  4849613 + 4850077  4849589 + 4850101  4849567 + 4850123  4849531 + 4850159  4849529 + 4850161  4849459 + 4850231  4849417 + 4850273  4849307 + 4850383  4849291 + 4850399  4849277 + 4850413  4849223 + 4850467  
……
79 + 9699611  67 + 9699623  59 + 9699631  53 + 9699637  47 + 9699643  43 + 9699647  41 + 9699649  37 + 9699653  23 + 9699667
M= 9699690 S(m)= 124180  S1(m)= 124031  Sp(m)= 136157.51   δ(m)= .1   K(m)= 4.38  r= 3109
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-6 20:05 | 显示全部楼层
愚工688 发表于 2019-8-6 11:38
通常筛选比较大数内的素数的程序度需要比较长的时间,筛选素数对也是如此。
从你的运算中可以看出,常常是 ...

的确用时很多。
我在寻找不能有最密4生素数中项合成的偶数中,前6300万内用Excel计算的,既费时又费力。
后来又把8,9年前没有学懂VFP程序捡了回来,刚开始挂机计算的很慢,我的公式预计42亿后不再出现不能合成的偶数,每天计算1万个外循环,相当于跨越210*1万=210万,但是对于42亿来说仍是杯水车薪,没有办法,我就试着看一看能不能多开几个工作区,多挂一些类似程序,还行,能挂10来个,再多,无论内存,还是CPU的使用率都无法承受,那样计算下来,怕是一年也算不完。
一次偶然的机会,让我从新认识了VFP的特性,输出和显示计算中间值是致命的,它拖慢了运算速度,后来在工具选项菜单中,把不必要的选项前的对勾去掉了,是我惊讶的发现,运算竟能成百倍的增加,所以很快就结束了最密4生素数的中项不能合成偶数的寻找工作,同时也印证我的公式的正确性。
我试一试在有素数表的情况下,看一看用时多少,估计不可能快到0.004 sec的程度。
回复 支持 反对

使用道具 举报

发表于 2019-8-6 20:21 | 显示全部楼层
本帖最后由 愚工688 于 2019-8-6 12:24 编辑

确实学习新的知识需要很大的毅力。在不断摸索中得到提高,也得到乐趣。

我是没有这个毅力了。连怎么在计算机上编写C++程序也不知道。
我使用的高速筛选程序也是多个运算区域同时运行的,建立的素数分区可以使用于连续的其它偶数,这样大大减少了运行时间。
因此连续多个偶数的筛选素对是很快的,不指定数量时程序默认是筛选1000个偶数。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-20 11:32 | 显示全部楼层
SELECT 1
USE F:\最密k生素数\最密素数式.dbf ALIAS 密素数式
SELECT 2
USE F:\最密k生素数\余数表.dbf ALIAS 余表
SELECT 3
USE F:\最密k生素数\素数表万内.dbf ALIAS 素表
SELECT 4
USE F:\最密k生素数\符合条件的最密素数式.dbf ALIAS 符合素数式
kssj=SECONDS() &&取出开始时间
K=69 &&给k赋值
T=186 &&给出外循环值
FOR I=1 TO T
@ 5,12 say I
    SELECT 3
    go 1
    FOR N=1 TO 1229
    SELECT 3
    E=素数
    SELECT 2
    delete all
    pack
    SELECT 1
    go  k*(I-1)+1
      A=素数式段
         FOR M=1 TO K
           SELECT 1     
           B=素数式段
           C=B-A
           F=MOD(C,E)
           SELECT 2
           count all for F=余数 to js
           IF js=0
             SELECT 2
             APPEND BLANK
             REPLACE 余数 WITH F
           ENDIF
            SELECT 1
            SKIP
         ENDFOR
         SELECT 2
        G=RECCOUNT(2)
        IF G=E
           EXIT         
        ENDIF
        SELECT 3  
        SKIP
   ENDFOR
   IF   N>1229
     SELECT 1
          go k*(I-1)+1
         FOR J=1 TO k
        D=RECNO()
        C=素数式段
          SELECT 4
          APPEND BLANK
          REPLACE 素数式 WITH C
           SELECT  1
           GO D+1
        ENDFOR
  endif
ENDFOR
=MESSAGEBOX("运行时间:"+LTRIM(STR(INT((SECONDS()-kssj)/60)))+"分"+LTRIM(STR(MOD(SECONDS()-kssj,60),5,2))+"秒",64,"运行时间提示")
这是一个去伪最密k生素数式的程序,程序有两部分组成,第一部分为主要部分,目的是剔除不能通过素数检验的素数式,主要工作部分,连带部分,为第二部分,当全部通过万内素数检验后,把符合条件的最密k生素数式抄录在另一个已经准备好的表,此程序解决了用手工操作排除工作(原来在Excel中,用手工操作非常费事)。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-24 09:06 , Processed in 0.083008 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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