找回密码
 欢迎注册
楼主: 数学星空

[讨论] 关于单位分数的一些难题

[复制链接]
发表于 2010-1-14 12:40:58 | 显示全部楼层
看看稍微修改以后就可以求出s(7)

  1. // shc.cpp : Defines the entry point for the console application.
  2. //

  3. #include "stdafx.h"
  4. #include <math.h>
  5. #define L 40
  6. #define N 7
  7. #define K 5
  8. unsigned n[K];
  9. unsigned long long M[K];
  10. unsigned long long R[K];
  11. unsigned long long maxM;
  12. int A[4];
  13. long long count[K];
  14. long long gc[L];

  15. void solve()
  16. {
  17.     unsigned long long V=M[K-1]*M[K-1]+R[K-1];
  18.     unsigned long long r=M[K-1]%R[K-1];
  19.     r=R[K-1]-r;
  20.     unsigned long long u=r;
  21.     for(;u<=M[K-1];u+=R[K-1]){
  22.         if(V%u==0&&(u+M[K-1]>=R[K-1]*n[K-1])){
  23.             int i;
  24.             for(i=0;i<K;i++){
  25.                 printf("%d ",n[i]);
  26.             }
  27.             printf("%lld %lld\n",(u+M[K-1])/R[K-1],(V/u+M[K-1])/R[K-1]);
  28.         }
  29.     }
  30. }

  31. void output(int level, int overflow)
  32. {
  33.     if(level==K){
  34.         int a3=A[3]%4;
  35.         int a1=A[1]%4;
  36. /*        if(A[2]==1&&a1==1)
  37.             return;
  38.         if(A[0]==1&&a3==0)
  39.             return;
  40.         if(A[0]==0&&A[2]==0){
  41.             if((a1==1||a1==2)&&a3<2)
  42.                 return;
  43.         }
  44.   */      int c=(int)ceil(log10((double)(M[level-1])));
  45.         if(c>=L)c=L-1;
  46.         if(c<0)c=0;
  47.         gc[c]++;
  48.         solve();
  49.     }
  50.     if(M[level-1]>maxM)maxM=M[level-1];
  51.     count[level-1]++;
  52. }

  53. unsigned long long gcd(unsigned long long x,unsigned long long y)
  54. {
  55.     while(y!=0){
  56.         unsigned long long r=x%y;
  57.         x=y;
  58.         y=r;
  59.     }
  60.     return x;
  61. }

  62. void search(int level)
  63. {
  64.     if(level>=K){
  65.         output(level,0);
  66.         return;
  67.     }
  68.     double ll=(double)M[level-1]/R[level-1];
  69.     double uu=ll*(N-level);
  70.     if(uu>=4294967295.5||uu>=18446744073709551615.0/M[level-1]){///overflow
  71.         output(level,1);
  72.         return;
  73.     }
  74.     unsigned li=(unsigned)ceil(ll);
  75.     unsigned ui=(unsigned)uu;
  76.     if(li<=n[level-1])li=n[level-1]+1;
  77.     unsigned i;
  78.     for(i=li;i<=ui;i++){
  79.         if(gcd(M[level-1],i)!=1)
  80.             continue;
  81.         n[level]=i;
  82.         M[level]=M[level-1]*i;
  83.         R[level]=R[level-1]*i-M[level-1];
  84.         A[i%4]++;
  85.         search(level+1);
  86.         A[i%4]--;
  87.     }
  88. }

  89. void search0()
  90. {
  91.     int i;
  92.     for(i=0;i<4;i++)A[i]=0;
  93.     for(i=2;i<=7;i++){
  94.         n[0]=i;
  95.         R[0]=i-1;
  96.         M[0]=i;
  97.         A[i%4]++;
  98.         search(1);
  99.         A[i%4]--;
  100.     }
  101. }

  102. int _tmain(int argc, _TCHAR* argv[])
  103. {
  104.     search0();
  105.     int i;
  106.         return 0;
  107. }

复制代码

评分

参与人数 2威望 +2 鲜花 +8 收起 理由
wayne + 6
medie2005 + 2 + 2

查看全部评分

毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-1-14 13:46:24 | 显示全部楼层
根据45#,我们有340万个平均22位最多28位的整数需要分解因子.
我不知道分解这么大的整数平均需要多长时间.假设分解每一个数需要1秒钟,那么也只需要一个CPU大概1000小时,从计算量上看,是完全可行的.
而如果直接采用试除法,由于已经知道因子的特殊形式,平均每个大概需要试除数百万次,也就是大概需要$10^14$次128比特整数的除法运算,从计算量上看,可能比因子分解算法慢数倍,但是从计算量上也是可行的.而且对于这个方法,我们只要提供一个128比特整数比较有效的加减乘除代码就可以了.
谁先提供一个效率比较高的128比特整数的加减乘除运算代码看看,我们只需要修改52#中的solve程序采用128比特计算,然后修改N为8,K为6就可以了.可以先部分运行一下代码测试一下大概的速度
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-1-14 14:23:50 | 显示全部楼层
快速乘法有了:
x86上128位二进制乘法最快速算法征解
除法有没有好的?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-1-14 14:25:46 | 显示全部楼层
看了一下solve的代码,只需要128位除64位的除法运算,那么应该直接用汇编指令就可以了.
谁将上面的solve函数改写一下?汇编我长时间不用,已经非常不熟练了
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-1-14 14:46:17 | 显示全部楼层
除法要快速,一般是针对除数是固定值时,预先算好一些算法值以加速运算。
对于128位除64位的除法,用一般的试商法即可;
如果在64位系统下,只要将高地位分别移进 RDX:RAX,而后 DIV 除数 即可。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-1-14 19:41:36 | 显示全部楼层
存在一些很大的M/R,所以还是要用对V因子分解的方法
然后对V每个小于sqrt(V)的因子d,如果(d+M)是R倍数,就可以构着一个解.
这个还是谁用Mathematica来做比较好.如果能够运行两个月左右估计就能解决这个问题了
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-1-14 19:45:40 | 显示全部楼层
呵,这个还是谁用Mathematica来做比较好.如果能够运行两个月左右估计就能解决这个问题了
这个难题可能对wayne来说不是问题,可惜我的mathematica编程不行.....
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-1-14 20:34:40 | 显示全部楼层
请教mathe:
51#楼的程序文件格式为.cpp吧?
在visual  studio 2008中运行怎么不成功呢?
见下图: 11.jpg
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-1-14 20:52:55 | 显示全部楼层
看图示似乎是编译未通过,尚未生成 exe 文件。

