HDU 2899Strange fuction(模拟退火)

时间:2022-06-11
本文章向大家介绍HDU 2899Strange fuction(模拟退火),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题意

题目链接

求 $F(x) = 6 * x^7+8*x^6+7*x^3+5*x^2-y*x (0 <= x <=100)$的最小值

Sol

强上模拟退火,注意eps要开大!

/*
*/
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<ctime>
using namespace std;
const int MAXN = 1e6 + 10;
const double eps = 1e-10, Dlt = 0.98;
int T;
double Y, Best;
double F(double x) {
    return 6 * x * x * x * x * x * x  * x + 8 * x * x * x * x * x * x + 7 * x * x * x + 5 * x * x - Y * x;
}
double getrand(double T) {
    return T * ((rand() << 1) - RAND_MAX);
}
double solve(int id) {
    double x = id, now = F(x);
    Best = min(Best, now);
    for(double T = 101; T > eps; T *= Dlt) {
        double wx = x + getrand(T), wv = F(wx);
        if(wx > eps && (wx - 100 <= eps)) {
            if(wv < Best) x = wx, Best = wv, now = wv;
            if(wv < now || ((exp((wv - now) / T)) * RAND_MAX < rand())) now = wv, x = wx;
        }
    }
}
int main() {
srand((unsigned)time(NULL));
    scanf("%d", &T);
    while(T--) {
        
        Best = 1e20;
        scanf("%lf", &Y);
        int times = 100;
        while(times--) solve(times);
        printf("%.4lfn", Best);
    }    
    return 0;
}
/*
3
100
200
1000000000
*/