添加依赖
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-math3</artifactId> <version>3.6.1</version> </dependency>
它的原理是Newton-Raphson算法,又叫做牛顿-拉裴森(Newton-Raphson)方法,是一维求根方法中最著名的一种。其特点是在计算时需要同时计算函数值与其一阶导数值,从几何上解释,牛顿法是将当前点处的切线延长,使之与横轴相交,然后把交点处值作为下一估值点。
从数学上解释,牛顿法可以从函数的泰勒展开得到。𝑓(𝑥)f(x)的泰勒展开可以表示为:
𝑓(𝑥+𝛿)=𝑓(𝑥)+𝑓′(𝑥)𝛿+𝑓″(𝑥)2𝛿2+𝑂(𝛿3)f(x+δ)=f(x)+f′(x)δ+f″(x)2δ2+O(δ3)
对于足够小的𝛿δ,可以将只保留上式右端关于的一阶项,得到:
𝛿=−𝑓(𝑥)𝑓′(𝑥)δ=−f(x)f′(x)
于是得到由到的递推公式:
𝑥𝑖+1=𝑥𝑖+𝛿=𝑥𝑖−𝑓(𝑥𝑖)𝑓′(𝑥𝑖)xi+1=xi+δ=xi−f(xi)f′(xi)
可见牛顿法是让𝑥x沿着𝑓(𝑥)f(x)梯度的方向下降,类似于最优化方法中的梯度下降法。牛顿法也可以作为最优化算法,只不过那时需要求函数的二阶导数。
public class MathMain { public static void main(String[] args) { double[] d = new double[]{6.0,-5.0,1.0}; UnivariateDifferentiableFunction function = new PolynomialFunction(d); System.out.println(function); UnivariateDifferentiableSolver solver = new NewtonRaphsonSolver(); List<Double> res = new ArrayList<>(); double solusion = solver.solve(10, function, 0); res.add(solusion); solusion++; solusion = solver.solve(10, function, solusion); res.add(solusion); System.out.println(res); } }
运行结果
6 - 5 x + x^2
[2.0000000000000004, 2.9999999999999996]
不过这种也有局限性,需要我们在实际使用中根据你的结果来调整。