运筹优化学习12:模拟退火算法求解TSP原理及C++实现代码

目录

1 基础理论

1.1 模拟退火与物理退火过程的类比

1.2 重要性采样方法

1.3 优化机制

2 算法核心要素

2.1 初温

2.2 新状态的产生

2.3 状态接受的判断

2.4 抽样稳定准则

2.4 收敛准则

3 算法的改进

4 基于C++的简单实现


模拟退火算法是模拟自然界物理退火过程设计的一个通用概率演算法,是一种基于蒙特卡洛准则迭代求解问题优化解的一种常用的随机优化算法。

1 基础理论

1.1 模拟退火与物理退火过程的类比

运筹优化学习12:模拟退火算法求解TSP原理及C++实现代码_第1张图片

1.2 重要性采样方法

运筹优化学习12:模拟退火算法求解TSP原理及C++实现代码_第2张图片

1.3 优化机制

算法从较高的初始温度开始,利用具有概率突条特性的Metropolis抽样策略在解空间内进行邻域搜索,伴随温度的不断下降重复采样过程,从而获得研究问题的优化解。

运筹优化学习12:模拟退火算法求解TSP原理及C++实现代码_第3张图片

2 算法核心要素

2.1 初温

初温应足够的大,以保证几乎所有的候选解都被接受,以保证算法最终收敛;初温越大搜索时间越长,但更有可能得到问题的最优解

2.2 新状态的产生

一方面保证新解的全空间分布,也要考虑新解的局部密度,可以通过设计多样化的邻域操作算子实现解状态的变更。

运筹优化学习12:模拟退火算法求解TSP原理及C++实现代码_第4张图片

如采用正态分布的解更为集中一些,而柯西分布的解则会相对分散一些

2.3 状态接受的判断

通常以概率判断状态是否被接受,一般接受服从以下两个方面的原则:

  • 同一温度下,接受目标函数值下降的候选解的概率要大于目标函数值增加的候选解
  • 随着温度的下降,接受目标函数值增加的概率要逐步减下
  • 当趋于0时,只接受目标函数下降的值

2.4 抽样稳定准则

决定各温度等级下,产生候选解的个数

常见设计为:连续若干步的目标函数值小于设定的阈值;固定的步数采样

2.4 收敛准则

  • 设置温度终值,理论上要求是趋于0但着不切实际
  • 基于时间的准则,设置外循环的迭代次数
  • 基于性能的准则,连续若干步变化微小,系统熵趋于稳定

3 算法的改进

运筹优化学习12:模拟退火算法求解TSP原理及C++实现代码_第5张图片运筹优化学习12:模拟退火算法求解TSP原理及C++实现代码_第6张图片

运筹优化学习12:模拟退火算法求解TSP原理及C++实现代码_第7张图片

4 基于C++的简单实现

/*
 * 使用模拟退火算法(SA)求解TSP问题(以中国TSP问题为例)
 * 参考自《Matlab 智能算法30个案例分析》
 */
#include
#include
#include
#include
#include
#define T0 50000.0  // 初始温度
#define T_end (1e-8)
#define q  0.98   // 退火系数
#define L 1000  // 每个温度时的迭代次数,即链长
#define N 31  // 城市数量
int city_list[N]; // 用于存放一个解

// 中国31个城市坐标
double city_pos[N][2] =
    {
    {1304,2312},{3639,1315},{4177,2244},{3712,1399},
    {3488,1535},{3326,1556},{3238,1229},{4196,1004},
    {4312,790},{4386,570},{3007,1970},{2562,1756},
    {2788,1491},{2381,1676},{1332,695},
    {3715,1678},{3918,2179},{4061,2370},
    {3780,2212},{3676,2578},{4029,2838},
    {4263,2931},{3429,1908},{3507,2367},
    {3394,2643},{3439,3201},{2935,3240},
    {3140,3550},{2545,2357},{2778,2826},
    {2370,2975}};

//函数声明
double distance(double *,double *); // 计算两个城市距离
double path_len(int *);  // 计算路径长度
void  init();  //初始化函数
void create_new(); // 产生新解
// 距离函数
double distance(double * city1,double * city2)
{
    double x1 = *city1;
    double y1 = *(city1+1);
    double x2 = *(city2);
    double y2 = *(city2+1);
    double dis = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
    return dis;
}

// 计算路径长度
double path_len(int * arr)
{
    double path = 0; // 初始化路径长度
    int index = *arr; // 定位到第一个数字(城市序号)
    for(int i=0;i T_end) // 当温度低于结束温度时,退火结束
    {
        for(int i=0;i= 0)
            {
                r = ((double)rand())/(RAND_MAX);
                if(exp(-df/T) <= r) // 保留原来的解
                {
                    memcpy(city_list,city_list_copy,N*sizeof(int));
                }
            }
        }
        T *= q; // 降温
        count++;
    }
    finish = clock(); // 退火过程结束
    double duration = ((double)(finish-start))/CLOCKS_PER_SEC; // 计算时间
    printf("模拟退火算法,初始温度T0=%.2f,降温系数q=%.2f,每个温度迭代%d次,共降温%d次,得到的TSP最优路径为:\n",T0,q,L,count);
    for(int i=0;i",city_list[i]);
    }
    printf("%d\n",city_list[N-1]);
    double len = path_len(city_list); // 最优路径长度
    printf("最优路径长度为:%lf\n",len);
    printf("程序运行耗时:%lf秒.\n",duration);
    return 0;
}

运行结果:

运筹优化学习12:模拟退火算法求解TSP原理及C++实现代码_第8张图片

参考文献:

干货 | 用模拟退火(SA, Simulated Annealing)算法解决旅行商问题

 

你可能感兴趣的:(运筹优化学习12:模拟退火算法求解TSP原理及C++实现代码)