TSP(中国旅行商问题)
本次博客是對(duì)于博客提出疑問的思考與實(shí)踐。
目錄
- 1. 問題描述
- 2. 現(xiàn)有的解決辦法
- 2.1 模擬退火算法
- 2.2 遺傳算法
- 2.2.1 遺傳算法簡(jiǎn)介
- 2.2.2 遺傳算法在TSP問題中的使用
四個(gè)圖論經(jīng)典問題
在這里主要討論第四個(gè)問題,中國(guó)郵政問題
1. 問題描述
給定一些城市與城市之間的距離,求解訪問每座城市一次且能返回出發(fā)點(diǎn)的最短路徑。
其圖論描述為:
給定圖G=(V,A)\mathrm{G }= (\mathrm{V},\mathrm{ A})G=(V,A),其中V\mathrm{V}V為頂點(diǎn)集,A\mathrm{A}A為各頂點(diǎn)相互連接的邊集,設(shè)d(ij)d(_{ij})d(ij?)是由頂點(diǎn)i和頂點(diǎn)j之間的距離所產(chǎn)生的距離矩陣,要求確定一條hamilton回路,即遍歷所有頂點(diǎn)當(dāng)且僅當(dāng)一次的最短距離。
旅行商問題可分為如下兩類:
其中,非對(duì)稱旅行商問題較難求解,我們一般討論對(duì)稱旅行商問題。
旅行商問題數(shù)學(xué)模型:
min?ti∈T∑i=1nd(ti,ti+1))\min_{t_i \in \mathrm{T}}{\sum_{i=1}^n}{d(t_{i},t_{i+1}))}ti?∈Tmin?i=1∑n?d(ti?,ti+1?))
T={t1,t2,…,tn}\mathrm{T} = \{t_1, t_2, \dots, t_n\}T={t1?,t2?,…,tn?}代表對(duì)于城市V={v1,v2,…,vn}\mathrm{V}=\{v_1, v_2, \dots, v_n\}V={v1?,v2?,…,vn?}的一個(gè)訪問順序,其中ti∈V,i∈{1,2,…,n}且tn+1=t1t_i \in \mathrm{V}, i\in\{1, 2, \dots, n\}且t_{n+1} = t_1ti?∈V,i∈{1,2,…,n}且tn+1?=t1?。
該問題是一個(gè)典型的優(yōu)化組合難題,已被證實(shí)屬于NP完全問題,即沒有確定的算法能在多項(xiàng)式時(shí)間內(nèi)得到問題的最優(yōu)解。1
2. 現(xiàn)有的解決辦法
現(xiàn)有數(shù)據(jù)集
數(shù)據(jù)集讀取: tsplib95
巡回旅行商問題是典型的NP難題。如果使用暴力搜索求解TSP問題,其時(shí)間復(fù)雜度為O((n?1)!)O((n-1)!)O((n?1)!),減一是因?yàn)槠鹗键c(diǎn)確定。基于TSP的問題特性,構(gòu)造性算法成為最先開發(fā)的求解算法,如最近領(lǐng)點(diǎn),最近合并,最近插入,最遠(yuǎn)插入,最近添加,貪婪插入等。但是由于構(gòu)造性算法優(yōu)化質(zhì)量較差,迄今為止已開發(fā)了許多性能較好的改進(jìn)型搜索算法。主要有:
2.1 模擬退火算法
模擬退火算法思想:
模擬退火算法區(qū)別于爬山思想(只向比當(dāng)前高的地方爬,容易陷入局部極小值),就是加入了一個(gè)概率方程組指導(dǎo)決策:
Pk(i→j)={1,f(i)≤f(j)exp?(?f(i)?f(j)t),otherwiseP_k{(i\to j)} = \begin{cases} 1,f(i)\leq f(j) \\ \exp{(-\frac{f(i)-f(j)}{t})},\textrm{otherwise} \end{cases} Pk?(i→j)={1,f(i)≤f(j)exp(?tf(i)?f(j)?),otherwise?
其中f(i)f(i)f(i)表示適應(yīng)度函數(shù),t表示溫度。
概率方程翻譯過來(lái)表示,當(dāng)溫度t較大的時(shí)候,接受比當(dāng)前差的狀態(tài)轉(zhuǎn)移;當(dāng)溫度較小的時(shí)候,只接受比當(dāng)前好的狀態(tài)轉(zhuǎn)移。
偽代碼:
用python實(shí)現(xiàn)代碼:(dantzig42.tsp)
# 模擬退火算法import tsplib95 import numpy as np import random import math import json# 初始溫度值 t_high = 10000temperature = 10000# 溫度下界 t_low = 0.1# 冷卻速度 cool_rate = 0.001# tsplib文件路徑 path = "D:\\dataset\\tsp\\dantzig42.tsp\\dantzig42.tsp"def read_tsp_question(tsp_path):return tsplib95.load(tsp_path)def calculate_seq_distance(city_seq):distance = 0for i in np.arange(0, len(city_seq)-1):distance += problem.get_weight(city_seq[i], city_seq[i+1])# print("city_seq[{}], city_seq[{}] distance = {}".format(i,i+1,problem.get_weight(city_seq[i], city_seq[i+1])))distance += problem.get_weight(city_seq[len(city_seq)-1], city_seq[0])return distancedef get_new_city_seq(city_seq):new_city_seq = city_seq.copy()# 隨機(jī)選擇兩個(gè)位點(diǎn), 交換兩個(gè)城市的位置first_index = random.randint(0, len(city_seq)-1)second_index = random.randint(0, len(city_seq)-1)while first_index == second_index:second_index = random.randint(0, len(city_seq) - 1)temp = new_city_seq[first_index]new_city_seq[first_index] = new_city_seq[second_index]new_city_seq[second_index] = tempreturn new_city_seqdef initial_sequence(city_num):initial_seq = np.arange(1, city_num + 1)initial_seq[10] = 32initial_seq[31] = 11seq_str = "[1,2,25,4,5,6,7,8,9,10,32,12,13,14,15,21,17,18,19,20,16,22,23,24,3,26,27,28,29,30,31,36,33,34,35,11,37,38,39,40,41,42]"initial_seq = json.loads(seq_str)return initial_seqdef acceptance_probability(next_distance, current_distance, temperature):if next_distance < current_distance:return 2else:return math.exp((current_distance-next_distance)/temperature)if __name__ == "__main__":problem = read_tsp_question(path)# 城市數(shù)量city_num = problem.dimension# 循環(huán)中最好的城市序列best_city_sequence = Nonebest_distance = -1# 當(dāng)前的城市序列current_city_seq = Nonecurrent_distance = -1# 下一步的城市序列next_city_seq = Nonewhile temperature >= t_low:if temperature == t_high and current_city_seq is None:current_city_seq = initial_sequence(city_num)best_city_sequence = current_city_seqcurrent_distance = calculate_seq_distance(current_city_seq)best_distance = current_distanceprint("initial_distance = {}".format(current_distance))next_city_seq = get_new_city_seq(current_city_seq)next_distance = calculate_seq_distance(next_city_seq)if acceptance_probability(next_distance, current_distance, temperature) > random.random():current_city_seq = next_city_seqcurrent_distance = next_distanceif current_distance < best_distance:best_city_sequence = current_city_seqbest_distance = current_distance# print("current_distance = {}\n".format(current_distance))temperature *= (1-cool_rate)print("best_city_seq: {}".format(best_city_sequence))print("best_distance: {}".format(best_distance))由于∪i=142{xi∣xi=i}\cup_{i=1}^{42}\{x_i|x_i =i\}∪i=142?{xi?∣xi?=i}就是最優(yōu)解(dantzig42 : 699),就初始化一個(gè)距離為1287的序列當(dāng)作初始解,體現(xiàn)模擬退火算法的優(yōu)化效果。
2.2 遺傳算法
2.2.1 遺傳算法簡(jiǎn)介
遺傳算法是一種基于自然選擇與基因遺傳學(xué)原理的隨機(jī)并行搜索算法,是一種尋找全局最優(yōu)且不需要任何初始化信息的高效優(yōu)化方法。它將問題的解集看做是一個(gè)種群,通過不斷的選擇、交叉、變異等遺傳操作,使解的質(zhì)量越來(lái)越好。該算法具有全局尋優(yōu)能力,適用性、解決非線性優(yōu)化問題具有較強(qiáng)的魯棒性。對(duì)問題沒有特定限制、計(jì)算過程簡(jiǎn)單、對(duì)搜索空間沒有特殊要求、易于與其他算法結(jié)合等特點(diǎn),,在函數(shù)優(yōu)化、圖像處理、系統(tǒng)辨識(shí)、自動(dòng)控制、經(jīng)濟(jì)預(yù)測(cè)和工程優(yōu)化等領(lǐng)域得到了廣泛的應(yīng)用, 在求解NP完全問題方面是一種較為有效的全局方法。1
簡(jiǎn)單遺傳算法求解 TSP 問題的主要計(jì)算過程如下:
Step 1: 確定編碼機(jī)制, 生成初始種群。解決 TSP問題通常采用城市序號(hào)對(duì)路徑進(jìn)行編碼, 按照訪問城市的順序排列組成編碼。
Step 2: 計(jì)算種群中每個(gè)個(gè)體的適應(yīng)度值.。TSP 求解是要尋找使目標(biāo)函數(shù)最小的個(gè)體, 因此選擇適應(yīng)度函數(shù) fitness(𝑖) = 𝐷/𝑓(𝑅𝑖).。設(shè)置常數(shù)𝐷, 防止路徑值過大而導(dǎo)致適應(yīng)度函數(shù)倒數(shù)接近于 0。 可以看出, 巡游路徑越小, 適應(yīng)度值越大。
Step 3: 選擇算子。通常采用精英個(gè)體保存策略和賭輪選擇算子, 即適應(yīng)度最高的個(gè)體一定被選擇. 計(jì)算每個(gè)個(gè)體在整個(gè)種群適應(yīng)度中的被選擇概率和累計(jì)概率分別為pi=fitness(i)∑i=1popsizefitness(i)p_i=\frac{\textrm{fitness}(i)}{\sum_{i=1}^{\textrm{popsize}}\textrm{fitness}(i)}pi?=∑i=1popsize?fitness(i)fitness(i)?, Qi=∑j=1ip(j)Q_i = \sum_{j=1}^ip(j)Qi?=∑j=1i?p(j)。通過隨機(jī)數(shù) 𝑟 所在的區(qū)間范圍選擇遺傳個(gè)體。
Step 4: 交叉算子.。由交叉概率 𝑝𝑐 選擇若干父體并進(jìn)行配對(duì), 按照交叉算法的規(guī)則生成新個(gè)體, 常用的規(guī)范方法有單點(diǎn)交叉、部分映射交叉、循環(huán)交叉等。
Step 5: 變異算子。為了保持種群個(gè)體的多樣性,防止陷入局部最優(yōu), 需要按照某一變異概率 𝑝𝑚 隨機(jī)確定變異個(gè)體, 并實(shí)行相應(yīng)變異操作, 通常采用逆序變異算子。
Step 6: 迭代終止條件。 若滿足預(yù)定的終止條件(達(dá)到最大迭代次數(shù)), 則停止迭代, 所得的路徑認(rèn)為是滿意的路徑; 否則, 轉(zhuǎn)至 Step 2, 計(jì)算新一代種群中每個(gè)個(gè)體的適應(yīng)度值。
簡(jiǎn)單遺傳算法往往存在收斂速度慢、易陷入局部最優(yōu)和優(yōu)化精度低等明顯不足。 如何在提高算法收斂速度的同時(shí)確保種群多樣性, 使尋優(yōu)結(jié)果接近最優(yōu)解是遺傳算法不斷改進(jìn)的目標(biāo)。
2.2.2 遺傳算法在TSP問題中的使用
上述對(duì)于遺傳算法的描述是通用的,只是闡述了遺傳算法的思想與基本的步驟。閱讀了幾篇用遺傳算法求解TSP問題的論文,優(yōu)化方法包括了上述的六步。比如說(shuō),第一步中的初始化種群,就有提出使用貪婪算法生成初始化種群的。
編碼方式:
最常規(guī)的編碼方式為二進(jìn)制編碼,但是不使用于此問題。此問題的一個(gè)組合形如(4,2,1,3,4)(4,2,1,3,4)(4,2,1,3,4),每個(gè)數(shù)字代表一個(gè)城市,一個(gè)序列代表著游覽城市的序列,是一個(gè)回路。如果使用二進(jìn)制編碼,不僅要考慮數(shù)據(jù)溢出的問題,而且還要考慮交叉之后的序列存在重復(fù)城市編號(hào)。
TSP問題中的交叉算子:
路徑表示(path representation)是表示旅程對(duì)應(yīng)的基因編碼的最自然、最簡(jiǎn)單的表示方法。例如,旅程 5-1-7-8-9-4-6-2-3 可以直接表示為(5 1 7 8 9 4 6 2 3),基于路徑表示的編碼方法,要求一個(gè)個(gè)體(即一條旅程)的染色體編碼中不允許有重復(fù)的基因碼,也就是說(shuō)要滿足任一個(gè)城市必須而且只能訪問一次的約束。這樣,基本遺傳算法的交叉操作生成的個(gè)體一般不能滿足這一約束條件。為此,人們提出了一個(gè)稱為重排操作的新操作來(lái)處理這類表示問題,它包括三種操作:部分匹配交叉(Partially Matched Crossover,PMX)、郭濤交叉(Guo Tao Crossover,GTX)、循環(huán)交叉(Cycle Crossover,CX)。主要是在傳統(tǒng)交叉操作上加入了“不允許有重復(fù)基因碼”的限制。
下述是遺傳算法選擇,交叉,變異的常見算法:2
選擇算子:
| 1 | 輪盤賭選擇(回放式隨機(jī)采樣) | 選擇誤差較大 | DeJong,Brindle |
| 2 | 無(wú)回放式隨機(jī)采樣 | 降低選擇誤差,復(fù)制數(shù)(f/(f+1)),操作不便 | DeJong,Brindle |
| 3 | 確定采樣 | 選擇誤差更小,操作簡(jiǎn)易 | Brindle |
| 4 | 柔性分段式選擇 | 有效防止基因缺失但需要選擇有關(guān)參數(shù) | Yun |
| 5 | 自適應(yīng)柔性分段式動(dòng)態(tài)群體采樣 | 群體自適應(yīng)變化,提高搜索效率 | Yun |
| 6 | 無(wú)放回式余數(shù)隨機(jī)采樣 | 群體自適應(yīng)變化,提高搜索效率 | DeJong,Brindle |
| 7 | 均勻排序 | 與適應(yīng)度的大小差異程序正負(fù)無(wú)關(guān) | Back |
| 8 | 穩(wěn)態(tài)選擇 | 保留父代中的一些高適應(yīng)度的串 | Syswerda |
| 9 | 隨機(jī)比賽 | Brindle | |
| 10 | 選擇評(píng)價(jià) | Whitley | |
| 11 | 最優(yōu)串選擇 | 全局收斂,提高搜索效率 | DeJong.Back |
| 12 | 最優(yōu)串保留 | 保證全局收斂 | Yun |
| 13 | 適應(yīng)度線性尺度變換 | 簡(jiǎn)單,可消除遺傳早期的超級(jí)串現(xiàn)象 | Bagley |
| 14 | 適應(yīng)度指數(shù)尺度變換 | Gillies | |
| 15 | 適應(yīng)度自適應(yīng)線性尺度變換 | 符合遺傳機(jī)理 | Yun |
交叉算子:
| 1 | 單點(diǎn)交叉 | 基于 GA 的成員 | Holland,DeJong,Goldberg | 符號(hào) |
| 2 | 雙點(diǎn)交叉 | 使用較多 | Cavicchio,Booker | 符號(hào) |
| 3 | 均勻交叉 | 每一位以相同的概率交叉 | Syswerda,whitely,Yun | 符號(hào) |
| 4 | 多點(diǎn)交叉 | 交換點(diǎn)大于 2 | DeJong,Spears | 符號(hào) |
| 5 | 部分匹配(PMX) | Goldberg | 序號(hào) | |
| 6 | 序號(hào)交叉(OX) | Davis | 序號(hào) | |
| 7 | 圓交叉(CX) | Smith | 序號(hào) | |
| 8 | 基于位置交叉 | Syswerda | 序號(hào) | |
| 9 | 算術(shù)交叉 | Michalewicz | 實(shí)數(shù) | |
| 10 | 啟發(fā)式交叉 | 應(yīng)用領(lǐng)域知識(shí) | Grffenstette | 序號(hào) |
變異算子:
| 1 | 常規(guī)位突變 | 基本 GA 的成員 | DeJong | 符號(hào) |
| 2 | 有效基因突變 | 避免有效基因缺失 | Yun | 符號(hào) |
| 3 | 自適應(yīng)有效基因突變 | 最低有效基因個(gè)數(shù)自適應(yīng)變換 | Yun | 符號(hào) |
| 4 | 概率自調(diào)整突變 | 由兩個(gè)串的相似性確定突變概率 | Whitley | 符號(hào) |
| 5 | 均勻突變 | 每一個(gè)實(shí)數(shù)元素以相同的概率在域內(nèi)變動(dòng) | Michalewicz | 實(shí)數(shù) |
| 6 | 非均勻突變 | 使整個(gè)矢量在解空間輕微變動(dòng) | Michalewicz | 實(shí)數(shù) |
| 7 | 三次高斯近似突變 | Bosworth,Foo,zeigler | 實(shí)數(shù) |
于瑩瑩,陳燕,李桃迎.改進(jìn)的遺傳算法求解旅行商問題[J].控制與決策,2014,29(08):1483-1488. ?? ??
王銀年. 遺傳算法的研究與應(yīng)用[D].江南大學(xué),2009. ??
總結(jié)
以上是生活随笔為你收集整理的TSP(中国旅行商问题)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 剪辑视频,在视频背景上随机添加图片
- 下一篇: 人生之路1.20代码 第一部分