0

(x-2)^2+(y-1)^2ある範囲で最小化するために、C++ でシミュレートされたアニーリングを実装しました。

このタイプのヒューリスティック手法では受け入れられないさまざまな出力が得られます。解は収束しているように見えますが、解に完全に近づくことはありません。

私のコード:

#include <bits/stdc++.h>
using namespace std;

double func(double x, double y)
{
    return (pow(x-2, 2)+pow(y-1, 2));
}
double accept(double z, double minim, double T,double d)
{
    double p = -(z - minim) / (d * T);
    return pow(exp(1), p);
}
double fRand(double fMin, double fMax)
{
    double f = (double)rand() / RAND_MAX;
    return fMin + f * (fMax - fMin);
}

int main()
{
    srand (time(NULL));
    double x = fRand(-30,30);
    double y = fRand(-30,30);
    double xm = x, ym=y;
    double tI = 100000;
    double tF = 0.000001;
    double a = 0.99;
    double d=(1.6*(pow(10,-23)));
    double T = tI;
    double minim = func(x, y);
    double z;
    double counter=0;

    while (T>tF) {
        int i=1;
        while(i<=30) {
            x=x+fRand(-0.5,0.5);
            y=y+fRand(-0.5,0.5);
            z=func(x,y);
            if (z<minim || (accept(z,minim,T,d)>(fRand(0,1)))) {
                minim=z;
                xm=x;
                ym=y;
            }
            i=i+1;
        }
        counter=counter+1;
        T=T*a;
    }

    cout<<"min: "<<minim<<" x: "<<xm<<" y: "<<ym<<endl;
    return 0;
}

どうすれば解決にたどり着くことができますか?

4

1 に答える 1

2

シミュレーテッド アニーリング アルゴリズムの実装には、間違っていると思われる点がいくつかあります。

反復ごとに、現在の最小値のいくつかの隣接 z を確認し、f(z) < 最小値の場合は更新する必要があります。f(z) > 最小の場合、新しい点を受け入れることもできますが、受け入れ確率関数を使用します。

問題は、accept関数内のパラメーターdが低すぎることです。パラメーターは常に戻り0.0、受け入れの条件をトリガーすることはありません。次のようなものを試してください1e-5; 物理的に正しい必要はありません。「温度」を下げながら減少するだけです。

外側のループで温度を更新した後、内側のループを実行する前にx=xmandを配置する必要がありy=ymます。または、現在のソリューションの近隣を検索する代わりに、基本的にランダムにさまよいます (境界もチェックしていません)。

そうすることで、通常、次のような出力が得られます。

min: 8.25518e-05 x: 2.0082 y: 0.996092

それが役に立ったことを願っています。

于 2015-11-18T18:04:46.740 に答える