2015-10-31 3 views
1

Если у меня есть выпуклая кривая и вы хотите найти точку минимума (x, y), используя цикл for или while. Я думаю о чем-то вродеПоиск точки минимума функции

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 

как могу я, что минимальная точка? (Х всегда> 0 и целое число)

+0

http://stackoverflow.com/questions/10722467/c-loop-to-find-minima-of-function – Neolisk

+0

Зависит от кривой. 'y = -x^2' является выпуклым, но не имеет минимума. Можете ли вы показать нам «вычислительную функцию» или хотя бы поделиться формулой кривой? – theB

+0

Характер вычисления состоит в том, что его выпуклая кривая, поэтому она будет иметь минимум. –

ответ

1

очень близко

вам просто нужно

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.For - например

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) 

Это автоматически создаст отдельные потоки для каждой итерации цикла.

+0

Выполнение линейного поиска является самым неэффективным, которое вы можете получить. – Neolisk

+0

OK показать нам лучшее решение пожалуйста. Поэтому мы можем учиться, а не просто критиковать. –

+0

Если я правильно помню из университета, это правильный способ сделать это: https://en.wikipedia.org/wiki/Golden_section_search – Neolisk

1

Для функции образца:

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

или properly written like this:

enter image description here

Минимум является mathematically obvious на x = 50 и y = -5, вы можете verify with google:

enter image description here

Ниже консольное приложение VB.NET, converted from python, находит минимум на x=50.0000703584199, y=-4.9999999999505, который является правильным для указанного допуска 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 

примечания стороны: ваша первая попытка найти минимум берет на себя все функция дискретна, что очень маловероятно в реальной жизни. То, что вы получите с помощью простого цикла, является очень приблизительной оценкой и долгое время, чтобы найти его, поскольку линейный поиск является наименее эффективным среди других методов.

+0

Прохладный. Получение результатов от вашей функции происходит значительно быстрее - повторить вычисление 1000 раз заняло примерно столько же времени, сколько потребовалось мне сделать один раз в многопоточном вычислении Около 11 мс.Я переписал свою функцию для многопоточности и пропустил функцию кривой с шагом .0001, чтобы имитировать ваши допуски, и это заняло всего 36 мс. Неплохо для неэффективной функции, хотя? ;-) О, спасибо, что показал мне самый быстрый способ. Понравилось –

+0

@DavidWilson: Увеличьте интервал поиска и/или допуск до 0,000001, вы должны заметить разницу. Я вообще склоняюсь к подходу к разработке программного обеспечения (простой + многопоточность, как вы и предполагали), но в таком случае вы не можете победить математику. :) – Neolisk

 Смежные вопросы

  • Нет связанных вопросов^_^