模擬退火 HDU - 2899 Strange Function

Strange Function

[ HDU - 2899 ]

題目大意:

函數 F(x) = 6x7 + 8x6 + 7x3 + 5x2 - yx, 其中x的範圍是0 ≤ x ≤ 100.
輸入y值,輸出F(x)的最小值

模擬退火算法

模擬退火就是類似於物體降溫的概率,來進行多次搜索迭代

在迭代過程中,模擬退火算法隨機選擇下一個狀態,有兩種可能

  1. 新狀態比原來狀態更優,那麼接受這個新狀態
  2. 新狀態更差,那麼以一定的概率接受該狀態,不過這個概率應該隨着時間的推移逐漸降低

模擬退火算法的主要步驟如下:

  1. 設置一個初始的溫度T
  2. 溫度下降,狀態轉移。從當前溫度按降溫係數下降到下一個溫度,在新的溫度計算當前狀態
  3. 如果溫度降到設定的溫度下界,程序停止

題解代碼

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

const double eps = 1e-8;    // 終止溫度

double y;
double func(double x)   // 計算函數值
{
    return 6 * pow(x, 7.0) + 8 * pow(x, 6.0) + 7 * pow(x, 3.0) + 5 * pow(x, 2.0) - y * x;
}

double solve(void)
{
    double T = 100;         // 初始溫度
    double delta = 0.98;    // 降溫係數
    double x = 50.0;        // x的初始值
    double now = func(x);   // 計算初始函數值
    double ans = now;       // 返回值
    while (T > eps) {
        int f[2] = {1, -1};
        double newx = x + f[rand() % 2] * T;    // 按概率改變x,隨t的降溫而減少
        if (newx >= 0 && newx <= 100) {
            double next = func(newx);
            ans = min(ans, next);
            if (now - next > eps) {
                x = newx;
                now = next;
            }
        }
        T *= delta;
    }
    return ans;
}

int main(void)
{
    int cas;
    scanf("%d", &cas);
    while (cas--) {
        scanf("%lf", &y);
        printf("%.4lf\n", solve());
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章