• 模拟退火


    模拟退火((SA))和随机化贪心

    物理上的模拟退火

    固体退火原理,将固体加温至充分高,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在每个温度都达到平衡态,最后在常温时达到基态,内能减为最小。

    启发

    根据物理上的模拟退火,我们可以吸取一些经验,采用模拟退火的方法。

    模拟退火是一个非常优秀的骗分甚至可以秒杀正解的算法,其能够很好地通过每次时间复杂度很小的贪心,然后不停贪心,就算这样那贪心许多次之后时间复杂度依然很小,甚至可以秒杀正解,而且模拟退火是有变化幅度的,而算法性能和其结果与初始值有关是他的特点,既是它的优点也是它的缺点。优点在于你可以控制它的复杂度,但缺点也就是该算法容易被卡。所以随机化贪心要少用啊。不然人品就败光了。

    过程

    1. 初始化:初始温度(T)(充分大),初始解状态(S)(是算法迭代的起点)

    2. 产生新解(S′)

    3. 计算增量(Δt′=C(S′)-C(S)),其中(C(S))为评价函数

    4. (Δt′<0)则接受(S′)作为新的当前解,否则以概率(exp(-Δt′/T))接受(S′)作为新的当前解.

    5. 如果满足终止条件或温度过低则输出当前解作为最优解,结束程序。终止条件通常取为连续若干个新解都没有被接受时终止算法。

    6. (T)逐渐减少,且(T>=0),然后转第(2)步。

    思想

    其思想主要结合了退火和信息学的特点,采取模拟的算法来实现随机化贪心,有人这么比喻,

    (Code)([JSOI2004]平衡点)

    #include <bits/stdc++.h>
    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    const double eps = 1e-253;
    const double t = 0.99389;
    int n; double xans, yans, xx, yy, ans = 1e18 + 7, now;
    using namespace std;
    struct de {
        int x, y, w;
    }data[10010];
    double jisuan(double x, double y)
    {
        double sum = 0;
        for (int i = 1; i <= n; i++)
        {
            double dx = x - data[i].x, dy = y - data[i].y;
            sum += data[i].w * (sqrt(dx * dx + dy * dy));
        }
        return sum;
    }
    void tuihuo(double T)
    {
        while (T > eps)
        {
            double xx = xans + (rand() * 2 - RAND_MAX) * T;
            double yy = yans + (rand() * 2 - RAND_MAX) * T;
            double now = jisuan(xx, yy);
            double del = now - ans;
            if (del < 0)//如果now比ans要优 
            {
                xans = xx;
                yans = yy;
                ans = now;	
            } 
             else if(exp(-del / T) * RAND_MAX>rand())//能否接受这个差 
        	    {
                xans = xx;
                yans = yy;
            }
            T *= t;
        }	
    }
    int main()
    {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++)
            scanf("%d%d%d", &data[i].x, &data[i].y, &data[i].w);
        tuihuo(1926), tuihuo(1926), tuihuo(1926);
        printf("%.3lf %.3lf", xans, yans);
        return 0;
    }		
    
    
  • 相关阅读:
    环境部署:Linux下查看JDK安装路径
    环境部署(一):Linux下安装JDK
    linux常见命令
    设计用例
    测试用例的优先级
    快速幂和快速乘
    docker-compose安装
    jmeter通过命令生成自动测试报告
    jmeter环境变量配置
    java将毫秒转化为当前时间
  • 原文地址:https://www.cnblogs.com/liuwenyao/p/10292961.html
Copyright © 2020-2023  润新知