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

时间:2015-08-06 04:15:59

标签: java function max min

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

例如,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;
    }
    }

2 个答案:

答案 0 :(得分: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;
}

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

此实施的下一步是考虑使包含lowerBoundupperBound 的网格不均匀。例如,在cos(x)的情况下,您不需要在最小值和最大值附近非常采样,因为函数在那里没有很大的变化。另一方面,在它越过零的地方,功能极快地改变了值。因此,我在此处所写的内容的改进将是设计您的网格更加动态(因此需要更少的评估)。

答案 1 :(得分:-1)

我不确定这是否会有所帮助,但这可能是你想要的。 https://en.wikibooks.org/wiki/The_Science_of_Programming/Peaks_and_Valleys