找回密码
 欢迎注册
查看: 23199|回复: 14

[原创] 大于n的最小高合成数

[复制链接]
发表于 2019-4-17 14:13:45 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
类似问题:小于n的最大高合成数
https://bbs.emath.ac.cn/thread-6248-1-1.html
https://blog.csdn.net/hcbbt/article/details/38580367

$n= 2 \times 10^40$


补充两个高合成数的资料
https://en.wikipedia.org/wiki/Highly_composite_number
http://wwwhomes.uni-bielefeld.de/achim/highly.html
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2019-4-17 15:03:38 | 显示全部楼层
8*9*25*7*11*13*17*19*23*29*31*37*41*43*47*53*59*61*67*71*73*79*83*89*97*101 小于 2*10^40,可以作为一个基本值,可在此基础上调整
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2019-4-17 15:48:27 | 显示全部楼层
64*81*25*49*121*169*289*19*23*29*31*37*41*43*47*53*59*61*67*71*73*79*83
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2019-4-17 16:04:09 | 显示全部楼层
本帖最后由 zeroieme 于 2019-4-17 16:35 编辑
liangbch 发表于 2019-4-17 15:03
8*9*25*7*11*13*17*19*23*29*31*37*41*43*47*53*59*61*67*71*73*79*83*89*97*101 小于 2*10^40,可以作为一 ...


有什么好办法“调整”

And
64*81*25*49*121*169*289*19*23*29*31*37*41*43*47*53*59*61*67*71*73*79*83<2*10^40
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2019-4-17 16:50:12 | 显示全部楼层
首先,这个数 可表示为 \(  {p_n}^{e_n} *  ... *  {p_2}^{e_2} * {p_1}^{e_1}\), p1=2, p2=3,p3=5
如100以内的高度合成数中,最大的为 \( 60= 5^1 * 3^1 * 2^2 \),
高度合成数具有这样的性质,我归纳的,如有错,欢迎指正。
1.所有的指数 e1,e2,e3, en等, 必须大于等于1, 即中间的某个素因子的指数不能为0, 或者说,指数必须是连续的。不可能有素因子2,3,7,但没有素因子5的情况。
2.若 j>i,  则  \( e_j<= e_i \), 即大的素因子,其指数一定不超过小的素因子的指数。
3.最大的素因子的指数是1

