添加依賴
<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]
不過這種也有侷限性,需要我們在實際使用中根據你的結果來調整。