BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / acm-icpc / #1950同步于 2006/7/24
该镜像源已超过 30 天没有更新,可能在源站已被删除。
ACM_ICPC机器人发帖

[求助]有关于牛顿迭代法初值的选择问题:POJ1905

linandmin
2006/7/24镜像同步0 回复
用牛顿迭代法解方程,理论上初值可以是任意值。但是如果初值选得好,收敛得就快。这在做POJ1905时得到了充分的体现。我任选一个初值,结果是TLE;我用了Discuss中的一个初值,结果0MS。我不明白的地方是,为什么他选的那个初值能达到0MS的效果呢?附代码如下: AC,且0MS的代码: #include<stdio.h> #include<iostream> #include<math.h> using namespace std; double LL,L; double f(double r) { return sin(LL/(2*r))-L/(2*r); } double fp(double r) { return -cos(LL/(2*r))*LL/(2*r*r)+L/(2*r*r); } int main() { double n,c,ans,r,temp; while(scanf("%lf%lf%lf",&L,&n,&c)) { if(L==-1 && n==-1 && c==-1) break; if(L==0 || n==0 || c==0) { printf("0.000\n"); continue; } LL=(1+n*c)*L; r =LL * LL * 0.25 / sqrt(LL * LL - L * L);//初值的选择在这 do { temp=r; r=r-f(r)/fp(r); }while(fabs(temp-r)>0.0000001); ans=r*(1-cos(LL/(2*r))); printf("%.3lf\n",ans); } return 0; } TLE的代码: #include<stdio.h> #include<iostream> #include<math.h> using namespace std; double LL,L; double f(double r) { return sin(LL/(2*r))-L/(2*r); } double fp(double r) { return -cos(LL/(2*r))*LL/(2*r*r)+L/(2*r*r); } int main() { double n,c,ans,r,temp; while(scanf("%lf%lf%lf",&L,&n,&c)) { if(L==-1 && n==-1 && c==-1) break; if(L==0 || n==0 || c==0) { printf("0.000\n"); continue; } LL=(1+n*c)*L; r =100;//代码的别的部分完全一样,就在这,初值的不一样,导 致不一样的结果 do { temp=r; r=r-f(r)/fp(r); }while(fabs(temp-r)>0.0000001); ans=r*(1-cos(LL/(2*r))); printf("%.3lf\n",ans); } return 0; } 谁能告诉我,为什么这么选择初值呢?
订阅后,新回复会通过你的通知中心匿名送达。
0 条回复
暂无回复 · 你可以订阅本帖等待新回复。