牛顿迭代法

可以参考这两篇博文,非常好:传送门   传送门

关于百度百科的解释:传送门

牛顿迭代法是在计算机编程领域广泛用来求解方程的算法。

我们每次枚举一个值X0,代入方程看是否为根,不是的话则将X0的值变为: 

X0=X0−F(X0)/F′(X0)

(其中F′(x)为F(x) 的导数)

比如要求出下面方程的一个根: 
F(x)=5x^3+4x^2+2


const double eps=1e-6;

double F(double x)
{
    return 5*x*x*x+4*x*x+2;
}
//F(x)的导函数
double F1(double x)
{
    return 15*x*x+8*x;
}

int newton(double x)
{
    while(fabs(F(x))>eps){
        x-=F(x)/F1(x);
    }
    return x;
}

如果想求出一个范围内的所有的跟,则可以在该范围内枚举初始值x,来逼近根的值。

对于ACM 竞赛,牛顿迭代最重要的应用还是在于其能用于求根号。

高精度开根号:

51nod 1166 
BZOJ 1213

对于该问题我们可以使用牛顿迭代+高精度除法,对于一个已知的数a,开根号本质上是求一个X0使得 X0^2=a,也就是求函数F(x)=x^2−a 的根 ,因为F′(x)=2x,故每次迭代,x的变化值为: x=x−(x^2−a)/(2*x)=(x+a/x)/2
所以再套一个高精度除法或者Java的BigInteger就好啦

//51Nod 1166
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class Main{
    public static void main(String[] args) throws Exception {
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                System.in), 1 << 16);
        String nStr = reader.readLine();
        BigDecimal n = new BigDecimal(nStr);
        BigDecimal ans = new BigDecimal(nStr.substring(0, nStr.length() / 2));
        BigDecimal tmp = BigDecimal.ONE;
        BigDecimal two = new BigDecimal("2");
        int length = 2;
        while(true){
            tmp = ans.add(n.divide(ans, length, RoundingMode.HALF_DOWN)).divide(two, length, RoundingMode.HALF_DOWN);
            if(tmp.subtract(ans).abs().compareTo(BigDecimal.ONE) == -1)
                break;
            ans = tmp;
        }
        String str = ans.toString();
        System.out.println(str.substring(0, str.length() - length - 1));
    }

}

二)底层优化 
虽然sqrt()sqrt() 已经很方便,但确实是存在比其更强大的手写算法,这个黑科技来自游戏雷神之锤3的源代码:(细节见末尾推荐文章)

int sqrt(float x) { 
    if(x == 0) return 0; 
    float result = x; 
    float xhalf = 0.5f*result; 
    int i = *(int*)&result; 
    i = 0x5f375a86- (i>>1); // what the fuck? 
    result = *(float*)&i; 
    result = result*(1.5f-xhalf*result*result); // Newton step, repeating increases accuracy 
    result = result*(1.5f-xhalf*result*result); 
    return 1.0f/result; 
}

黑科技来源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值