1. 程式人生 > >旅行商問題之遺傳演算法

旅行商問題之遺傳演算法

  1. 問題描述

行商問題(Travelling Salesman Problem, 簡記TSP,亦稱貨郎擔問題):設有n個城市和距離矩陣,其中表示城市i到城市j的距離,i,j=1,2 … n,則問題是要找出遍訪每個城市恰好一次的一條迴路並使其路徑長度為最短。

  1. 演算法設計

遺傳演算法是通過模擬生物進化過程來完成優化搜尋的,由J. Holland提出的一類借鑑生物界自然選擇和自然遺傳機制的隨機化搜尋演算法。它起源於達爾文的進化論,是模擬達爾文的遺傳選擇和自然淘汰的生物進化過程的計算模型。其主要特點是群體搜尋策略和群體中個體之間的資訊交換,搜尋不以梯度資訊為基礎。“優勝劣汰”這一自然規律的生物進化過程本身是一個自然的、並行發生的、魯棒的優化過程,生物種群通過生物體的遺傳、變異來提高對環境的適應性,從而達到優化的目的。整個遺傳演算法的過程主要包括瞭如下步驟:

1)引數的設定:確定個體編碼方式,這裡即為使用節點編號組成TSP路徑。
2)初始隨機解的生成:隨機生成可行路徑,路徑中不能有重複節點。
3)選擇運算元:選擇父代的策略。
4)交叉運算元:交叉父代併產生新個體,同時需要考慮解決節點衝突。
5)變異運算元:對新個體進行變異操作
6)保留策略:精英保留或者父代完全不參與子代。

  1. 核心虛擬碼
def initPopulation(self):
    """初始化種群"""
    for i in 種群數量
        gene = [x for x in 染色體長度]
        打亂染色體排序

def cross(self, parent1, parent2):
    """交叉"""
    隨機座標 index1
    隨機座標index2
    獲取parent2上index1到index2之間的基因片段 
for g in parent1基因:
        if 當前位置==index1:
            將index1到index2之間的基因片段插入  # 插入基因片段
            當前位置+1
        if g not in index1到index2之間的基因片段:
            將parent1基因插入
            當前位置+1
    交叉變異次數 + 1
    return 新的染色體

def mutation(self, gene):
    """突變"""
    隨機突變基因位置 index1
    隨機突變基因位置 index2
    染色體index1和index2位置基因互換位置
    突變次數 + 1
    return 新的染色體

def newChild(self):
    """產生新的後代"""
    在種群中獲取好的染色體作為parent1
    隨機交叉概率rate
    # 按概率交叉
    if rate < 初始化的交叉概率:
        # 交叉
        在種群中獲取好的染色體作parent2
        交叉(parent1, parent2)
    else:
        parent1直接複製給後代
    # 按概率突變
    隨機突變概率rate
    if rate < 初始化的突變概率:
        突變(gene)
    return 新的後代

  1. 程式碼執行及測試

相關程式碼請見:GitHub:https://github.com/zhiweichen12/python-GA-TCP
遺傳演算法因其隨機演算法的性質,不一定每次都能執行到最優解。同時執行引數的設定對執行結果影響也很大。本實驗具體初始化的引數如下表:
在這裡插入圖片描述

實驗資料採用了中國34個城市(23個省會、4個直轄市、5個自治區及2個特別行政區)的座標資料,從經緯度計算歐式距離,作為兩兩城市間的距離開銷。
在這裡插入圖片描述
為了測試得到相對好的結果,並且考慮到增加區域性搜尋的能力,子代代數越大,變異的概率也相應有一定的增大,測試了多組資料,結果如下:
在這裡插入圖片描述
注:由於每次產生後代都是在隨機概率情況下進行交叉和變異,在迭代次數 固定情況下,以上最小開銷是經過多次試驗後取得的最優解;在迭代次數飽和情 況下,以上最小開銷是以人為觀察隨迭代次數增加其不變的取值。最小開銷均有 一定的誤差。
經過調參試驗,經過了 5017 次迭代,最終得到最小開銷為 167.68。具體詳 情請見下圖:
在這裡插入圖片描述

  1. 結論

本實驗採用的是遺傳演算法的方式來實現旅行商問題。遺傳演算法是一種群體性 演算法,具有並行性,全域性搜尋能力極強,區域性搜尋能力差。引數的選擇對演算法性 能影響很大,並且需要對問題進行編碼。根據前面的實驗資料,在處理資料量大 的問題時,需要增大種群大小和增大迭代次數才能使優化值更接近最優解。演算法 前期收斂較快,但隨著迭代次數的增加,種群陷入區域性較優解,需要長時間的迭 代才能繼續下降,且越接近最優解越難下降。在核心運算元的選擇上,本實驗採用 了相對特殊的操作方式,在適應性函式和選擇操作上,可以做一定的修改,增加 更多的隨機因素,而不僅僅依據排序的結果。在交叉操作上,使用到的啟發式三 交叉方式產生後兩個子代的方式相對樸素,也有改進空間。總體而言,本實驗實 現的演算法,收斂效能較差,容易陷入區域性早熟,這在今後可以調整整體流程,進 一步完善。