TSP+SA+python

模拟退火算法求解TSP问题

1. TSP问题简介

旅行商人要拜访n个城市,并最终回到出发城市,要求每个城市只能拜访一次,优化目标是最小化路程之和。

2. 例子求解结果

20个城市坐标:(88, 16),(42, 76),(5, 76),(69, 13),(73, 56),(100, 100),(22, 92),(48, 74),(73, 46),(39, 1),(51, 75),(92, 2),(101, 44),(55, 26),(71, 27),(42, 81),(51, 91),(89, 54),(33, 18),(40, 78)
结果路径图如下:
在这里插入图片描述

3. 模拟退火算法设计

模拟退火算法的(Simulated Annealing,SA)是一种基于概率的全局寻优方法,已在理论上被证明以概率l 收敛于全局最优解。模拟退火算法模拟物理退火过程,从某一较高初温出发,随着温度的不断下降,以一定概率突跳在全局进行寻优,并最终趋于全局最优,搜索过程中趋于零概率的突跳特性可有效避免算法陷入局部最优。模拟退火算法依赖现有求解规则,是一种对已有规则进行改造的算法,它的解与初始值无关;其核心思想是以1概率接受较优解,以较小概率接受裂解(Metropolis准则)。

3.1 实现方法一

思路一求解流程:
(1) 贪婪算法构造初始解作为当前解(SA对初始解不敏感,但贪婪算法构造的初始解能够提高求解效率);
(2) 当前解随机交换生成100个个体,选择最优解作为当代最优解;
(3) 当代最优解优于历史最优解,则更新历史最优解和当前解,否则以一定概率接受当代最优解作为当前解;
(4) 执行退火操作,判断是否满足结束条件,满足退出迭代,否则继续执行步骤(2)-(3)。

# -*- coding: utf-8 -*-
"""
模拟退火算法法求解TSP问题
随机在(0,101)二维平面生成20个点
距离最小化
"""
import math
import random
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']  # 添加这条可以让图形显示中文

#计算路径距离,即评价函数
def calFitness(line,dis_matrix):
dis_sum = 0
dis = 0
for i in range(len(line)):
if i<len(line)-1:
dis = dis_matrix.loc[line[i],line[i+1]]#计算距离
dis_sum = dis_sum+dis
else:
dis = dis_matrix.loc[line[i],line[0]]
dis_sum = dis_sum+dis
return round(dis_sum,1)

def traversal_search(line,dis_matrix):
#随机交换生成100个个体,选择其中表现最好的返回
i = 0#生成个体计数
line_value,line_list = [],[]
while i<=100:
new_line = line.copy()#复制当前路径
exchange_max = random.randint(1,5)#随机生成交换次数,城市数量较多时增加随机数上限效果较好
exchange_time = 0#当前交换次数
while exchange_time <= exchange_max:
pos1,pos2 = random.randint(0,len(line)-1),random.randint(0,len(line)-1)#交换点
new_line[pos1],new_line[pos2]=new_line[pos2],new_line[pos1]#交换生成新路径
exchange_time += 1#更新交换次数

    new_value <span class="token operator">=</span> calFitness<span class="token punctuation">(</span>new_line<span class="token punctuation">,</span>dis_matrix<span class="token punctuation">)</span><span class="token comment">#当前路径距离</span>
    line_list<span class="token punctuation">.</span>append<span class="token punctuation">(</span>new_line<span class="token punctuation">)</span>
    line_value<span class="token punctuation">.</span>append<span class="token punctuation">(</span>new_value<span class="token punctuation">)</span>
    i<span class="token operator">+=</span><span class="token number">1</span>
    
