2015-08-06 5 views
3

Я ищу способ вычисления минимального и максимального значений для функции в Java. Программа, которую я собираюсь создать, увидит все локальные минимумы и максимумы для функции, которая колеблется вокруг оси x (это не школьное задание, хотя я упомянул cos (x) в схеме ниже). Методы, которые я видел по всему Интернету, вычисляют значение min/max для массива. Я изучаю метод, который будет непосредственно вычислять это значение для функции, которая идет от x = 0 до x = бесконечность.Вычислить минимум и максимум для функции

Например, соз (х) от х = 0 до х = 5000. Есть множество локальных минимумов и максимумов,

Кроме того, Sin (х) от х = 0 до х = 5000. Большой количество локальных максимумов и минимумов.

Функция также непрерывна от x = 0 до x = бесконечность.

Есть ли предпочтительный численный метод для этого?

public class Test { 
    public static void main(String [] args) { 
     Function testFunction = new Function() 
     { 
      public double f(double x) { 
      return something; 
     } 

     } 

     findMax(testFunction, 1, 40000, 0.001); 
     findMin(testFunction, 1, 40000, 0.001); 

    } 

    public static interface Function { 
     public double f(double x); 
    } 

    public static double function(double x) { 
     return Math.cos(x); 
    } 

    public static void findMax(Function f, double lowerBound, double upperBound, double step) { 

    } 

    public static void findMin(Function f, double lowerBound, double upperBound, double step) { 

    } 

} 

Это аналогичная программа, которая находит корни -

// Finds the roots of the specified function passed in with a lower bound, 
    // upper bound, and step size. 
    public static void findRoots(Function f, double lowerBound, 
        double upperBound, double step) { 
    double x = lowerBound, next_x = x; 
    double y = f.f(x), next_y = y; 
    int s = sign(y), next_s = s; 

    for (x = lowerBound; x <= upperBound ; x += step) { 
     s = sign(y = f.f(x)); 
     if (s == 0) { 
     System.out.println(x); 
     } else if (s != next_s) { 
     double dx = x - next_x; 
     double dy = y - next_y; 
     double cx = x - dx * (y/dy); 
     System.out.println(cx); 
     } 
     next_x = x; next_y = y; next_s = s; 
    } 
    } 
+0

Хорошо, я, вероятно, не должен был писать сообщение в полночь. Я обновлю его .... – Axion004

+0

Дериватируйте свою квадратичную функцию и проверяйте крайности? – John

+0

@ Axion004, вы знаете, как математически найти min max любого уравнения второй степени? Вам когда-нибудь приходилось сталкиваться с производными первого и второго порядка? –

ответ

4

Вот наиболее наивная реализация вашей findMax() функции:

public static void findMax(Function f, double lowerBound, double upperBound, double step) { 
    double maxValue = f.f(lowerBound); 

    for (double i=lowerBound; i <= upperBound; i+=step) { 
     double currEval = f.f(i); 
     if (currEval > maxValue) { 
      maxValue = currEval; 
     } 
    } 

    return maxValue; 
} 

Вы можете играть вокруг с размером шага до вы сходитесь на максимальном значении. Чем меньше размер шага, тем более точное разрешение вам нужно будет обнаружить максимум.

Следующим шагом по этой реализации будет рассматривать ВОДОЛАЗНАЯ сетку, содержащую lowerBound и upperBoundнеравномерно. Например, в случае cos(x), вам не нужно очень много пробовать вблизи минимумов и максимумов, потому что функция там не очень сильно меняет значение. С другой стороны, вблизи того места, где он пересекает ноль, функция очень быстро меняет значение. Поэтому улучшение в том, что я написал здесь, было бы для того, чтобы ваша сетка была более динамичной (и, следовательно, требовала меньше оценок).

+0

@ Axion004 Пожалуйста, просмотрите этот ответ. –

+0

Благодарим вас, просмотрев и тестируя. – Axion004

+0

Прошу прощения, я понимаю, что мне нужно написать новый вопрос. Я задам новый вопрос. Было бы гораздо эффективнее сделать один метод, который непосредственно смотрит на значение производной. Когда производная находится в пределах определенного epsilon, скажем eps = 0,000001, тогда это значение возвращается. Это пройдет через интервал [a: b], а затем вернет все значения, в которых произошел минимум или максимум. Я прошу прощения за то, что не видел этого раньше. – Axion004

0

Я не уверен, что это поможет, но может ли это быть тем, что вы ищете. https://en.wikibooks.org/wiki/The_Science_of_Programming/Peaks_and_Valleys

+3

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

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