• 模拟退火算法(SA)求解旅行商问题(TSP)python


    目录

    一、模拟退火算法求解TSP(city14)的python代码

    二、city14的运行结果

    三、 模拟退火算法求解TSP(city30)的python代码

    四、city30的运行结果

    五、模拟退火算法的python代码(类封装) 


    一、模拟退火算法求解TSP(city14)的python代码

    1. import random
    2. import numpy as np
    3. import math
    4. import matplotlib.pyplot as plt
    5. plt.rcParams['font.sans-serif']=['SimHei']
    6. plt.rcParams['axes.unicode_minus']=False
    7. '''计算路径总路程的函数'''
    8. def fitness(n,X,Y,X0):
    9. '''
    10. :param n: 城市数量
    11. :param X: n个城市的横坐标
    12. :param Y: n个城市的纵坐标
    13. :param X0: 一个解向量
    14. :return: 总路程
    15. '''
    16. s=0
    17. for i in range(n):
    18. if i!=n-1:
    19. s=s+np.sqrt((X[X0[i]]-X[X0[i+1]])**2+(Y[X0[i]]-Y[X0[i+1]])**2)
    20. else:
    21. s=s+np.sqrt((X[X0[i]]-X[X0[0]])**2+(Y[X0[i]]-Y[X0[0]])**2)
    22. return s
    23. '''定义领域搜索运算操作——交换操作'''
    24. def exchange(X0,q):
    25. '''
    26. :param X0: 一个解向量
    27. :param q: 指定的需要交换的数的两个位置的列表,列表长度为2
    28. :return: 一个领域解
    29. '''
    30. X1=X0.copy()
    31. temp=X1[q[0]]
    32. X1[q[0]]=X1[q[1]]
    33. X1[q[1]]=temp
    34. return X1
    35. '''定义随机产生初始解的函数'''
    36. def initialX0(n):
    37. '''
    38. :param n: 城市数量
    39. :return: 一个初始解
    40. '''
    41. X0=random.sample(range(n),n)
    42. return X0
    43. '''模拟退火算法——TSP'''
    44. def SA_TSP(n,X,Y,n_TK,r,T_f):
    45. '''
    46. :param n: 城市数量
    47. :param X: n个城市的横坐标
    48. :param Y: n个城市的纵坐标
    49. :param n_TK: 内循环的迭代次数
    50. :param T_down: 降温变化
    51. :param T_f: 终止温度
    52. :return: 最优路径和最短距离
    53. '''
    54. '''产生一个初始解'''
    55. X0=initialX0(n)
    56. print("初始解:\n{}".format(X0))
    57. print("初始解的总路程:\n{}".format(fitness(n,X,Y,X0)))
    58. '''初始温度'''
    59. T0=1000
    60. '''存储历史最优路径'''
    61. X_min=[]
    62. X_min.append(X0)
    63. '''存储历史最优距离'''
    64. s_min=[]
    65. s_min.append(fitness(n,X,Y,X0))
    66. k=0
    67. while T0>T_f:
    68. for i in range(n_TK):
    69. #随机产生两个位置
    70. q=random.sample(range(n),2)
    71. #领域运算得到一个随机领域解
    72. X1=exchange(X0,q)
    73. #计算初始解和随机领域解的目标函数值
    74. s1=fitness(n,X,Y,X0)
    75. s2=fitness(n,X,Y,X1)
    76. #更新历史最优解
    77. if s2<min(s_min):
    78. s_min.append(s2)
    79. X_min.append(X1)
    80. else:
    81. s_min.append(s_min[-1])
    82. X_min.append(X_min[-1])
    83. '''判断是否更新解'''
    84. if s2
    85. X0=X1
    86. else:
    87. E=math.exp(-(s2-s1)/T0)
    88. R=random.uniform(0,1)
    89. if E>R:
    90. X0=X1
    91. k=k+1
    92. '''降温'''
    93. T0=T0*r
    94. '''绘制优化过程'''
    95. plt.plot(range(k+1),s_min)
    96. plt.grid()
    97. plt.title("模拟退火算法——TSP的优化过程")
    98. plt.xlabel("迭代次数")
    99. plt.ylabel("总路程")
    100. plt.show()
    101. '''绘制路线图'''
    102. #最优路径
    103. W=X_min[-1]
    104. for i in range(n):
    105. if i!=n-1:
    106. plt.plot([X[W[i]],X[W[i+1]]],[Y[W[i]],Y[W[i+1]]],c='plum')
    107. else:
    108. plt.plot([X[W[i]],X[W[0]]],[Y[W[i]],Y[W[0]]],c='plum')
    109. plt.scatter(X,Y,c='red')
    110. plt.title("路线图")
    111. plt.xlabel("x")
    112. plt.ylabel("y")
    113. plt.show()
    114. return X_min[-1],s_min[-1]
    115. '''主函数'''
    116. if __name__=="__main__":
    117. '''城市的数量'''
    118. n=14
    119. '''定义14个城市的坐标'''
    120. city_x=[16.47,16.47,20.09,22.39,25.23,22.00,20.47,17.20,16.30,14.05,16.53,21.52,19.41,20.09]
    121. city_y=[96.10,94.44,92.54,93.37,97.24,96.05,97.02,96.29,97.38,98.12,97.38,95.59,97.13,92.55]
    122. '''内循环的迭代次数'''
    123. n_Tk=200
    124. '''降温变化'''
    125. r=0.9
    126. '''终止温度'''
    127. T_f=0.001
    128. '''模拟退火算法求解TSP'''
    129. Xmin,smin=SA_TSP(n,city_x,city_y,n_Tk,r,T_f)
    130. print("最优路径:\n{}".format(Xmin))
    131. print("最短距离:\n{}".format(smin))

    二、city14的运行结果

     

    三、 模拟退火算法求解TSP(city30)的python代码

    1. import random
    2. import numpy as np
    3. import math
    4. import matplotlib.pyplot as plt
    5. plt.rcParams['font.sans-serif']=['SimHei']
    6. plt.rcParams['axes.unicode_minus']=False
    7. '''计算路径总路程的函数'''
    8. def fitness(n,X,Y,X0):
    9. '''
    10. :param n: 城市数量
    11. :param X: n个城市的横坐标
    12. :param Y: n个城市的纵坐标
    13. :param X0: 一个解向量
    14. :return: 总路程
    15. '''
    16. s=0
    17. for i in range(n):
    18. if i!=n-1:
    19. s=s+np.sqrt((X[X0[i]]-X[X0[i+1]])**2+(Y[X0[i]]-Y[X0[i+1]])**2)
    20. else:
    21. s=s+np.sqrt((X[X0[i]]-X[X0[0]])**2+(Y[X0[i]]-Y[X0[0]])**2)
    22. return s
    23. '''定义领域搜索运算操作——交换操作'''
    24. def exchange(X0,q):
    25. '''
    26. :param X0: 一个解向量
    27. :param q: 指定的需要交换的数的两个位置的列表,列表长度为2
    28. :return: 一个领域解
    29. '''
    30. X1=X0.copy()
    31. temp=X1[q[0]]
    32. X1[q[0]]=X1[q[1]]
    33. X1[q[1]]=temp
    34. return X1
    35. '''定义随机产生初始解的函数'''
    36. def initialX0(n):
    37. '''
    38. :param n: 城市数量
    39. :return: 一个初始解
    40. '''
    41. X0=random.sample(range(n),n)
    42. return X0
    43. '''模拟退火算法——TSP'''
    44. def SA_TSP(n,X,Y,n_TK,r,T_f):
    45. '''
    46. :param n: 城市数量
    47. :param X: n个城市的横坐标
    48. :param Y: n个城市的纵坐标
    49. :param n_TK: 内循环的迭代次数
    50. :param T_down: 降温变化
    51. :param T_f: 终止温度
    52. :return: 最优路径和最短距离
    53. '''
    54. '''产生一个初始解'''
    55. X0=initialX0(n)
    56. print("初始解:\n{}".format(X0))
    57. print("初始解的总路程:\n{}".format(fitness(n,X,Y,X0)))
    58. '''初始温度'''
    59. T0=2000
    60. '''存储历史最优路径'''
    61. X_min=[]
    62. X_min.append(X0)
    63. '''存储历史最优距离'''
    64. s_min=[]
    65. s_min.append(fitness(n,X,Y,X0))
    66. k=0
    67. while T0>T_f:
    68. for i in range(n_TK):
    69. #随机产生两个位置
    70. q=random.sample(range(n),2)
    71. #领域运算得到一个随机领域解
    72. X1=exchange(X0,q)
    73. #计算初始解和随机领域解的目标函数值
    74. s1=fitness(n,X,Y,X0)
    75. s2=fitness(n,X,Y,X1)
    76. #更新历史最优解
    77. if s2<min(s_min):
    78. s_min.append(s2)
    79. X_min.append(X1)
    80. else:
    81. s_min.append(s_min[-1])
    82. X_min.append(X_min[-1])
    83. '''判断是否更新解'''
    84. if s2
    85. X0=X1
    86. else:
    87. E=math.exp(-(s2-s1)/T0)
    88. R=random.uniform(0,1)
    89. if E>R:
    90. X0=X1
    91. k=k+1
    92. '''降温'''
    93. T0=T0*r
    94. '''绘制优化过程'''
    95. plt.plot(range(k+1),s_min)
    96. plt.grid()
    97. plt.title("模拟退火算法——TSP的优化过程")
    98. plt.xlabel("迭代次数")
    99. plt.ylabel("总路程")
    100. plt.show()
    101. '''绘制路线图'''
    102. #最优路径
    103. W=X_min[-1]
    104. for i in range(n):
    105. if i!=n-1:
    106. plt.plot([X[W[i]],X[W[i+1]]],[Y[W[i]],Y[W[i+1]]],c='plum')
    107. else:
    108. plt.plot([X[W[i]],X[W[0]]],[Y[W[i]],Y[W[0]]],c='plum')
    109. plt.scatter(X,Y,c='red')
    110. plt.title("路线图")
    111. plt.xlabel("x")
    112. plt.ylabel("y")
    113. plt.show()
    114. return X_min[-1],s_min[-1]
    115. '''主函数'''
    116. if __name__=="__main__":
    117. '''城市的数量'''
    118. n=30
    119. '''定义30个城市的坐标'''
    120. city_x=[41, 37, 54, 25, 7, 2, 68, 71, 54, 83, 64, 18, 22, 83, 91, 25, 24, 58, 71, 74, 87,
    121. 18, 13, 82, 62, 58, 45,41,44, 4]
    122. city_y=[94, 84, 67, 62, 64, 99, 58, 44, 62, 69, 60, 54, 60, 46, 38, 38, 42, 69, 71, 78, 76,
    123. 40, 40, 7, 32, 35, 21,26,35, 50]
    124. '''内循环的迭代次数'''
    125. n_Tk=300
    126. '''降温变化'''
    127. r=0.9
    128. '''终止温度'''
    129. T_f=0.001
    130. '''模拟退火算法求解TSP'''
    131. Xmin,smin=SA_TSP(n,city_x,city_y,n_Tk,r,T_f)
    132. print("最优路径:\n{}".format(Xmin))
    133. print("最短距离:\n{}".format(smin))

    四、city30的运行结果

     

    五、模拟退火算法的python代码(类封装) 

    1. import random
    2. import numpy as np
    3. import math
    4. import matplotlib.pyplot as plt
    5. plt.rcParams['font.sans-serif']=['SimHei']
    6. plt.rcParams['axes.unicode_minus']=False
    7. class SA_TSP:
    8. def __init__(self,n,X,Y,n_Tk,r,T_f,T0):
    9. self.n=n
    10. self.X=X
    11. self.Y=Y
    12. self.n_Tk=n_Tk
    13. self.r=r
    14. self.T_f=T_f
    15. self.T0=T0
    16. def fitness(self,X0):
    17. s=0
    18. for i in range(self.n):
    19. if i!=self.n-1:
    20. s = s + np.sqrt((self.X[X0[i]] - self.X[X0[i + 1]]) ** 2 + (self.Y[X0[i]] - self.Y[X0[i + 1]]) ** 2)
    21. else:
    22. s = s + np.sqrt((self.X[X0[i]] - self.X[X0[0]]) ** 2 + (self.Y[X0[i]] - self.Y[X0[0]]) ** 2)
    23. return s
    24. def exchange(self,X0,q):
    25. X1=X0.copy()
    26. temp = X1[q[0]]
    27. X1[q[0]] = X1[q[1]]
    28. X1[q[1]] = temp
    29. return X1
    30. def initialX0(self):
    31. X0=random.sample(range(self.n),self.n)
    32. return X0
    33. def SA_tsp(self):
    34. X0=SA_TSP.initialX0(self)
    35. print("初始解:\n{}".format(X0))
    36. print("初始解的总路程:\n{}".format(SA_TSP.fitness(self,X0)))
    37. '''存储历史最优路径'''
    38. X_min = []
    39. X_min.append(X0)
    40. '''存储历史最优距离'''
    41. s_min = []
    42. s_min.append(SA_TSP.fitness(self,X0))
    43. k=0
    44. while self.T0>self.T_f:
    45. for i in range(self.n_Tk):
    46. q=random.sample(range(self.n),2)
    47. X1=SA_TSP.exchange(self,X0,q)
    48. s1=SA_TSP.fitness(self,X0)
    49. s2=SA_TSP.fitness(self,X1)
    50. #更新历史最优解
    51. if s2<min(s_min):
    52. s_min.append(s2)
    53. X_min.append(X1)
    54. else:
    55. s_min.append(s_min[-1])
    56. X_min.append(X_min[-1])
    57. '''判断是否更新解'''
    58. if s2
    59. X0=X1
    60. else:
    61. E=math.exp(-(s2-s1)/self.T0)
    62. R=random.uniform(0,1)
    63. if E>R:
    64. X0=X1
    65. k=k+1
    66. '''降温'''
    67. self.T0=self.T0*self.r
    68. '''绘制优化过程'''
    69. plt.plot(range(k+1),s_min)
    70. plt.grid()
    71. plt.title("模拟退火算法——TSP的优化过程")
    72. plt.xlabel("迭代次数")
    73. plt.ylabel("总路程")
    74. plt.show()
    75. '''绘制路线图'''
    76. #最优路径
    77. W=X_min[-1]
    78. for i in range(self.n):
    79. if i!=self.n-1:
    80. plt.plot([self.X[W[i]],self.X[W[i+1]]],[self.Y[W[i]],self.Y[W[i+1]]],c='plum')
    81. else:
    82. plt.plot([self.X[W[i]],self.X[W[0]]],[self.Y[W[i]],self.Y[W[0]]],c='plum')
    83. plt.scatter(self.X,self.Y,c='red')
    84. plt.title("路线图")
    85. plt.xlabel("x")
    86. plt.ylabel("y")
    87. plt.show()
    88. return X_min[-1],s_min[-1]
    89. '''主函数'''
    90. if __name__=="__main__":
    91. '''城市的数量'''
    92. n=30
    93. '''定义30个城市的坐标'''
    94. city_x=[41, 37, 54, 25, 7, 2, 68, 71, 54, 83, 64, 18, 22, 83, 91, 25, 24, 58, 71, 74, 87,
    95. 18, 13, 82, 62, 58, 45,41,44, 4]
    96. city_y=[94, 84, 67, 62, 64, 99, 58, 44, 62, 69, 60, 54, 60, 46, 38, 38, 42, 69, 71, 78, 76,
    97. 40, 40, 7, 32, 35, 21,26,35, 50]
    98. '''内循环的迭代次数'''
    99. n_Tk=300
    100. '''降温变化'''
    101. r=0.9
    102. '''终止温度'''
    103. T_f=0.001
    104. '''初始温度'''
    105. T0=2000
    106. '''创建对象'''
    107. city30=SA_TSP(n,city_x,city_y,n_Tk,r,T_f,T0)
    108. '''方法'''
    109. Xmin,smin=city30.SA_tsp()
    110. print("最优路径:\n{}".format(Xmin))
    111. print("最短距离:\n{}".format(smin))
  • 相关阅读:
    代码随想录Day02 数组基础2 leetcode T977有序数组的平方, T209 长度最小的子数组,T59 螺旋矩阵II
    UG NX二次开发(C#)-UI Styler-批量选择点
    hive on sparksql 任务卡死
    计算机网络性能
    【字符编码系列一】ASCII编码是什么?
    【ppt密码】ppt的密码忘了,怎么破解
    OceanBase:Zone管理
    软件系统测试有什么注意事项?对软件产品起到什么作用?
    【golang】go 返回参数 以及go中 裸返
    Scratch软件编程等级考试一级——20210626
  • 原文地址:https://blog.csdn.net/m0_70452407/article/details/133965551