网页资讯视频图片知道文库贴吧地图采购
进入贴吧全吧搜索

 
 
 
日一二三四五六
       
       
       
       
       
       

签到排名:今日本吧第个签到,

本吧因你更精彩,明天继续来努力!

本吧签到人数:0

一键签到
成为超级会员,使用一键签到
一键签到
本月漏签0次!
0
成为超级会员,赠送8张补签卡
如何使用?
点击日历上漏签日期,即可进行补签。
连续签到:天  累计签到:天
0
超级会员单次开通12个月以上,赠送连续签到卡3张
使用连续签到卡
10月15日漏签0天
mathematica吧 关注:20,006贴子:74,360
  • 看贴

  • 图片

  • 吧主推荐

  • 游戏

  • 10回复贴,共1页
<<返回mathematica吧
>0< 加载中...

不同质数因子NestWhile的改善

  • 只看楼主
  • 收藏

  • 回复
  • situxuming
  • 小吧主
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
Project Euler上第47道题目,链接如下:
http://projecteuler.net/problem=47
最小的两个具有两个不同质数因子的连续整数是:
14 = 2 7
15 = 3 5
最小的三个具有三个不同质数因子的连续整数是:
644 = 2^2 7 23
645 = 3 5 43
646 = 2 17 19.
找出最小的四个具有四个不同质数因子的整数。它们之中的第一个是多少?
******************************************************************************
最容易想到的是用NestWhile,自己写的程序如下:
NestWhile[{Length@FactorInteger[#[[2]] + 1], #[[2]] + 1} &, {2, 209}, (#1[[1]] != 4 || #2[[1]] != 4 || #3[[1]] != 4 || #4[[1]] != 4) &, 4]
运行时间:1.36 sec
***********************************************************************
然后看到直接有内部函数PrimeNu可以算不同质数因子的个数,就改了下:
NestWhile[{PrimeNu[#[[2]] + 1], #[[2]] + 1} &, {2, 209}, (#1[[1]] != 4 || #2[[1]] != 4 || #3[[1]] != 4 || #4[[1]] != 4) &, 4]
结果运行时间变为: 3.9 sec,
慢了3倍。
Trace看了一下,慢的原因是PrimeNu会有一系列的判断过程,不像Length@FactorInteger这般直接。
***************************************************************************
然后在这道题的Forum上看到有人贴出下面NestWhile版本:
NestWhile[# + 1 &, 209, ! (And @@ Thread[4 == Length /@ FactorInteger[# + {0, 1, 2, 3}]]) &]
运行时间是: 3.32 sec
推测这个慢的原因是,相比我自己写的Nest程序,每一次Nest运算,后面的判断都要进行较多的计算
这原因是从下面的改写得到的:
NestWhile[# + 1 &, 209, ! ({4, 4, 4, 4} === Length /@ FactorInteger[# + {0, 1, 2, 3}]) &]
后面的判断减少了计算,运行时间提高到2.85sec
********************************************************************************
但这里最快的却是While循环:
(a = 210; While[Length@FactorInteger[a] != 4 || Length@FactorInteger[a + 1] != 4 || Length@FactorInteger[a + 2] != 4 || Length@FactorInteger[a + 3] != 4, a++]; a)
运行时间:0.81 sec
*********************************************************************************
For循环最慢:
(For[i = 1, Not[{4, 4, 4, 4} === Length /@ FactorInteger[i + {0, 1, 2, 3}]], i++]; i)
2.76 sec
如果Length/
@FactorInteger替换成PrimeNu,时间突增到13s。足见,并不是任何内部函数都比自己编的函数要有效率的。。
。记得之前 @xzcyr 好像也发过一个帖子,是说怎么让NestWhile快过While,现在找不到了~
对于这个具体问题,MMA函数式编程有什么改善的方法,使得其运行效率比单纯While循环快?


  • 草红样
  • 小吧主
    9
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
“For循环最慢”其实不太恰当的,要比较的话,要保持一致性,不仅仅是算法,还有写法,这样写的话,For和While的速度几乎一样
(For[i = 1, Length@FactorInteger[i] != 4 || Length@FactorInteger[i + 1] != 4 || Length@FactorInteger[i + 2] != 4 || Length@FactorInteger[i + 3] != 4, i++]; i) // AbsoluteTiming


2026-10-15 00:13:33
广告
不感兴趣
开通SVIP免广告
  • 草红样
  • 小吧主
    9
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
下面几个用NestWhile的速度快了一点(其实是等价的),但比While还是慢了些,
NestWhile[(# + 1) &, 0,
Length@FactorInteger[#] != 4 || Length@FactorInteger[# + 1] != 4 ||
Length@FactorInteger[# + 2] != 4 ||
Length@FactorInteger[# + 3] != 4 &] // AbsoluteTiming
NestWhile[(# + 1) &, 0,
Evaluate[Or @@ Table[fun[# + i] != 4, {i, 0, 3}]] & /.
fun :> Composition[Length, FactorInteger]] // AbsoluteTiming
NestWhile[(# + 1) &, 0,
Evaluate[ Or @@ Table[ With[{j = i}, Hold@Length@FactorInteger[# + j] != 4], {i, 0, 3}]] & // ReleaseHold] // AbsoluteTiming


  • xzcyr
  • 吧主
    15
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
咦,我发过讨论NestWhile和While的帖吗……我自己都不记得了……搜一搜也只有这帖九楼搭点边的,是草红样讨论的……:
http://tieba.baidu.com/p/2052726090


登录百度账号

扫二维码下载贴吧客户端

下载贴吧APP
看高清直播、视频!
  • 贴吧页面意见反馈
  • 违规贴吧举报反馈通道
  • 贴吧违规信息处理公示
  • 10回复贴,共1页
<<返回mathematica吧
分享到:
©2026 Baidu贴吧协议|隐私政策|吧主制度|意见反馈|网络谣言警示