知道了这个规律,编程就相对容易了。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2019-4-17 17:45:48 | 显示全部楼层
我用的笨办法是建立高合成数表,查找得。
1024*243*125*49*121*13*17*19*23*29*31*37*41*43*47*53*59*61*67*71*73*79*83
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2019-4-17 18:41:31 | 显示全部楼层
这应该属于凸规划问题。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2019-4-17 19:19:51 | 显示全部楼层
编了个程序查了下,最佳答案是 83*79*73*71*67*61*59*53*47*43*41*37*31*29*23*19*17*13*(11^2)*(7^3)*(5^3)*(3^5)*(2^7), 总共 603979776因子
程序的速度非常快,不到1秒。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2019-4-17 19:22:48 | 显示全部楼层
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>

  4. typedef struct _node
  5. {
  6.         double logp;        // log(p)
  7.         double logn;        // 高度合成数的对数,是累加的
  8.         int e;                        // 指数
  9.         double fn;                // 因子总数,
  10. }NODE;

  11. #define MAX_D        32                //最大深度为32,最大可查找具有32个素因子的高度合成数

  12. //前32个素数
  13. const int sp[MAX_D]=
  14. {
  15.         2, 3, 5, 7, 11, 13, 17, 19,
  16.         23, 29, 31, 37, 41, 43, 47, 53,
  17.         59, 61, 67, 71, 73, 79, 83, 89,
  18.         97, 101, 103, 107, 109, 113, 127, 131
  19. };

  20. // 更新 arr[n], arr[n-1], 直到arr[1]
  21. void init( NODE arr[], int n )
  22. {
  23.         int i;
  24.         for (i=n;i>=1;i--)
  25.         {
  26.                 arr[i].logp= log( (double)sp[i-1]);         arr[i].e=1;
  27.                 if (i==n)
  28.                 {
  29.                         arr[i].logn=  arr[i].logp * arr[i].e;
  30.                         arr[i].fn   = arr[i].e+1;
  31.                 }
  32.                 else
  33.                 {
  34.                         arr[i].logn=  arr[i+1].logn + (arr[i].logp * arr[i].e);  // arr[1].logn 就是这个数的对数
  35.                         arr[i].fn  =  arr[i+1].fn * (arr[i].e+1);                                //这个累计的,arr[1].fn就是这个数的所有因子数
  36.                 }
  37.         }
  38. }



  39. // arr[pos].e++;
  40. // arr[j].e= arr[pos].e  (  1<=j<pos)
  41. // 进位不溢出,返回true, 否则返回false
  42. // m 为最大查找深度
  43. bool carry( NODE arr[], int pos , int m, double maxLogN)
  44. {
  45.         while (1)
  46.         {
  47.                 if ( pos==m)   //不能在最高位做进位,因为最高位的指数必须是1,若超过1,则搜索结束
  48.                         return false;

  49.                 arr[pos].e++;
  50.                 arr[pos].logn = arr[pos+1].logn + (arr[pos].logp * arr[pos].e);
  51.                 arr[pos].fn   = arr[pos+1].fn * (arr[pos].e+1);

  52.                 for (int i=pos-1;i>=1;i--)
  53.                 {
  54.                         arr[i].e    = arr[pos].e;
  55.                         arr[i].logn = arr[i+1].logn + (arr[i].logp * arr[i].e);        // arr[1].logn 就是这个数的对数
  56.                         arr[i].fn   = arr[i+1].fn * (arr[i].e+1);                                //这个累计的,arr[1].fn就是这个数的所有因子数
  57.                 }
  58.                
  59.                 if ( arr[1].logn < maxLogN )
  60.                         break;
  61.                 pos++;  // 在arr[pos]处做进位失败,继续在更高位上做进位
  62.         }
  63.         return true;
  64. }


  65. void saveResult(NODE arr[], int eArr[], int m, double *pMaxFac)
  66. {
  67.         if ( arr[1].fn > *pMaxFac)
  68.         {
  69.                 for (int j=1;j<=m;j++)
  70.                         eArr[j]=arr[j].e;  //保存结果
  71.                 *pMaxFac= arr[1].fn;
  72.         }
  73. }

  74. void print_factor_list(int eArr[], int m )
  75. {
  76.         double fac=1.0; //因子数
  77.         printf("\n");
  78.         for (int i=m;i>=1;i--)
  79.         {
  80.                 fac *= (eArr[i]+1.0);
  81.                 if (  eArr[i]==1)
  82.                         printf("%d",sp[i-1]);
  83.                 else
  84.                         printf("(%d^%d)", sp[i-1], eArr[i]);
  85.                 if ( i>1)
  86.                         printf("*");
  87.         }
  88.         printf(",%lf factor\n",fac);
  89. }

  90. // 查找高度合成数
  91. // eArr为各个素因子的指数,m为查找深度,返回最佳搜索结果的因子的个数,eArr[]存放因子
  92. // arr[0]和eArr[0]不使用
  93. double search_HCN( NODE arr[], int eArr[], double maxLogN, int m )
  94. {
  95.         double maxFac=0.0;        // 最大因子数

  96.         init(arr,m);
  97.         if ( arr[1].logn<maxLogN)  //第一个搜索的组合就超范围,返回0.0
  98.                 saveResult(arr, eArr, m, &maxFac);                       
  99.         else
  100.         {
  101.                 for (int i=1;i<=m;i++)
  102.                         eArr[i]=0;
  103.                 return 0.0;
  104.         }


  105.         while (1)
  106.         {
  107.                 // 将arr[1].e增加
  108.                 arr[1].e++;
  109.                 arr[1].logn = arr[2].logn + (arr[1].logp * arr[1].e);        // arr[1].logn 就是这个数的对数
  110.                 arr[1].fn   = arr[2].fn * (arr[1].e+1);       
  111.                
  112.                 if (arr[1].logn <  maxLogN)
  113.                         saveResult(arr, eArr, m, &maxFac);        //保存结果
  114.                 else
  115.                 {
  116.                         if ( carry( arr, 2, m, maxLogN) )  //进位成功
  117.                                 saveResult(arr, eArr, m, &maxFac);       
  118.                         else
  119.                                 break;        //进位失败,所有搜索完成
  120.                 }
  121.         }
  122.         return maxFac; //返回最大因子个数
  123. }

  124. void test_search_hcn()
  125. {
  126.         NODE arr[MAX_D+1] ;  
  127.         int eArr[MAX_D];

  128.         double logMaxN= log(2.0) + log(10.0)*40;  //高度合查成数的对数不能超过max
  129.         double sum;
  130.         int i,maxDeep;  //最大查找深度
  131.        
  132.         for (sum=0.0,i=0;i<MAX_D;i++)
  133.         {
  134.                 sum += log( (double)(sp[i]));
  135.                 if (sum<logMaxN)
  136.                         maxDeep=i+1;
  137.                 else
  138.                         break;
  139.         }

  140.         for (int m=maxDeep; m>=2;m--)        //查找素因子个数为m,m-1,..,3,2的情况下的高度合成数
  141.         {
  142.                 search_HCN( arr, eArr, logMaxN, m );
  143.                 print_factor_list(eArr,m);
  144.         }
  145. }

  146. int main(int argc, char* argv[])
  147. {
  148.         test_search_hcn();
  149.         return 0;
  150. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2019-4-17 20:07:00 | 显示全部楼层
5#的第三个条件,理由不充分。去掉。
修改后的代码如下:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>

  4. typedef struct _node
  5. {
  6.         double logp;        // log(p)
  7.         double logn;        // 高度合成数的对数,是累加的
  8.         int e;                        // 指数
  9.         double fn;                // 因子总数,
  10. }NODE;

  11. #define MAX_D        32                //最大深度为32,最大可查找具有32个素因子的高度合成数

  12. //前32个素数
  13. const int sp[MAX_D]=
  14. {
  15.         2, 3, 5, 7, 11, 13, 17, 19,
  16.         23, 29, 31, 37, 41, 43, 47, 53,
  17.         59, 61, 67, 71, 73, 79, 83, 89,
  18.         97, 101, 103, 107, 109, 113, 127, 131
  19. };

  20. // 更新 arr[n], arr[n-1], 直到arr[1]
  21. void init( NODE arr[], int n )
  22. {
  23.         int i;
  24.         for (i=n;i>=1;i--)
  25.         {
  26.                 arr[i].logp= log( (double)sp[i-1]);         arr[i].e=1;
  27.                 if (i==n)
  28.                 {
  29.                         arr[i].logn=  arr[i].logp * arr[i].e;
  30.                         arr[i].fn   = arr[i].e+1;
  31.                 }
  32.                 else
  33.                 {
  34.                         arr[i].logn=  arr[i+1].logn + (arr[i].logp * arr[i].e);  // arr[1].logn 就是这个数的对数
  35.                         arr[i].fn  =  arr[i+1].fn * (arr[i].e+1);                                //这个累计的,arr[1].fn就是这个数的所有因子数
  36.                 }
  37.         }
  38. }


  39. // arr[pos].e++;
  40. // arr[j].e= arr[pos].e  (  1<=j<pos)
  41. // 进位不溢出,返回true, 否则返回false
  42. // m 为最大查找深度
  43. bool carry( NODE arr[], int pos , int m, double maxLogN)
  44. {
  45.         while (1)
  46.         {
  47.                 if ( pos>m)               
  48.                         return false;

  49.                 arr[pos].e++;
  50.                 if ( pos<m)
  51.                 {
  52.                         arr[pos].logn = arr[pos+1].logn + (arr[pos].logp * arr[pos].e);
  53.                         arr[pos].fn   = arr[pos+1].fn * (arr[pos].e+1);
  54.                 }
  55.                 else // pos==m
  56.                 {
  57.                         arr[pos].logn =  (arr[pos].logp * arr[pos].e);
  58.                         arr[pos].fn   =  (arr[pos].e+1);
  59.                 }

  60.                 for (int i=pos-1;i>=1;i--)
  61.                 {
  62.                         arr[i].e    = arr[pos].e;
  63.                         arr[i].logn = arr[i+1].logn + (arr[i].logp * arr[i].e);        // arr[1].logn 就是这个数的对数
  64.                         arr[i].fn   = arr[i+1].fn * (arr[i].e+1);                                //这个累计的,arr[1].fn就是这个数的所有因子数
  65.                 }
  66.                
  67.                 if ( arr[1].logn < maxLogN )
  68.                         break;
  69.                 pos++;  // 在arr[pos]处做进位失败,继续在更高位上做进位
  70.         }
  71.         return true;
  72. }


  73. void saveResult(NODE arr[], int eArr[], int m, double *pMaxFac)
  74. {
  75.         if ( arr[1].fn > *pMaxFac)
  76.         {
  77.                 for (int j=1;j<=m;j++)
  78.                         eArr[j]=arr[j].e;  //保存结果
  79.                 *pMaxFac= arr[1].fn;
  80.         }
  81. }

  82. void print_factor_list(int eArr[], int m )
  83. {
  84.         double fac=1.0; //因子数
  85.         printf("\n");
  86.         for (int i=m;i>=1;i--)
  87.         {
  88.                 fac *= (eArr[i]+1.0);
  89.                 if (  eArr[i]==1)
  90.                         printf("%d",sp[i-1]);
  91.                 else
  92.                         printf("(%d^%d)", sp[i-1], eArr[i]);
  93.                 if ( i>1)
  94.                         printf("*");
  95.         }
  96.         printf(",%lf factor\n",fac);
  97. }

  98. // 查找高度合成数
  99. // eArr为各个素因子的指数,m为查找深度,返回最佳搜索结果的因子的个数,eArr[]存放因子
  100. // arr[0]和eArr[0]不使用
  101. double search_HCN( NODE arr[], int eArr[], double maxLogN, int m )
  102. {
  103.         double maxFac=0.0;        // 最大因子数

  104.         init(arr,m);
  105.         if ( arr[1].logn<maxLogN)  //第一个搜索的组合就超范围,返回0.0
  106.                 saveResult(arr, eArr, m, &maxFac);                       
  107.         else
  108.         {
  109.                 for (int i=1;i<=m;i++)
  110.                         eArr[i]=0;
  111.                 return 0.0;
  112.         }


  113.         while (1)
  114.         {
  115.                 // 将arr[1].e增加
  116.                 arr[1].e++;
  117.                 arr[1].logn = arr[2].logn + (arr[1].logp * arr[1].e);        // arr[1].logn 就是这个数的对数
  118.                 arr[1].fn   = arr[2].fn * (arr[1].e+1);       
  119.                
  120.                 if (arr[1].logn <  maxLogN)
  121.                         saveResult(arr, eArr, m, &maxFac);        //保存结果
  122.                 else
  123.                 {
  124.                         if ( carry( arr, 2, m, maxLogN) )  //进位成功
  125.                                 saveResult(arr, eArr, m, &maxFac);       
  126.                         else
  127.                                 break;        //进位失败,所有搜索完成
  128.                 }
  129.         }
  130.         return maxFac; //返回最大因子个数
  131. }

  132. void test_search_hcn()
  133. {
  134.         NODE arr[MAX_D+1] ;  
  135.         int eArr[MAX_D];

  136.         double logMaxN= log(2.0) + log(10.0)*40;  //高度合查成数的对数不能超过max
  137.         double sum;
  138.         int i,maxDeep;  //最大查找深度
  139.        
  140.         for (sum=0.0,i=0;i<MAX_D;i++)
  141.         {
  142.                 sum += log( (double)(sp[i]));
  143.                 if (sum<logMaxN)
  144.                         maxDeep=i+1;
  145.                 else
  146.                         break;
  147.         }

  148.         for (int m=maxDeep; m>=2;m--)        //查找素因子个数为m,m-1,..,3,2的情况下的高度合成数
  149.         {
  150.                 search_HCN( arr, eArr, logMaxN, m );
  151.                 print_factor_list(eArr,m);
  152.         }
  153. }

  154. int main(int argc, char* argv[])
  155. {
  156.         test_search_hcn();
  157.         return 0;
  158. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

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

GMT+8, 2024-4-27 07:22 , Processed in 0.169190 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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