数值法解方程广泛应用于各种工程科学领域,它可以求出解的近似值,而对于高次方程没有求根公式,而且对于各种困难的方程,数值法就显得尤为重要。
我们的老师向我们介绍了“二分法”,这种方法虽也是数值解法,但是使用起来不仅繁琐,计算复杂,而且效率低下。相比之下,使用牛顿法就显得更好。
下面简要的介绍一下牛顿法:
(图片绘制的不太好,看得懂就行。。)
对于方程一元f(x)=0,设其中一个解为x0,寻找x0就是我们的任务。我们首先找一个在x0附近的解的估计值x1。
牛顿法的核心思想就是利用曲线f(x)在 x1 点的切线(即导数)来近似的替代方程左边复杂的f(x),由于直线与x轴的交点十分容易求得,所以很容易可以找出一个近似的原方程的解,然后将这个解作为新的x1,重复上述过程,得出的解就会越来越接近于真实情况。而且,在多数情况下,只要初始值不是给的相差太远,牛顿法的逼近速度是很快的,远远快于二分法。
根据这个方法,不难写出牛顿法的程序,下面给出这个程序:
效果:
程序如下:
(使用方法:将下代码写入记事本,另存为 .vbs 文件,文件名可以随意,若360误报属360技术问题。)
Dim x0, x1, x2, x3, m_expr, i, x, Res, der, s_expr
Function Limit (expr, point) '取极限的近似值
Dim dif, i, nk, difk, ndifk, k, x
dif = 1
ndifk = 1000
x = point + dif
nk = Eval(expr)
For i = 1 To 3
dif = dif / 100
x = point + dif
k = Eval(expr)
difk = Abs(nk - k)
nk = k
'If difk < ndifk Then
'ndifk = difk
'Else
'Limit = "F"
'End If
Next
If Limit <> "F" Then Limit = k
End Function
Function Derivative (expr, point) '取导数的近似值
Dim Delta_x
Delta_x = 0.000001
Derivative = (Limit(expr, point + Delta_x) - Limit(expr, point))/Delta_x
End Function
s_expr = Inputbox("请输入关于x的一元方程" & vbCrLf & "注:指数是“^”,如 x^2 就是 x平方;乘号是“*”,不支持形如2x的写法,必须写成2*x")
m_expr = Mid(s_expr,1,InStr(s_expr,"=")-1) & "-(" & Mid(s_expr,InStr(s_expr,"=")+1,Len(s_expr)-InStr(s_expr,"=")) & ")"
x0 = 1
Do
x0 = Inputbox("请给出一个解的估计值 x0 ,输入exit退出", "初始值", x0)
If LCase(x0) = "exit" Then Exit Do
x = x0
Res = ""
For i = 1 To 1000
x = x0
der = Derivative(m_expr, x)
If der = 0 Then Msgbox "无法找到解!请尝试更换一个估计值!":Exit For
x1 = (Eval(m_expr)/der)
x0 = x0 - x1
If x1 = 0 Then
Exit For
End If
Next
If abs(x1) > 0.001 Then
Msgbox "解发散,无法求解!请尝试更换一个估计值!"
End If
If Abs(x0) < 1 Then x0 = "0" & x0
Msgbox s_expr & vbCrLf & vbCrLf & "x = " & x0 & vbCrLf & vbCrLf & "共计算" & i & "次"
Loop