我正在寻找一种计算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;
}
}
答案 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;
}
您可以使用步长,直到收敛到最大值。步长越小,您必须检测到最大值的分辨率越高。
此实施的下一步是考虑使包含lowerBound
和upperBound
的网格不均匀。例如,在cos(x)
的情况下,您不需要在最小值和最大值附近非常采样,因为函数在那里没有很大的变化。另一方面,在它越过零的地方,功能极快地改变了值。因此,我在此处所写的内容的改进将是设计您的网格更加动态(因此需要更少的评估)。
答案 1 :(得分:-1)
我不确定这是否会有所帮助,但这可能是你想要的。 https://en.wikibooks.org/wiki/The_Science_of_Programming/Peaks_and_Valleys