當前位置:
首頁 >
基于组合遗传粒子群算法的旅行商问题求解
發布時間:2024/9/30
35
豆豆
生活随笔
收集整理的這篇文章主要介紹了
基于组合遗传粒子群算法的旅行商问题求解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
問題描述
一個商品推銷員要去若干個城市推銷商品,該推銷員從一個城市出發,需要經過所有城市后,回到出發地。應如何選擇行進路線,以使總的行程最短。
對于n個城市的TSP,本文利用python分別實現混合粒子群算法對該問題的求解。
混合粒子群
混合粒子群算法的基本運算過程如下
流程圖如圖
代碼
語言:python
第一步初始化參數
import numpy as np import matplotlib.pyplot as pltclass Hybrid_POS_TSP(object):def __init__(self, data, num_pop=200):self.num_pop = num_pop # 群體個數self.data = data # 城市坐標self.num = len(data) # 城市個數# 群體的初始化和路徑的初始化self.chrom = np.array([0] * self.num_pop * self.num).reshape(self.num_pop, self.num)#shape(num_pop,num)self.fitness = [0] * self.num_pop#一個個體一個適應度函數# 路徑矩陣,函數matrix_dis同遺傳算法self.matrix_distance = self.matrix_dis()距離函數,加入類Hybrid_POS_TSP
# 計算城市間的距離函數 n*n, 第[i,j]個元素表示城市i到j距離def matrix_dis(self):res = np.zeros((self.num, self.num))for i in range(self.num):for j in range(i + 1, self.num):res[i, j] = np.linalg.norm(self.data[i, :] - self.data[j, :]) # 求二階范數 就是距離公式res[j, i] = res[i, j]return res隨機產生初始化群體函數,加入類Hybrid_POS_TSP
# 隨機產生初始化群體函數def rand_chrom(self):rand_ch = np.array(range(self.num)) ## num 城市個數 對應染色體長度 城市=14for i in range(self.num_pop): # num_pop # 群體個數 200np.random.shuffle(rand_ch) # 打亂城市染色體編碼self.chrom[i, :] = rand_ch#.chrom 父代self.fitness[i] = self.comp_fit(rand_ch)# 計算單個染色體的路徑距離值,可利用該函數更新fittnessdef comp_fit(self, one_path):res = 0for i in range(self.num - 1):res += self.matrix_distance[one_path[i], one_path[i + 1]] # matrix_distance n*n, 第[i,j]個元素表示城市i到j距離res += self.matrix_distance[one_path[-1], one_path[0]] # 最后一個城市 到起點距離return res路徑可視化函數,加入類Hybrid_POS_TSP
def out_path(self, one_path):res = str(one_path[0] + 1) + '-->'for i in range(1, self.num):res += str(one_path[i] + 1) + '-->'res += str(one_path[0] + 1) + '\n'print(res)兩條路徑的交叉函數:將每個個體與該個體的個體極值和當前群體的群體極值進行交叉操作。代碼加入類Hybrid_POS_TSP
#兩條路徑的交叉函數:將每個個體與該個體的個體極值和當前群體的群體極值進行交叉操作def cross_1(self, path, best_path):#path為 個體最優 ,best_path為群體最優r1 = np.random.randint(self.num)#隨機產生小于num的整數r2 = np.random.randint(self.num)#隨機產生小于num的整數while r2 == r1:#如果兩者相等r2 = np.random.randint(self.num)#重新產生r2left, right = min(r1, r2), max(r1, r2)#left 為(r1,r2)小者,right 為(r1,r2)大者cross = best_path[left:right + 1]#交叉片段為 群體最優中的(r1:r2)片段#下面的for 循環是為了確保 個體染色體(0:(num-(right-left+1)) 片段 不含有 cross中的元素。for i in range(right - left + 1):#有(r2-r1)次遍歷for k in range(self.num):#遍歷個體染色體中的每一個值if path[k] == cross[i]:#如果當前個體染色體元素path[k] 是cross之內path[k:self.num - 1] = path[k + 1:self.num] #則修改path[k:num - 1] 片段,同時末尾補0 (也就是說把不屬于cross的個體染色體元素 往前趕path[-1] = 0path[self.num - right + left - 1:self.num] = cross#把個體染色體(num-(right-left+1):num ) 片段 和群體交叉return path變異函數:對單個染色體隨機交換兩個點的位置。代碼加入類Hybrid_POS_TSP
def mutation(self, path):#path 個體染色體r1 = np.random.randint(self.num)#隨機生成小于num的整數r2 = np.random.randint(self.num)#隨機生成小于num的整數while r2 == r1:#如果r1==r2r2 = np.random.randint(self.num)#則r2再重新生成path[r1], path[r2] = path[r2], path[r1]#交換片段return path主函數
#data = np.random.rand(20, 2) * 10 # 隨機產生20個城市坐標 def main(data, max_n=200, num_pop=200):#迭代次數max_n200 群體個數num_pop=200Path_short = Hybrid_POS_TSP(data, num_pop=num_pop) # 混合粒子群算法類Path_short.rand_chrom() # 初始化種群# 初始化路徑繪圖fig, ax = plt.subplots()x = data[:, 0]y = data[:, 1]ax.scatter(x, y, linewidths=0.1)for i, txt in enumerate(range(1, len(data) + 1)):ax.annotate(txt, (x[i], y[i]))res0 = Path_short.chrom[0]x0 = x[res0]y0 = y[res0]for i in range(len(data) - 1):plt.quiver(x0[i], y0[i], x0[i + 1] - x0[i], y0[i + 1] - y0[i], color='r', width=0.005, angles='xy', scale=1,scale_units='xy')plt.quiver(x0[-1], y0[-1], x0[0] - x0[-1], y0[0] - y0[-1], color='r', width=0.005, angles='xy', scale=1,scale_units='xy')plt.show()print('初始染色體的路程: ' + str(Path_short.fitness[0]))#定義6個容器 分別存放個體極值,個體染色體,群體最優極值,群體最優染色體,每一次迭代后的最優極值,每一次迭代后最優個體染色體 (容器定義的樣子要和染色體個數等一致)# 存儲個體極值的路徑和距離best_P_chrom = Path_short.chrom.copy()# 個體極值 路徑 (個體染色體)best_P_fit = Path_short.fitness.copy()#個體極值 距離min_index = np.argmin(Path_short.fitness)#最優個體的index序號#存儲當前種群極值的路徑和距離best_G_chrom = Path_short.chrom[min_index, :]#存儲當前種群極值的路徑(群體最優染色體)best_G_fit = Path_short.fitness[min_index]#存儲當前種群極值的距離(群體最優極值)# 存儲每一步迭代后的最優路徑和距離best_chrom = [best_G_chrom]#當代最優個體best_fit = [best_G_fit]#當代最優極值# 復制當前群體進行交叉變異x_new = Path_short.chrom.copy()# 進入迭代 更新個體極值,個體染色體,群體最優極值,群體最優個體,存放當代最優個體,存放當代最優極值for i in range(max_n):#遍歷迭代# 更新當前的個體極值 和路徑 #for j in range(num_pop):#遍歷每一個個體if Path_short.fitness[j] < best_P_fit[j]:#best_P_fit[j] = Path_short.fitness[j]#更新個體極值best_P_chrom[j, :] = Path_short.chrom[j, :]#更新個體極值路徑# 更新當前種群的群體極值min_index = np.argmin(Path_short.fitness)best_G_chrom = Path_short.chrom[min_index, :]#群體極值 路徑best_G_fit = Path_short.fitness[min_index]#群體極值# 添加 每一次迭代后的 當代全局最優個體和解極值if best_G_fit < best_fit[-1]:#best_G_fit 全局極值 best_fit每一步迭代后的最優極值best_fit.append(best_G_fit)#best_chrom.append(best_G_chrom)else:best_fit.append(best_fit[-1])best_chrom.append(best_chrom[-1])#遍歷每一個個體,將個體與當代最優個體進行有條件交叉;個體有條件自我變異。條件都為(個體適應度是否更好,如果是則交叉變異# 將每個個體與個體極值和當前的群體極值進行交叉for j in range(num_pop):#遍歷每一個個體 # 與當代極值交叉x_new[j, :] = Path_short.cross_1(x_new[j, :], best_G_chrom)fit = Path_short.comp_fit(x_new[j, :])if fit < Path_short.fitness[j]:Path_short.chrom[j, :] = x_new[j, :]Path_short.fitness[j] = fit# 變異x_new[j, :] = Path_short.mutation(x_new[j, :])fit = Path_short.comp_fit(x_new[j, :])if fit <= Path_short.fitness[j]:Path_short.chrom[j] = x_new[j, :]Path_short.fitness[j] = fitif (i + 1) % 20 == 0:print('第' + str(i + 1) + '步后的最短的路程: ' + str(Path_short.fitness[min_index]))print('第' + str(i + 1) + '步后的最優路徑:')Path_short.out_path(Path_short.chrom[min_index, :]) # 顯示每一步的最優路徑Path_short.best_chrom = best_chromPath_short.best_fit = best_fit#畫出最優路徑res1 = Path_short.best_chrom[-1]x0 = x[res1]y0 = y[res1]for i in range(len(data) - 1):plt.quiver(x0[i], y0[i], x0[i + 1] - x0[i], y0[i + 1] - y0[i], color='r', width=0.005, angles='xy', scale=1,scale_units='xy')plt.quiver(x0[-1], y0[-1], x0[0] - x0[-1], y0[0] - y0[-1], color='r', width=0.005, angles='xy', scale=1,scale_units='xy')plt.show()return Path_short # 返回結果類if __name__ == '__main__':# 路徑坐標np.random.seed(10)data = np.random.rand(20, 2) * 10 # 隨機產生20個城市坐標main(data,)結果:
開始路徑
結果路徑
作者:電氣余登武。寫作不容易,點個贊再走。
總結
以上是生活随笔為你收集整理的基于组合遗传粒子群算法的旅行商问题求解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 银行积分怎么兑换
- 下一篇: pandas基本数据处理