计算勾股数
mathematica吧
全部回复
仅看楼主
level 8
m= 200;
Cases[Flatten[Table[{a, b, c}, {a, m}, {b, a, m}, {c, b, m}], 2],
{a_, b_, c_} /; a^2 + b^2 == c^2] // Timing
这段代码怎么运行这么慢呢,同样的算法比python都慢好多,
8.0好像能编译,不知道怎么写?
2012年12月01日 12点12分 1
level 10
编译后提高也不大
equalQ = Compile[{{a, _Integer}, {b, _Integer}, {c, _Integer}}, a^2 + b^2 == c^2, CompilationTarget -> "C"];m = 200;Select[Flatten[Table[{a, b, c}, {a, m}, {b, a, m}, {c, b, m}], 2], equalQ @@ # &]; // Timing
2012年12月01日 13点12分 3
原来要对整个进行编译提高才会大
2012年12月02日 10点12分
关注我在14楼的回复……
2012年12月03日 06点12分
level 10
ReplaceList[
Range[200], {___, a_, ___, b_, ___,
c_, ___} /; (a^2 + b^2 == c^2) :> {a, b, c}] // Timing
这个纯模式匹配都比Solve快[揉脸]
2012年12月01日 13点12分 4
[Love]好Neat啊,赞!!!
2012年12月01日 13点12分
回复 mm_酱 :[大笑]mma果然比较符合人的思维
2012年12月02日 02点12分
level 10
用Do的话会提速1s多
2012年12月02日 02点12分 5
吧务
level 15
[哈哈]cckinger的耗时8s多,我这个5s多:
Sqrt@Select[Subsets[Range[200]^2, {3}],
#[[1]] + #
[[2]] == #[[3]] &] // AbsoluteTiming
2012年12月02日 03点12分 6
Solve和Reduce是最慢的,上面那个模式匹配其次,Subsets比楼主的Flatten+Table快,但最快的还是Do[大笑] Last@Reap@ Do[If[i^2 + j^2 == k^2, Sow@{i, j, k}], {i, 200}, {j, i + 1, 200}, {k, j, 200}] // Timing
2012年12月02日 04点12分
回复 cckinger :我这里Do用了5.599,Subsets用了5.346……你用AbsoluteTiming再测一次看看?(现在都是多核的电脑,Timing已经不准了。)
2012年12月02日 04点12分
回复 xzcyr :哈哈,你看我下面的截图
2012年12月02日 04点12分
level 10
[吐舌]
2012年12月02日 04点12分 7
这神马情况!!!
2012年12月02日 04点12分
在运行每个式子前先清下变量试试?
2012年12月02日 04点12分
回复 xzcyr :我还有一个超快的方法,不过按楼主的算法要求,可能违规[揉脸] Last@Reap@ Do[If[IntegerQ[Sqrt[i^2 + j^2]] && Sqrt[i^2 + j^2] <= 200, Sow@{i, j, Sqrt[i^2 + j^2]}], {i, 200}, {j, i + 1, 200}] // AbsoluteTiming
2012年12月02日 04点12分
[啊!]
2012年12月02日 04点12分
level 10
看这个怎么样
xxx = Range[200]^2; yyy = Table[{i, j}, {i, 1, 200}, {j, i, 200}]~Flatten~1; Cases[Map[(temp = Total[#^2]; If[MemberQ[xxx, temp], Append[#, Sqrt[temp]], 0]) &, yyy], _List] // Timing
2012年12月02日 04点12分 8
在我的机器上是0.655204
2012年12月02日 04点12分
回复 mm_酱 :在我的机器上AbsoluteTiming是0.9478。
2012年12月02日 05点12分
吧务
level 15
我抓到重点了!:
Select[Append[
#, Norm@#
] & /@ Subsets[Range[200], {2}], IntegerQ[
#[[3]]] && (#
[[3]] < 200) &] // AbsoluteTiming
不过这个还是比Do的那个慢了0.1s的样子。(Do的那个0.485,我这个0.59。)
2012年12月02日 05点12分 9
[鼓掌]我喜欢这个,比用Do循环看着舒服多了
2012年12月02日 05点12分
level 7
在mm酱的基础上改改,我机器上是0.515625
2012年12月02日 05点12分 10
xxx = Range[200]^2;[$1]yyy = Flatten[Table[{i, j, Sqrt[i^2 + j^2]}, {i, 200}, {j, i, 200}], [$1] 1];[$1]a = Select[yyy, MemberQ[xxx, #[[3]]^2] &] // Timing
2012年12月02日 05点12分
回复 xiaoruilin0507 :我这边AbsoluteTiming是0.679
2012年12月02日 06点12分
吧务
level 9
ggs[max_] := {x, y, Sqrt[x^2 + y^2]} /. Table[ToRules@Reduce[x^2 + y^2 == z^2 && 0 < x <= y <= max, {x, y}, Integers], {z, max}];
ggs[1000] // Timing
这个方法也很快,当范围小的时候不明显,范围一大就有优势了
2012年12月02日 06点12分 11
ggs[200] // AbsoluteTiming,0.9672……
2012年12月02日 06点12分
回复 xzcyr :范围增加到500以上的时候就速度就比其他快了
2012年12月02日 06点12分
回复 草红样 :[啊!]真的!1000的时候这个才4秒,我的要15秒!
2012年12月02日 07点12分
顺便Do的那个要11秒多,xxx修改版用了71.9……在求解范围较大的情况下,各自的效率完全不是一回事啊[拍砖]。
2012年12月02日 07点12分
level 8
谢谢大家的热情帮助
2012年12月02日 06点12分 12
level 7
@ mm_酱 吧主,我觉得这个贴要加精。这么多种方法做同一个问题!
2012年12月02日 06点12分 13
2012年12月02日 06点12分
回复 xiaoruilin0507 :@mm_酱
2012年12月02日 06点12分
回复 xiaoruilin0507 :加精的速度还挺快。吧主v5
2012年12月02日 06点12分
吧务
level 9
ggs = Compile[{{m, _Integer}},
Do[If[i^2 + j^2 == k^2, Print[i, j, k]],
{i, m}, {j, i, m}, {k, j, m}],
CompilationTarget -> "C" ];
ggs[500] // Timing
这个方法才够快,但是我没找到让他返回List的方法,大家帮忙看看
2012年12月02日 08点12分 14
ggs = Compile[{{m, _Integer}}, Do[If[i^2 + j^2 == k^2, Sow@{i, j, k}], {i, m}, {j, i, m}, {k, j, m}], CompilationTarget -> "C"]; ggs[200] // Reap // Last // Timing
2012年12月02日 08点12分
测试1000的时候也是3s多额[啊?]
2012年12月02日 08点12分
回复 cckinger :嗯,不过个人更推荐这个方法,Reduce那个总有些阴差阳错的感觉[吐舌]
2012年12月02日 08点12分
回复 cckinger :再加个选项,RuntimeOptions -> "Speed",速度又提升了10倍
2012年12月02日 08点12分
level 8
如果用Select,能编译码,Flatten好像不能编译啊
2012年12月02日 09点12分 15
关注我在14楼的回复……
2012年12月03日 06点12分
吧务
level 9
有图有真相
2012年12月03日 07点12分 17
吧务
level 15
要使用Compile还要装个C语言什么的吗……:
2012年12月03日 08点12分 18
是啊,看提示信息你的电脑上确实没设置好,可以安装VC或者GCC,然后再在Mma里面设置, 不过VS太大了,安装也慢,个人更推荐GCC,小巧但不失强大
2012年12月03日 08点12分
回复 草红样 :说小巧也有60几兆呢……啊……这栋楼里只有我一个不会C语言的吗?
2012年12月03日 08点12分
回复 xzcyr :没有,20M左右而已,免安装,解压并环境变量后就能用
2012年12月03日 08点12分
2012年12月03日 08点12分
level 10
有个想过从数学的角度优化么?一组勾股数有些什么性质?能不能用来减少搜索次数?
2012年12月03日 11点12分 27
比如可以先求出没有大于1公约数的勾股数,然后其他的可以按比例得到?
2012年12月03日 12点12分
回复 mm_酱 :直觉上得用质数相关理论啊…………我不会……
2012年12月03日 14点12分
level 9
用do做的话还可以用并行来算
m = 200;
SetSharedFunction[f];
ParallelDo[
If[a^2 + b^2 == c^2, f@a = {a, b, c}], {a, m}, {b, a + 1, m}, {c,
IntegerPart[Sqrt[a^2 + b^2]], m}]; // AbsoluteTiming
result = Union[Table[If[IntegerQ[f[a][[2]]], f@a], {a, m}]]
out {0.6600378, Null}
m = 200;
SetSharedFunction[f]
ParallelDo[
If[(i^2 + j^2)^(1/2) <= m && IntegerQ@((i^2 + j^2)^(1/2)),
f@i = {i, j, (i^2 + j^2)^(1/2)};], {i, m}, {j, i,
m}] // AbsoluteTiming
Union[Table[If[IntegerQ[f[i][[2]]], f@i], {i, m}]]
out {0.2340134, Null}
2012年12月04日 11点12分 31
吧务
level 11
Do可以并行,Table也是可以并行的,11楼那个Reduce的方法就Table改成了ParallelTable,然后运行1000,嗯,效率提升不小。当然我电脑上是4核的

2012年12月06日 05点12分 32
1 2 尾页