[英]Finding all local maxima of a function
I have written code to find the global minimum of a function using the simulated annealing algorithm — down below — but how to use the same algorithm to find all local maxima of a function ?我已经编写了代码来使用模拟退火算法找到函数的全局最小值——在下面——但是如何使用相同的算法来找到函数的所有局部最大值?
My code for finding the local minimum of a function, note that i know nothing about the function I am asking the interactor for the f(x)
at x
ie the cost of the function in a particular point.我寻找当地最低的函数,注意我一无所知,我问交互器的功能代码
f(x)
在x
中的特定点即功能的成本。
#include <bits/stdc++.h>
using namespace std;
double myRand(double fMin, double fMax)
{
double f = (double)rand() / RAND_MAX;
return fMin + f * (fMax - fMin);
}
int main()
{
cout.flush();
double x,fx,xMin;
double fMin;
cout << "? "<<fixed << setprecision(6) << -1<<endl;
cin>>fMin;
for(double T = 1000; T>1; T*=.995)
{
x=myRand(-100,100);
cout << "? "<<fixed << setprecision(6) << x <<endl;
cin>>fx;
if (fx<fMin)
{
fMin=fx;
xMin = x;
}
else
{
double P=exp((fMin-fx)/T);
if (P>myRand(1,100))
{
fMin=fx;
xMin=x;
}
}
}
cout << "! "<<fixed << setprecision(6)<<xMin<<endl;
return 0;
}
my attempt to find the local maxima is我试图找到局部最大值是
#include <bits/stdc++.h>
using namespace std;
double myRand(double fMin, double fMax)
{
double f = (double)rand() / RAND_MAX;
return fMin + f * (fMax - fMin);
}
int main()
{
cout.flush();
double x,fx,xMax;
double fMax;
int n;
double a,b;
cin>>n>>a>>b;
double answer[n];
for(int i=0; i<n; i++)
{
cout << "? "<<fixed << setprecision(6) << a+i/5 <<endl;
cin>>fMax;
for(double T = 1000; T>1; T*=.995)
{
x=myRand(a,b);
// i am avoiding to get the same local max twice
while(i>0&&answer[i-1]==x)
x=myRand(a,b);
cout << "? "<<fixed << setprecision(6) << x <<endl;
cin>>fx;
if (fx>fMax)
{
fMax=fx;
xMax = x;
}
else
{
double P=exp((fMax-fx)/T);
if (P<myRand(0,1))
{
fMax=fx;
xMax=x;
}
}
}
answer[i]=xMax;
}
cout << "!";
for(int i=0; i<n; i++)
{
cout<<" "<<fixed << setprecision(6)<<answer[i];
}
return 0;
}
Place the algorithm inside a function:将算法放在函数中:
double my_unknown_function(double x) { cout << "? " << fixed << setprecision(6) << x << endl; cin >> fx; return fx; } using function = double(double); double minimum(function func) { double x, fx, xMin; /* ... */ for(double T = 1000; T>1; T*=.995) { x = myRand(-100,100); fx = func(x); /* ... */ } return xMin; }
In this way you can simply get multiple local minima:通过这种方式,您可以简单地获得多个局部最小值:
std::vector<double> lm; for (int i(0); i < 100; ++i) lm.push_back(minimum(my_unknown_function));
As explained in the comments, simulated annealing is an optimization heuristic.正如评论中所解释的,模拟退火是一种优化启发式方法。 It's not an exhaustive search and it doesn't find all minima .
这不是一个详尽的搜索,也没有找到所有的 minima 。
Anyway calling minimum
multiple times you can get different results, since it's stochastic.无论如何,多次调用
minimum
可以获得不同的结果,因为它是随机的。 In expectation, with a large enough number of restarts , any local search method will someday give you the actual global minimum.在预期中,如果有足够多的重新启动,任何本地搜索方法总有一天会为您提供实际的全局最小值。
Do not rewrite the algorithm for the maximization task: you could introduce bugs and testing is harder.不要为最大化任务重写算法:你可能会引入错误并且测试更难。
Just take the opposite of your function:只需与您的功能相反:
double my_unknown_function(double x) { cout << "? " << fixed << setprecision(6) << x << endl; cin >> fx; return -fx; }
Also consider:还要考虑:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.