我已经编写了代码,使用模拟退火算法来查找函数的全局最小值(下图),但是如何使用同一算法来查找函数的所有局部最大值?
我寻找当地最低的函数,注意我一无所知,我问功能代码交互器用于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;
}
我试图找到局部最大值是
#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;
}
将算法放在函数内:
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;
}
这样,您可以简单地获得多个局部最小值:
std::vector<double> lm;
for (int i(0); i < 100; ++i)
lm.push_back(minimum(my_unknown_function));
如评论中所述,模拟退火是一种优化启发式方法。这不是一个详尽的搜索,也没有找到所有的最小值。
无论如何,minimum
多次调用都可以得到不同的结果,因为它是随机的。可以预期的是,如果重启次数足够多,则任何本地搜索方法总有一天会为您提供实际的全局最小值。
不要重写用于最大化任务的算法:您可能会引入错误,并且测试更加困难。
只需采取相反的功能:
double my_unknown_function(double x)
{
cout << "? " << fixed << setprecision(6) << x << endl;
cin >> fx;
return -fx;
}
同时考虑:
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句