带有停止条件的VB.NET中的递归

时间:2014-08-08 05:28:05

标签: vb.net recursion while-loop tail-recursion

我在VB.NET中编写了一个函数,它使用Bisect Method来查找任意函数的根。

[给定连续函数f(x),如果f(x1)和f(x2)具有不同的符号,则它保证在x1和x2之间至少有一个根。 Bisect Method缩小了范围[x1,x2],直到找到根。]

我用两种不同的方式编写了这个函数:一个使用while循环,另一个使用递归。

在while循环方法中,我可以轻松跟踪迭代次数,例如,在1000次循环之后,如果没有找到根,则该函数会停止并退出。

我的问题是:如何在仍然能够保持尾调用优化的同时使用递归方法插入这样的停止条件?提前谢谢。

方法1:While循环

Public Function FindOneRoot(lowerBound As Double, upperBound As Double, _
                             tolerance As Double, ByRef Root As Double, _
                             theFunction As Func(Of Double, Double)) As Boolean
  Dim flower As Double = theFunction(lowerBound)
  Dim fupper As Double = theFunction(upperBound)
  Root = (lowerBound + upperBound) / 2
  Dim froot As Double = theFunction(Root)
  Dim count As Integer = 0
  While Math.Abs(froot) > tolerance
     If froot * flower > 0 Then
        lowerBound = Root
     Else
        upperBound = Root
     End If
     Root = (lowerBound + upperBound) / 2
     froot = theFunction(Root)
     count += 1 'keep track of the loops

     If count >= 1000 Then 'stop looping after 1000 iterations
        Exit While
     End If
  End While

  If count < 1000 Then
     Return True
  Else
     Return False
  End If

End Function

方法2:递归

 Public Function FindOneRoot(x1 As Double, x2 As Double, tolerance As Double, _
                                    theFunction As Func(Of Double, Double)) As Double
  Dim x As Double = (x1 + x2) / 2
  If Math.Abs(theFunction(x)) < tolerance Then
     Return x 'found a root
  ElseIf theFunction(x1) * theFunction(x) < 0 Then
     Return FindOneRoot(x1, x, tolerance, Root, theFunction)
  Else
     Return FindOneRoot(x, x2, tolerance, Root, theFunction)
  End If
End Function

1 个答案:

答案 0 :(得分:1)

在递归中使用相同的条件。但是在函数之外声明计数

添加另一个参数作为计数传递计数并检查函数内部

 Public Function FindOneRoot(x1 As Double, x2 As Double, tolerance As Double, 
 ByRef Root As Double,theFunction As Func(Of Double, Double),
 Count as integer) As Boolean

    If count >= 1000 Then 'stop looping after 1000 iterations
       Return False: Exit Function
    End If

   Dim x As Double = (x1 + x2) / 2
   If Math.Abs(theFunction(x)) < tolerance Then
      Return x 'found a root
   ElseIf theFunction(x1) * theFunction(x) < 0 Then
     Return FindOneRoot(x1, x, tolerance, Root, theFunction,count +1)
  Else
  Return FindOneRoot(x, x2, tolerance, Root, theFunction,count +1)
  End If
  End Function