计算函数的最小值和最大值

Calculate the minimum and maximum for a function

我正在寻找一种计算 Java 中函数的最小值和最大值的方法。我要创建的程序将看到围绕 x 轴振荡的函数的所有局部最小值和最大值(这不是学校作业,尽管我在下面的大纲中提到了 cos(x))。我在互联网上看到的方法都是计算数组的 min/max 值。我正在研究编写一种方法,该方法将直接计算从 x = 0 到 x = infinity 的函数的此值。

例如,cos(x) 从 x = 0 到 x = 5000。有大量的局部最小值和最大值,

此外,sin(x) 从 x = 0 到 x = 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;
    }
    }

这是您的 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;
}

您可以调整步长直到收敛到最大值。步长越小,您必须检测到的分辨率就越高。

此实现的下一步是考虑将包含 lowerBoundupperBound 不均匀 的网格分开。例如,在 cos(x) 的情况下,您不需要在最小值和最大值附近采样太多,因为函数在那里的值变化不大。另一方面,在接近零的位置,函数的值变化非常快。因此,对我在这里写的内容的改进是将您的网格设计得更加动态(因此需要更少的评估)。

我不确定这是否有帮助,但这是您要找的东西吗? https://en.wikibooks.org/wiki/The_Science_of_Programming/Peaks_and_Valleys