你可以用向导产生一个工程(目的:生成stdafx.h及staafx.cpp),
然后再将 mathe 的代码粘贴进来进行编译。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-1-15 09:59:35 | 显示全部楼层
试着用LiLDA求解,发现代码有bug,做因子分解时经常崩溃掉,而且稍微添加一点代码,崩溃的地方都不同,不知道什么原因

  1. #include <time.h>
  2. #include <LiDIA/rational_factorization.h>
  3. #include <iostream.h>
  4. using namespace LiDIA;
  5. using namespace std;
  6. #include <math.h>
  7. #define L 40
  8. #define N 8
  9. #define K 6
  10. unsigned long n[K];
  11. bigint M[K];
  12. bigint R[K];
  13. bigint maxM;
  14. int A[4];
  15. long long c;
  16. long long gc[L];
  17. int start_time;

  18. #define MAX_INDEX 20
  19. int iindex[MAX_INDEX];
  20. void solve()
  21. {
  22.         bigint V,MM,RR,uu;
  23.         MM=M[K-1];
  24.         RR=R[K-1];
  25.         V=MM*MM+RR;
  26.         rational_factorization f;
  27.         f.assign(V);
  28.         f.factor();
  29.         if(!f.is_prime_factorization()){
  30.                 printf("cannot factor %lld solution\n",c);
  31.         }else{
  32.                 if(f.no_of_comp()>=MAX_INDEX){
  33.                         printf("too much compondents for %lld solution\n",c);
  34.                 }else{
  35.                         int i;
  36.                         for(i=0;i<f.no_of_comp();i++){
  37.                                 iindex[i]=0;
  38.                         }
  39.                         do{
  40.                                 bigint v=1;
  41.                                 for(i=0;i<f.no_of_comp();i++){
  42.                                         int j;
  43.                                         for(j=0;j<iindex[i];j++){
  44.                                                 v*=f.base(i);
  45.                                         }
  46.                                 }
  47.                                 if((v+MM)%RR==0){///solution found
  48.                                         for(i=0;i<K;i++){
  49.                                                 cout<<"n"<<i+1<<"="<<n[i]<<";";
  50.                                         }
  51.                                         cout<<"n"<<K+1<<'='<<(v+MM)/RR<<";n"<<K+2<<"="<<(V/v+MM)/RR<<";\n";
  52.                                 }
  53.                                 for(i=f.no_of_comp()-1;i>=0;i--){
  54.                                         if(iindex[i]==f.exponent(i)){
  55.                                                 iindex[i]=0;
  56.                                                 continue;
  57.                                         }else{
  58.                                                 iindex[i]++;
  59.                                                 break;
  60.                                         }
  61.                                 }
  62.                                 if(i<0)break;
  63.                         }while(1);
  64.                 }
  65.         }
  66.         fflush(stdout);
  67. }

  68. void output(int level, int overflow)
  69. {
  70.     if(level==K){
  71.         solve();
  72.     }
  73.     if(M[level-1]>maxM)maxM=M[level-1];
  74.     c++;
  75.     fprintf(stderr,"processed %lld by %ds\n",c,time(NULL)-start_time);
  76. }

  77. void search(int level)
  78. {
  79.     if(level>=K){
  80.         output(level,0);
  81.         return;
  82.     }
  83.     double ll=(double)dbl(M[level-1])/dbl(R[level-1]);
  84.     double uu=ll*(N-level);
  85.     if(uu>=4294967295.5){///overflow
  86.         output(level,1);
  87.         return;
  88.     }
  89.     unsigned long li=(unsigned long)ceil(ll);
  90.     unsigned long ui=(unsigned long)uu;
  91.     if(li<=n[level-1])li=n[level-1]+1;
  92.     unsigned long i;
  93.     for(i=li;i<=ui;i++){
  94.         if(gcd(M[level-1],i)!=1)
  95.             continue;
  96.         n[level]=i;
  97.         M[level]=M[level-1]*i;
  98.         R[level]=R[level-1]*i-M[level-1];
  99.         A[i%4]++;
  100.         search(level+1);
  101.         A[i%4]--;
  102.     }
  103. }

  104. void search0()
  105. {
  106.     int i;
  107.     for(i=0;i<4;i++)A[i]=0;
  108.     for(i=2;i<=7;i++){
  109.         n[0]=i;
  110.         R[0]=i-1;
  111.         M[0]=i;
  112.         A[i%4]++;
  113.         search(1);
  114.         A[i%4]--;
  115.     }
  116. }

  117. int main()
  118. {
  119.         start_time=time(NULL);
  120.     search0();
  121.     int i;
  122.         return 0;
  123. }

复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-5-2 13:45 , Processed in 0.052739 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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