<span class="token keyword">return</span> <span class="token builtin">min</span><span class="token punctuation">(</span>line_value<span class="token punctuation">)</span><span class="token punctuation">,</span>line_list<span class="token punctuation">[</span>line_value<span class="token punctuation">.</span>index<span class="token punctuation">(</span><span class="token builtin">min</span><span class="token punctuation">(</span>line_value<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token comment">#返回表现最好的个体</span>

def greedy(CityCoordinates,dis_matrix):
‘’‘贪婪策略构造初始解’‘’
#转换格式—dis_matrix
dis_matrix = dis_matrix.astype(‘float64’)
for i in range(len(CityCoordinates)):dis_matrix.loc[i,i]=math.pow(10,10)
line = []#初始化
now_city = random.randint(0,len(CityCoordinates)-1)#随机生成出发城市
line.append(now_city)#添加当前城市到路径
dis_matrix.loc[:,now_city] = math.pow(10,10)#更新距离矩阵,已经过城市不再被取出
for i in range(len(CityCoordinates)-1):
next_city = dis_matrix.loc[now_city,:].idxmin()#距离最近的城市
line.append(next_city)#添加进路径
dis_matrix.loc[:,next_city] = math.pow(10,10)#更新距离矩阵
now_city = next_city#更新当前城市

<span class="token keyword">return</span> line

#画路径图
def draw_path(line,CityCoordinates):
x,y= [],[]
for i in line:
Coordinate = CityCoordinates[i]
x.append(Coordinate[0])
y.append(Coordinate[1])
x.append(x[0])
y.append(y[0])

plt<span class="token punctuation">.</span>plot<span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">,</span><span class="token string">'r-'</span><span class="token punctuation">,</span> color<span class="token operator">=</span><span class="token string">'#4169E1'</span><span class="token punctuation">,</span> alpha<span class="token operator">=</span><span class="token number">0.8</span><span class="token punctuation">,</span> linewidth<span class="token operator">=</span><span class="token number">0.8</span><span class="token punctuation">)</span>
plt<span class="token punctuation">.</span>xlabel<span class="token punctuation">(</span><span class="token string">'x'</span><span class="token punctuation">)</span>
plt<span class="token punctuation">.</span>ylabel<span class="token punctuation">(</span><span class="token string">'y'</span><span class="token punctuation">)</span>
plt<span class="token punctuation">.</span>show<span class="token punctuation">(</span><span class="token punctuation">)</span>

if name == main:
#参数
CityNum = 20#城市数量
MinCoordinate = 0#二维坐标最小值
MaxCoordinate = 101#二维坐标最大值

<span class="token comment">#SA参数</span>
Tend <span class="token operator">=</span> <span class="token number">0.1</span><span class="token comment">#终止温度</span>
T <span class="token operator">=</span> <span class="token number">100</span><span class="token comment">#初温</span>
beta <span class="token operator">=</span> <span class="token number">0.99</span><span class="token comment">#退火步长</span>


best_value <span class="token operator">=</span> math<span class="token punctuation">.</span><span class="token builtin">pow</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token comment">#较大的初始值,存储最优解</span>
best_line <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token comment">#存储最优路径</span>

<span class="token comment">#随机生成城市数据,城市序号为0,1,2,3...</span>
<span class="token comment"># CityCoordinates = [(random.randint(MinCoordinate,MaxCoordinate),random.randint(MinCoordinate,MaxCoordinate)) for i in range(CityNum)]</span>
CityCoordinates <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">(</span><span class="token number">88</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">42</span><span class="token punctuation">,</span> <span class="token number">76</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">76</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">69</span><span class="token punctuation">,</span> <span class="token number">13</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">73</span><span class="token punctuation">,</span> <span class="token number">56</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">22</span><span class="token punctuation">,</span> <span class="token number">92</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">48</span><span class="token punctuation">,</span> <span class="token number">74</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">73</span><span class="token punctuation">,</span> <span class="token number">46</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">39</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">51</span><span class="token punctuation">,</span> <span class="token number">75</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">92</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">101</span><span class="token punctuation">,</span> <span class="token number">44</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">55</span><span class="token punctuation">,</span> <span class="token number">26</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">71</span><span class="token punctuation">,</span> <span class="token number">27</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">42</span><span class="token punctuation">,</span> <span class="token number">81</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">51</span><span class="token punctuation">,</span> <span class="token number">91</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">89</span><span class="token punctuation">,</span> <span class="token number">54</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">33</span><span class="token punctuation">,</span> <span class="token number">18</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">40</span><span class="token punctuation">,</span> <span class="token number">78</span><span class="token punctuation">)</span><span class="token punctuation">]</span>

<span class="token comment">#计算城市之间的距离</span>
dis_matrix <span class="token operator">=</span> pd<span class="token punctuation">.</span>DataFrame<span class="token punctuation">(</span>data<span class="token operator">=</span><span class="token boolean">None</span><span class="token punctuation">,</span>columns<span class="token operator">=</span><span class="token builtin">range</span><span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>CityCoordinates<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>index<span class="token operator">=</span><span class="token builtin">range</span><span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>CityCoordinates<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>CityCoordinates<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    xi<span class="token punctuation">,</span>yi <span class="token operator">=</span> CityCoordinates<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span>CityCoordinates<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span>
    <span class="token keyword">for</span> j <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>CityCoordinates<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
        xj<span class="token punctuation">,</span>yj <span class="token operator">=</span> CityCoordinates<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span>CityCoordinates<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span>
        dis_matrix<span class="token punctuation">.</span>iloc<span class="token punctuation">[</span>i<span class="token punctuation">,</span>j<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token builtin">round</span><span class="token punctuation">(</span>math<span class="token punctuation">.</span>sqrt<span class="token punctuation">(</span><span class="token punctuation">(</span>xi<span class="token operator">-</span>xj<span class="token punctuation">)</span><span class="token operator">**</span><span class="token number">2</span><span class="token operator">+</span><span class="token punctuation">(</span>yi<span class="token operator">-</span>yj<span class="token punctuation">)</span><span class="token operator">**</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">)</span>


<span class="token comment"># 随机构造初始解</span>
<span class="token comment"># line = list(range(len(CityCoordinates)));random.shuffle(line)</span>
<span class="token comment"># value = calFitness(line,dis_matrix)#初始路径距离</span>

<span class="token comment"># 贪婪构造初始解</span>
line <span class="token operator">=</span> greedy<span class="token punctuation">(</span>CityCoordinates<span class="token punctuation">,</span>dis_matrix<span class="token punctuation">)</span>
value <span class="token operator">=</span> calFitness<span class="token punctuation">(</span>line<span class="token punctuation">,</span>dis_matrix<span class="token punctuation">)</span><span class="token comment">#初始路径距离</span>


<span class="token comment">#存储当前最优</span>
best_value<span class="token punctuation">,</span>best_line <span class="token operator">=</span> value<span class="token punctuation">,</span>line
draw_path<span class="token punctuation">(</span>best_line<span class="token punctuation">,</span>CityCoordinates<span class="token punctuation">)</span><span class="token comment">#初始路径</span>

<span class="token keyword">while</span> T <span class="token operator">&gt;=</span> Tend<span class="token punctuation">:</span>
    new_value<span class="token punctuation">,</span>new_line <span class="token operator">=</span> traversal_search<span class="token punctuation">(</span>line<span class="token punctuation">,</span>dis_matrix<span class="token punctuation">)</span>
    <span class="token comment"># print(random.random(),math.exp(-(new_value-value)/T))</span>
    
    <span class="token keyword">if</span> new_value <span class="token operator">&lt;=</span> best_value<span class="token punctuation">:</span><span class="token comment">#优于最优解</span>
        best_value<span class="token punctuation">,</span>best_line <span class="token operator">=</span> new_value<span class="token punctuation">,</span>new_line<span class="token comment">#更新最优解</span>
        line<span class="token punctuation">,</span>value <span class="token operator">=</span> new_line<span class="token punctuation">,</span>new_value<span class="token comment">#更新当前解</span>
    <span class="token keyword">elif</span> random<span class="token punctuation">.</span>random<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> math<span class="token punctuation">.</span>exp<span class="token punctuation">(</span><span class="token operator">-</span><span class="token punctuation">(</span>new_value<span class="token operator">-</span>value<span class="token punctuation">)</span><span class="token operator">/</span>T<span class="token punctuation">)</span><span class="token punctuation">:</span>
        line<span class="token punctuation">,</span>value <span class="token operator">=</span> new_line<span class="token punctuation">,</span>new_value<span class="token comment">#更新当前解</span>
    <span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">'当前最优值 %.1f'</span> <span class="token operator">%</span> <span class="token punctuation">(</span>best_value<span class="token punctuation">)</span><span class="token punctuation">)</span>
    T <span class="token operator">*=</span> beta

<span class="token comment">#路径顺序</span>
<span class="token keyword">print</span><span class="token punctuation">(</span>best_line<span class="token punctuation">)</span>
<span class="token comment">#画图</span>
draw_path<span class="token punctuation">(</span>best_line<span class="token punctuation">,</span>CityCoordinates<span class="token punctuation">)</span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139

3.2 实现方法二

思路二:模拟退火算法擅长改造现有求解规则,本算法引入模拟退火思想对贪婪构造过程进行扰动,以扩大搜索空间。首先认为贪婪构造中选择距当前城市最近的城市作为下一个城市是最优的,在此基础上引入概率,以p概率接受最近城市作为下一个城市,以p2概率接受第二近的城市,以p3概率接受第三个城市,以此类推,当前面的最近城市都不接受作为下一个城市时,最后一个城市则必须接受。概率p尝试采用S型函数p = 1/(1+math.exp(-0.03*T)),概率随T变小而变小,p的值域为(0.5,1)。

# -*- coding: utf-8 -*-
"""
模拟退火算法法求解TSP问题
随机在(0,101)二维平面生成20个点
距离最小化
"""
import math
import random
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']  # 添加这条可以让图形显示中文

#计算路径距离,即评价函数
def calFitness(line,dis_matrix):
dis_sum = 0
dis = 0
for i in range(len(line)):
if i<len(line)-1:
dis = dis_matrix.loc[line[i],line[i+1]]#计算距离
dis_sum = dis_sum+dis
else:
dis = dis_matrix.loc[line[i],line[0]]
dis_sum = dis_sum+dis
return round(dis_sum,1)

def greedy(CityCoordinates,dis_matrix,p):
‘’‘贪婪策略构造初始解,基于概率扰动’‘’
#更改dis_matrix格式
dis_matrix = dis_matrix.astype(‘float64’)
for i in range(len(CityCoordinates)):dis_matrix.loc[i,i]=math.pow(10,10)
line = []#初始化,存放路径
now_city = random.randint(0,len(CityCoordinates)-1)#随机生成出发城市
line.append(now_city)#添加当前城市到路径
dis_matrix.loc[:,now_city] = math.pow(10,10)#更新距离矩阵,已途径城市不再被取出

i <span class="token operator">=</span> <span class="token number">1</span><span class="token comment">#当前已排好城市个数</span>
j <span class="token operator">=</span> <span class="token number">0</span><span class="token comment">#记录当前城市已遍历临近城市次数</span>
<span class="token keyword">while</span> <span class="token builtin">len</span><span class="token punctuation">(</span>CityCoordinates<span class="token punctuation">)</span><span class="token operator">-</span>i<span class="token operator">&gt;</span><span class="token number">0</span><span class="token punctuation">:</span>
    next_city <span class="token operator">=</span> dis_matrix<span class="token punctuation">.</span>loc<span class="token punctuation">[</span>now_city<span class="token punctuation">,</span><span class="token punctuation">:</span><span class="token punctuation">]</span><span class="token punctuation">.</span>idxmin<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token comment">#距离该城市最近的城市</span>
    j <span class="token operator">+=</span> <span class="token number">1</span>
    <span class="token keyword">if</span> j <span class="token operator">==</span> <span class="token builtin">len</span><span class="token punctuation">(</span>CityCoordinates<span class="token punctuation">)</span><span class="token operator">-</span>i<span class="token punctuation">:</span><span class="token comment">#是否为当前可遍历最后一个城市,是则直接添加——防止所有城市都不被取出的情况</span>
        line<span class="token punctuation">.</span>append<span class="token punctuation">(</span>next_city<span class="token punctuation">)</span><span class="token comment">#添加进路径</span>
        dis_matrix<span class="token punctuation">.</span>loc<span class="token punctuation">[</span><span class="token punctuation">:</span><span class="token punctuation">,</span>next_city<span class="token punctuation">]</span> <span class="token operator">=</span> math<span class="token punctuation">.</span><span class="token builtin">pow</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token comment">#更新距离矩阵</span>
        now_city <span class="token operator">=</span> next_city<span class="token comment">#更新当前城市</span>
        i <span class="token operator">+=</span> <span class="token number">1</span>
        j <span class="token operator">=</span> <span class="token number">0</span><span class="token comment">#重置</span>
    <span class="token keyword">else</span><span class="token punctuation">:</span>
        <span class="token keyword">if</span> random<span class="token punctuation">.</span>random<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> p<span class="token punctuation">:</span>
            line<span class="token punctuation">.</span>append<span class="token punctuation">(</span>next_city<span class="token punctuation">)</span><span class="token comment">#添加进路径</span>
            dis_matrix<span class="token punctuation">.</span>loc<span class="token punctuation">[</span><span class="token punctuation">:</span><span class="token punctuation">,</span>next_city<span class="token punctuation">]</span> <span class="token operator">=</span> math<span class="token punctuation">.</span><span class="token builtin">pow</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token comment">#更新距离矩阵</span>
            now_city <span class="token operator">=</span> next_city<span class="token comment">#更新当前城市</span>
            i <span class="token operator">+=</span> <span class="token number">1</span>
            j <span class="token operator">=</span> <span class="token number">0</span><span class="token comment">#重置</span>
        <span class="token keyword">else</span><span class="token punctuation">:</span>
            <span class="token comment">#不接受当前城市作为下一个城市</span>
            dis_matrix<span class="token punctuation">.</span>loc<span class="token punctuation">[</span>now_city<span class="token punctuation">,</span>next_city<span class="token punctuation">]</span> <span class="token operator">=</span> math<span class="token punctuation">.</span><span class="token builtin">pow</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token comment">#更新距离矩阵</span>
<span class="token keyword">return</span> line

#画路径图
def draw_path(line,CityCoordinates):
x,y= [],[]
for i in line:
Coordinate = CityCoordinates[i]
x.append(Coordinate[0])
y.append(Coordinate[1])
x.append(x[0])
y.append(y[0])
plt.plot(x, y,‘r-’, color=‘#4169E1’, alpha=0.8, linewidth=0.8)
plt.xlabel(‘x’)
plt.ylabel(‘y’)
plt.show()

if name == main:
#参数
CityNum = 20#城市数量
MinCoordinate = 0#二维坐标最小值
MaxCoordinate = 101#二维坐标最大值

<span class="token comment">#SA参数</span>
Tend <span class="token operator">=</span> <span class="token number">0.1</span>
T <span class="token operator">=</span> <span class="token number">100</span>
beta <span class="token operator">=</span> <span class="token number">0.98</span>
<span class="token comment">#p = 1/(1+math.exp(-0.03*T)) #S型曲线</span>

best_value <span class="token operator">=</span> math<span class="token punctuation">.</span><span class="token builtin">pow</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token comment">#较大的初始值,存储最优解</span>
best_line <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token comment">#存储最优路径</span>

<span class="token comment">#随机生成城市数据,城市序号为0,1,2,3...</span>
<span class="token comment"># CityCoordinates = [(random.randint(MinCoordinate,MaxCoordinate),random.randint(MinCoordinate,MaxCoordinate)) for i in range(CityNum)]</span>
CityCoordinates <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">(</span><span class="token number">88</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">42</span><span class="token punctuation">,</span> <span class="token number">76</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">76</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">69</span><span class="token punctuation">,</span> <span class="token number">13</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">73</span><span class="token punctuation">,</span> <span class="token number">56</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">22</span><span class="token punctuation">,</span> <span class="token number">92</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">48</span><span class="token punctuation">,</span> <span class="token number">74</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">73</span><span class="token punctuation">,</span> <span class="token number">46</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">39</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">51</span><span class="token punctuation">,</span> <span class="token number">75</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">92</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">101</span><span class="token punctuation">,</span> <span class="token number">44</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">55</span><span class="token punctuation">,</span> <span class="token number">26</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">71</span><span class="token punctuation">,</span> <span class="token number">27</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">42</span><span class="token punctuation">,</span> <span class="token number">81</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">51</span><span class="token punctuation">,</span> <span class="token number">91</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">89</span><span class="token punctuation">,</span> <span class="token number">54</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">33</span><span class="token punctuation">,</span> <span class="token number">18</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">40</span><span class="token punctuation">,</span> <span class="token number">78</span><span class="token punctuation">)</span><span class="token punctuation">]</span>

<span class="token comment">#计算城市间距离</span>
dis_matrix <span class="token operator">=</span> pd<span class="token punctuation">.</span>DataFrame<span class="token punctuation">(</span>data<span class="token operator">=</span><span class="token boolean">None</span><span class="token punctuation">,</span>columns<span class="token operator">=</span><span class="token builtin">range</span><span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>CityCoordinates<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>index<span class="token operator">=</span><span class="token builtin">range</span><span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>CityCoordinates<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>CityCoordinates<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
    xi<span class="token punctuation">,</span>yi <span class="token operator">=</span> CityCoordinates<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span>CityCoordinates<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span>
    <span class="token keyword">for</span> j <span class="token keyword">in</span> <span class="token builtin">range</span><span class="token punctuation">(</span><span class="token builtin">len</span><span class="token punctuation">(</span>CityCoordinates<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
        xj<span class="token punctuation">,</span>yj <span class="token operator">=</span> CityCoordinates<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span>CityCoordinates<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span>
        dis_matrix<span class="token punctuation">.</span>iloc<span class="token punctuation">[</span>i<span class="token punctuation">,</span>j<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token builtin">round</span><span class="token punctuation">(</span>math<span class="token punctuation">.</span>sqrt<span class="token punctuation">(</span><span class="token punctuation">(</span>xi<span class="token operator">-</span>xj<span class="token punctuation">)</span><span class="token operator">**</span><span class="token number">2</span><span class="token operator">+</span><span class="token punctuation">(</span>yi<span class="token operator">-</span>yj<span class="token punctuation">)</span><span class="token operator">**</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">)</span>

<span class="token comment">#循环</span>
<span class="token keyword">while</span> T <span class="token operator">&gt;=</span> Tend<span class="token punctuation">:</span>
    p <span class="token operator">=</span> <span class="token number">1</span><span class="token operator">/</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token operator">+</span>math<span class="token punctuation">.</span>exp<span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">0.03</span><span class="token operator">*</span>T<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token comment">#概率</span>
    line <span class="token operator">=</span> greedy<span class="token punctuation">(</span>CityCoordinates<span class="token punctuation">,</span>dis_matrix<span class="token punctuation">,</span>p<span class="token punctuation">)</span><span class="token comment">#路径</span>
    value <span class="token operator">=</span> calFitness<span class="token punctuation">(</span>line<span class="token punctuation">,</span>dis_matrix<span class="token punctuation">)</span><span class="token comment">#路径距离</span>
    <span class="token keyword">if</span> value <span class="token operator">&lt;</span> best_value<span class="token punctuation">:</span><span class="token comment">#优于最优解</span>
        best_value<span class="token punctuation">,</span>best_line <span class="token operator">=</span> value<span class="token punctuation">,</span>line<span class="token comment">#更新最优解</span>
        <span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">"当前最优解%.1f"</span> <span class="token operator">%</span> <span class="token punctuation">(</span>best_value<span class="token punctuation">)</span><span class="token punctuation">)</span>
    T <span class="token operator">*=</span> beta<span class="token comment">#更新T</span>

<span class="token comment">#路径顺序</span>
<span class="token keyword">print</span><span class="token punctuation">(</span>best_line<span class="token punctuation">)</span>
<span class="token comment">#画路径图</span>
draw_path<span class="token punctuation">(</span>best_line<span class="token punctuation">,</span>CityCoordinates<span class="token punctuation">)</span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118

TSP系列目录
智能优化算法类别启发式算法求解TSP问题系列博文
进化算法遗传算法求解TSP问题
仿人智能优化算法禁忌搜索算法求解TSP问题
仿自然优化算法模拟退火算法求解TSP问题
群智能优化算法蚁群算法求解TSP问题
群智能优化算法粒子群算法求解TSP问题
总结篇五种常见启发式算法求解TSP问题
改进篇遗传-粒子群算法&遗传-禁忌搜索算法求解TSP问题

记录学习过程,欢迎指正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值