日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

模拟退火算法求解旅行商问题(python实现)

發布時間:2024/9/30 python 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 模拟退火算法求解旅行商问题(python实现) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

模擬退火算法求解旅行商問題


文章目錄

  • 模擬退火算法求解旅行商問題
  • 一、模擬退火算法原理
  • 二、旅行商問題
    • 1.求解思路
    • 2.代碼
  • 總結


??????旅行商問題(TSP 問題)。假設有一個旅行商人要拜訪全國31個省會城市,他需要選擇所要走的路徑,路徑的限制是每個城市只能拜訪-一次, 而且最后要回到原來出發的城市。路徑的選擇要求是:所選路徑的路程為所有路徑之中的最小值。


一、模擬退火算法原理

見鏈接:萬字長文了解模擬退火算法原理及求解復雜約束問題(源碼實現)

二、旅行商問題

1.求解思路

??????旅行商問題是一個十分經典的NP難度問題,如果想找到真正的唯一最優的解復雜度是O(N!)的,所以求解這一類問題的策略就是找一個相對最優的解,也就是最優化問題。模擬退火算法就是一種啟發式的組合優算法,通過不斷迭代來尋找最優解。
??????旅行商問題的解可以表述為一個循環排列,我們可以把求解旅行商問題當做把n個城市的全排列進行對比,求最短的一條路徑,但是這樣復雜度太高,這里使用一個叫Mapkob鏈的東西,也就是城市的最排列次數不能超過Mapkob鏈長度(L = 20000)。對于當前已有的排列,產生新排列的過程使用2變換法,也就是在當前的隊列中任選兩個序號u和v(u<v),將u和v及其之間的順序逆轉。在逆轉之后需要重新計算新路徑長度,若新路徑長度小于當前路徑,就用新路徑代替當前路徑,否則使用模擬退火算法根據概率決定是否轉移。

2.代碼

代碼如下(示例):

#!/usr/bin/env python3 # -*- coding: utf-8 -*- # @Author: yudengwu(余登武) # @Date : 2021/6/22 #@email:1344732766@qq.comimport numpy as np import pandas as pd from tqdm import tqdm#進度條設置 import matplotlib.pyplot as plt from pylab import * import matplotlib; matplotlib.use('TkAgg') mpl.rcParams['font.sans-serif'] = ['SimHei'] mpl.rcParams['axes.unicode_minus'] = Falsecity_num = 31 # 城市的數量 #############1.數據集 城市坐標 C=[1304 ,2312,3639 ,1315,4177 ,2244,3712 ,1399,3488, 1535,3326, 1556,3238 ,1229,4196 ,1044,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,2376,3394 ,2643,3439,3201,2935,3240,3140,3550,2545,2357,2778,2826,2370 ,2975] #31個省會城市坐標 C=np.array(C).reshape(-1,2)#shape=(31, 2)###############相關函數:距離和親和度函數(路程) 路徑畫圖函數####################.函數:計算城市之間的距離 def calculate_distance(X, Y):"""計算城市兩輛之間的歐式距離,結果用numpy矩陣存儲:param X: 城市的X坐標,np.array數組:param Y: 城市的Y坐標,np.array數組"""distance_matrix = np.zeros((city_num, city_num))for i in range(city_num):for j in range(city_num):if i == j:continuedis = np.sqrt((X[i] - X[j]) ** 2 + (Y[i] - Y[j]) ** 2) # 歐式距離計算distance_matrix[i][j] = disreturn distance_matrix##適應度函數 計算總距離 def fitness_func(distance_matrix, xi):"""適應度函數,計算目標函數值.:param distance: 城市的距離矩陣:param xi: 的一個解:return: 目標函數值,即總距離"""total_distance = 0for i in range(1, city_num):start = xi[i - 1]end = xi[i]total_distance += distance_matrix[start][end]total_distance += distance_matrix[end][xi[0]] # 從最后一個城市回到出發城市return total_distance#路徑畫圖 def plot_tsp(gbest):"""繪制最優解的圖形"""X=D[:,0]#城市坐標的X軸Y=D[:,1]#城市坐標的Y軸plt.scatter(X, Y, color='r')for i in range(1, city_num):start_x, start_y = X[gbest[i - 1]], Y[gbest[i - 1]]end_x, end_y = X[gbest[i]], Y[gbest[i]]plt.plot([start_x, end_x], [start_y, end_y], marker='>',alpha=0.8)start_x, start_y = X[gbest[0]], Y[gbest[0]]plt.plot([start_x, end_x], [start_y, end_y], color='b', alpha=0.8)plt.show()#=======在現有路徑上采用2變換法,返回新的路徑==== def getNewPath(cur_path):#cur_path=np.random.choice(range(31),31,replace=False)path = cur_path.copy()u = np.random.randint(0,city_num,1)[0]v = np.random.randint(0,city_num,1)[0]while u==v:v = np.random.randint(0, city_num, 1)[0]path[u:v] = list(reversed(path[u:v] ))return path#############模擬退火算法開始############ D=calculate_distance(C[:,0], C[:,1])#任意兩個城市距離間隔矩陣 shape=(31, 31) # 初始溫度,結束溫度 t_init = 50 t_final = 1e-7 # 溫度衰減系數 a = 0.98 # 迭代次數 markovlen = 100def SA_TSP():# 獲取初始距離矩陣D=calculate_distance(C[:,0], C[:,1])#任意兩個城市距離間隔矩陣 shape=(31, 31)# 得到初始解cur_path = np.random.choice(range(city_num),city_num,replace=False)print('初始解\n',cur_path)cur_dis=fitness_func(D, cur_path)print('初始路徑總長度:',cur_dis)best_path = cur_path#最優解best_dis = cur_dis#最優解對應的路徑長度t = t_init#當前溫度while t > t_final:#如果溫度小于最小溫度#print('當前溫度t:',t)for point in range(markovlen):#當前溫度t,進行markovlen次迭代new_path = getNewPath(cur_path)#新的解new_dis = fitness_func(D, new_path)#新的解 對應的路徑長度delt = new_dis - cur_dis #能量差if delt <= 0: # 表示得到優解cur_path = new_pathcur_dis = new_dis#==是否是全局最優解==if best_dis > cur_dis:best_dis = cur_disbest_path = cur_pathelse: # 得到較差解p = np.math.exp(-delt / t)if np.random.random() < p: # 接受差解cur_path = new_pathcur_dis = new_dist *= a # 退火print("城市數量:{}, 最優路徑:{}, 結果距離為:{:.2f}".format(city_num, best_path, best_dis))plot_tsp(best_path)SA_TSP()

總結

結果和之前寫的其它算法版本差不多。其它算法:粒子群、遺傳、差分、免疫、蟻群等 。可以翻翻同專欄的其它文章。


作者:電氣-余登武

總結

以上是生活随笔為你收集整理的模拟退火算法求解旅行商问题(python实现)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。