Vb.net 求函数的最小点

Vb.net 求函数的最小点,vb.net,minimum,Vb.net,Minimum,如果我有一条凸曲线,想用for或while循环找到最小点(x,y)。我在想类似的事情 dim y as double dim LastY as double = 0 for i = 0 to a large number y=computefunction(i) if lasty > y then exit for next 我怎样才能得到最低分数?(x始终大于0且为整数)非常接近 你只需要 dim y as double dim smallestY as double = co

如果我有一条凸曲线,想用for或while循环找到最小点(x,y)。我在想类似的事情

dim y as double
dim LastY as double = 0
for i = 0 to a large number
  y=computefunction(i)
  if lasty > y then exit for
next
我怎样才能得到最低分数?(x始终大于0且为整数)

非常接近

你只需要

dim y as double
dim smallestY as double = computefunction(0)
for i = 0 to aLargeNumber as integer
    y=computefunction(i)
    if smallestY > y then smallestY=y
next
'now that the loop has finished, smallestY should contain the lowest value of Y
如果这段代码需要很长时间才能运行,您可以很容易地使用parallel将其转换为多线程循环

dim y as Double
dim smallestY as double = computefunction(0)
Parallel.For(0, aLargeNumber, Sub(i As Integer)
                                  y=computefunction(i)
                                  if smallestY > y then smallestY=y
                               End Sub)
这将自动为循环的每个迭代创建单独的线程。

对于示例函数:

y = 0.01 * (x - 50) ^ 2 - 5
或:

最小值为
x=50
y=-5
,您可以:

在VB.NET控制台应用程序下方,在
x=50.0000703584199,y=-4.9999999505
处找到一个最小值,该值对于
0.0001
的指定公差是正确的:

Module Module1

  Sub Main()
    Dim result As Double = GoldenSectionSearch(AddressOf ComputeFunction, 0, 100)
    Dim resultString As String = "x=" & result.ToString + ", y=" & ComputeFunction(result).ToString
    Console.WriteLine(resultString) 'prints x=50.0000703584199, y=-4.9999999999505
  End Sub

  Function GoldenSectionSearch(f As Func(Of Double, Double), xStart As Double, xEnd As Double, Optional tol As Double = 0.0001) As Double
    Dim gr As Double = (Math.Sqrt(5) - 1) / 2

    Dim c As Double = xEnd - gr * (xEnd - xStart)
    Dim d As Double = xStart + gr * (xEnd - xStart)

    While Math.Abs(c - d) > tol
      Dim fc As Double = f(c)
      Dim fd As Double = f(d)

      If fc < fd Then
        xEnd = d
        d = c
        c = xEnd - gr * (xEnd - xStart)
      Else
        xStart = c
        c = d
        d = xStart + gr * (xEnd - xStart)
      End If
    End While

    Return (xEnd + xStart) / 2
  End Function

  Function ComputeFunction(x As Double)
    Return 0.01 * (x - 50) ^ 2 - 5
  End Function

End Module
模块1
副标题()
Dim结果为Double=GoldenSectionSearch(计算函数的地址,0,100)
Dim RESULTS字符串为String=“x=”&result.ToString+”,y=“&ComputeFunction(result).ToString
Console.WriteLine(resultString)“打印x=50.0000703584199,y=-4.9999999505
端接头
函数goldensionsearch(f作为Func(Of Double,Double),xStart作为Double,xEnd作为Double,可选tol作为Double=0.0001)作为Double
尺寸gr为双精度=(数学Sqrt(5)-1)/2
尺寸c为双精度=xEnd-gr*(xEnd-xStart)
尺寸d为双精度=xStart+gr*(xEnd-xStart)
而Math.Abs(c-d)>tol
尺寸fc为双精度=f(c)
尺寸fd为双精度=f(d)
如果fc

旁注:您最初试图寻找最小值的方法是假设函数是离散的,这在现实生活中是非常不可能的。使用一个简单的for循环会得到一个非常粗略的估计,并且需要很长时间才能找到它,因为线性搜索在其他方法中效率最低。

取决于曲线
y=-x^2
是凸的,但没有最小值。你能给我们看一下
computefunction
,或者至少分享一下曲线的公式吗?计算的本质是它是一条凸曲线,所以它会有一个最小值。@theB:固定区间上的任何凸曲线都会有一个最小值。像
y=-x^2
这样的函数可以有两个相等的最小值,具体取决于间隔的选择方式。@neolick您完全正确。不管出于什么原因,我的大脑完全决定忽略间歇部分。我仍然认为,尽管FWIW,对函数本身的分析可能会给出一个更简单、更准确的解决方案。线性搜索是你能得到的最低效的搜索。好的,请告诉我们最好的解决方案。因此,我们可以学习,而不仅仅是被批评。如果我在大学里没记错的话,这是正确的方法:好吧,也许是这样,但是@sjjohnson希望找到使用for next循环的最小值。可能值得询问参数和计算函数,以便进行比较基准测试。酷。从函数中获取结果的速度要快得多——重复计算1000次所花费的时间与我在11毫秒左右的非多线程计算中所花费的时间差不多。我将函数重写为多线程,并以.0001的步骤运行曲线函数,以模拟公差,只需36毫秒。不过,对于一个效率低下的函数来说也不错,嗯?;-)哦,谢谢你告诉我最快的方法。它是appreciated@DavidWilson:将搜索间隔和/或公差增加到0.000001,您应该注意到一个差异。我通常倾向于软件工程方法(简单+多线程,如你所建议的),但在这种情况下,你无法击败数学