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

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

[复制链接]
发表于 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-12-28 03:32 , Processed in 0.061938 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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