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;
    }
    世上无难事,只要肯登攀。
  • 相关阅读:
    Express 框架中 使用ejs
    Nodejs操作MongoDB数据库
    MongoDB基础操作
    node中的包、npm和模块
    background
    animation
    transition
    transform
    【SpringCloud】各种组件的更新情况
    【SpringCloud】版本选择
  • 原文地址:https://www.cnblogs.com/littlehoom/p/3612306.html
Copyright © 2011-2022 走看看