繁体   English   中英

查找函数的所有局部最大值

[英]Finding all local maxima of a function

我已经编写了代码来使用模拟退火算法找到函数的全局最小值——在下面——但是如何使用相同的算法来找到函数的所有局部最大值

我寻找当地最低的函数,注意我一无所知,我问交互器的功能代码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;

}
  1. 将算法放在函数中:

     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));

    正如评论中所解释的,模拟退火是一种优化启发式方法。 不是一个详尽的搜索也没有找到所有的 minima

    无论如何,多次调用minimum可以获得不同的结果,因为它是随机的。 在预期中,如果有足够多的重新启动,任何本地搜索方法总有一天会为您提供实际的全局最小值。

  2. 不要为最大化任务重写算法:你可能会引入错误并且测试更难。

    只需与您的功能相反:

     double my_unknown_function(double x) { cout << "? " << fixed << setprecision(6) << x << endl; cin >> fx; return -fx; }

还要考虑:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM