zoukankan      html  css  js  c++  java
  • Simulated Annealing(模拟退火算法)

     

    /*
    Simulated Annealing(模拟退火算法)
    求解旅行商问题(TSP)
    网上给的数据是31个省会的坐标,蚁群算法得到的结果是:15378
    我算的结果中,最好的一次是:15495
    */
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    //#include<ctime>
    #include<cmath>
    #include<time.h>
    #define N 31       //城市个数
    #define Tmax 8000  //初始温度
    #define Tmin 1E-10 //终止温度
    #define RATE 0.95  //温度衰减率
    #define in_loop 13000 //内层循环次数
    #define out_loop 2000 //外层循环次数
    #define p_limit 10000 //概率选择次数
    
    using namespace std;
    
    //31个省会x和y的坐标
    double x[N]={1304,3639,4177,3712,3488,3326,3238,4196,4312,4386,3007,2562,2788,2381,1332,3715,3918,4061,3780,3676,4029,4263,3429,3507,3394,3439,2935,3140,2545,2778,2370};
    double y[N]={2312,1315,2244,1399,1535,1556,1229,1004,790,570,1970,1756,1491,1676,695,1678,2179,2370,2212,2578,2838,2931,1908,2367,2643,3201,3240,3550,2357,2826,2975};
    
    //两个城市之间的距离
    double d[N][N];
    
    void init(){
        //初始化任意两个城市的距离
        for(int i=0;i<N;i++)for(int j=0;j<i;j++){
            d[i][j]=d[j][i]=sqrt((y[j]-y[i])*(y[j]-y[i])+(x[j]-x[i])*(x[j]-x[i]));
        }
        for(int i=0;i<N;i++)d[i][i]=0;
    
        srand((unsigned)time(0));
    }
    
    //路径
    class path{
    public:
        path(){}
        ~path(){}
        int city[N];    //依次经过的城市编号
        double dis;     //总的距离
        void totalLen(){
            dis=0;
            for(int i=0;i<N-1;i++)dis+=d[city[i]][city[i+1]];
            dis+=d[city[0]][city[N-1]];
        }
    };
    
    //最优解
    path bestpath;
    
    //产生新路径
    path newpath(path prepath){
        path newp = prepath;
        int x,y,t;
        do{
            x=rand()%N;
            y=rand()%N;
        }while(x==y);
        t=newp.city[x];newp.city[x]=newp.city[y];newp.city[y]=t;
        newp.totalLen();
        return newp;
    }
    
    //Annealing
    void Anne()
    {
        init();
        //随机选一个初始解
        for(int i=0;i<N;i++)bestpath.city[i]=i;
        bestpath.totalLen();
        int out_t=0,p_t=0;
        double T=Tmax,delta,prob, rnd;
        path np,cp; //新路径,当前路径
        cp=bestpath;
        while(out_t<out_loop&&T>Tmin){
            for(int i=0;i<in_loop;i++){
                np=newpath(cp);
                if(np.dis<cp.dis){
                    cp=np;
                    out_t=0;
                    p_t=0;
                }
                else{
                    delta=np.dis-cp.dis;
                    prob=exp(-delta/T);
                    rnd=rand()%10000/10000.0;
                    if(prob>rnd)cp=np;
                    p_t++;
                }
                if(p_t>p_limit){
                    out_t++;
                    break;
                }
            }
            if(cp.dis<bestpath.dis)bestpath=cp;
            T*=RATE;
            printf("dis= %f
    ",bestpath.dis);
        }
    }
    
    int main()
    {
        Anne();
        return 0;
    }
    世上无难事,只要肯登攀。
  • 相关阅读:
    Leetcode 191.位1的个数 By Python
    反向传播的推导
    Leetcode 268.缺失数字 By Python
    Leetcode 326.3的幂 By Python
    Leetcode 28.实现strStr() By Python
    Leetcode 7.反转整数 By Python
    Leetcode 125.验证回文串 By Python
    Leetcode 1.两数之和 By Python
    Hdoj 1008.Elevator 题解
    TZOJ 车辆拥挤相互往里走
  • 原文地址:https://www.cnblogs.com/littlehoom/p/3612306.html
Copyright © 2011-2022 走看看