找回密码
 欢迎注册
楼主: nyy

[求助] 如何高效产生本原勾股数组?

[复制链接]
发表于 2023-12-9 15:45:57 | 显示全部楼层
Reap+Sow还可以再快上一点点:

  1. Clear["Global`*"];(*清除所有变量*)
  2. Timing[max=2*10^6;
  3. SortBy[Sort/@Reap[Do[If[GCD[m,n]==1&&OddQ@(n+m),Sow@{m^2-n^2,2m n,m^2+n^2}],{n,(Sqrt[2max-1]-1)/2},{m,Range[n+1,Sqrt[max-n^2]]}]][[2,1]],Last]]
复制代码

点评

nyy
运行时间1.87201,我的代码比你快零点几秒(当然是建立在你的基础上的)  发表于 2023-12-11 09:08
nyy
讨厌层层嵌套的代码  发表于 2023-12-9 21:38
nyy
这个没看懂。我现在知道我起初写的代码多低消了  发表于 2023-12-9 21:35
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2023-12-11 09:00:40 | 显示全部楼层
northwolves 发表于 2023-12-9 15:34
这个还可以快上几倍,勾股数组的斜边的通项公式

ClearAll["Global`*"];(*清除所有变量*)

我发现你比我牛逼。
sortby比sort排序要快很多!
我今天才知道
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2023-12-11 09:06:11 | 显示全部楼层
northwolves 发表于 2023-12-9 15:34
这个还可以快上几倍,勾股数组的斜边的通项公式

ClearAll["Global`*"];(*清除所有变量*)
  1. Clear["Global`*"];(*清除所有变量*)
  2. Timing[
  3.     max=2*10^6;(*边长的最大值*)
  4.     jmax=-1+Sqrt[-1+max];(*由j^2+(j+2)^2<=2*max计算出j的最大值*)
  5.     aa=Flatten[#,1]&@Table[Sort@{(i*j),(i^2-j^2)/2,(i^2+j^2)/2},(*生成勾股数组,并排序*)
  6.                            {j,1,jmax,2},(*指定j的范围*)
  7.                            {i,Select[Range[j+2,Sqrt[2*max-j^2],2],GCD[j,#]==1&]}(*指定i的范围*)
  8.                           ];
  9.     bb=SortBy[aa,Last](*按照第三列升序排列,SortBy排序比Sort快很多,原因不知道*)
  10. ]
复制代码


比你的代码快一点点,零点几秒吧

点评

nyy
代码运行时间1.51321,bb结果的数组维度{318320, 3}  发表于 2023-12-11 09:07
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2023-12-11 09:11:06 | 显示全部楼层
northwolves 发表于 2023-12-9 15:45
Reap+Sow还可以再快上一点点:

不知道能不能用Compile,这个也许能编译成c语言,然后更快

点评

nyy
ParallelCombine::nopar: No parallel kernels available; proceeding with sequential evaluation.我的似乎并行不了  发表于 2023-12-11 09:15
nyy
Parallelization并行应该也能增加速度  发表于 2023-12-11 09:11
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2023-12-14 16:49:22 | 显示全部楼层
本帖最后由 chyanog 于 2023-12-14 16:55 编辑
  1. cf = Compile[{{max, _Integer}},
  2.    Module[{jmax, bag},
  3.     bag = Internal`Bag[Most@{0}];
  4.     jmax = Sqrt[max - 1] - 1;
  5.     Do[If[GCD[j, i] == 1,
  6.       Internal`StuffBag[bag, Floor@{i j, (i^2 - j^2)/2, (i^2 + j^2)/2}, 1]],
  7.     {j, 1, jmax, 2},
  8.     {i, j + 2, Sqrt[2 max - j^2], 2}];
  9.     Partition[Internal`BagPart[bag, All], 3]
  10.     ]
  11.    ];
  12. ans = SortBy[Sort /@ cf[2 10^6], Last]; // AbsoluteTiming
  13. Length[ans]
复制代码
{0.305319, Null}

318320

点评

nyy
你这个快的原因是什么?COMPile?  发表于 2023-12-14 21:37
nyy
能上一点注释不?没做事不容易看明白  发表于 2023-12-14 17:17

评分

参与人数 1威望 +8 金币 +8 贡献 +8 经验 +8 鲜花 +8 收起 理由
northwolves + 8 + 8 + 8 + 8 + 8 赞一个!

查看全部评分

毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2023-12-14 20:39:26 | 显示全部楼层

Internal`Bag是什么意思?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2023-12-15 09:01:54 | 显示全部楼层
  1. Clear["Global`*"];(*清除所有变量*)
  2. cf=Compile[{{max, _Integer}},
  3.     Module[{jmax,aa,i,j},(*指定局部变量*)
  4.         jmax=-1+Sqrt[-1+max];(*由j^2+(j+2)^2<=2*max计算出j的最大值*)
  5.         aa=Flatten[#,1]&@Table[Sort@{(i*j),(i^2-j^2)/2,(i^2+j^2)/2},(*生成勾股数组,并排序*)
  6.                                {j,1,jmax,2},(*指定j的范围*)
  7.                                {i,Select[Range[j+2,Sqrt[2*max-j^2],2],GCD[j,#]==1&]}(*指定i的范围*)
  8.                               ]
  9.     ]
  10. ]
  11. bb=SortBy[cf[2*10^6],Last]// AbsoluteTiming;(*按照第三列升序排列,SortBy排序比Sort快很多,原因不知道*)
复制代码


我的代码错在什么地方?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2023-12-21 11:30:21 | 显示全部楼层
nyy 发表于 2023-12-8 13:42
把你的代码肢解一下,并且添加上注释,这样更容易看明白、更好维护

...

{93,476,485},{44,483,485}
这两组都是本原勾股数,但是排序有问题。
应该是{44,483,485}在{93,476,485}的前面
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

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

GMT+8, 2024-11-21 18:03 , Processed in 0.023985 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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