遗传算法旅行社

本文使用遗传算法实现旅行商问题的求解,通过Python编程优化城市路线,降低旅行总距离。文章详细介绍了遗传算法的初始化、交叉、变异等步骤,并展示了优化过程和最终结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import numpy as np  
import matplotlib.pyplot as plt  
import pandas as pd  
import matplotlib as mt  
R = 6371  # 地球距离  
  
# 参数  
citys = 34  # 染色体DNA长度  
pc = 0.1  
pc = 0.2  # 交叉概率  
pc = 0.3  # 交叉概率  
pm = 0.12  # 变异概率  
popsize = 500  # 种群规模  
iternum = 1000  # 迭代次数  
Fitness_choice = [100**0,100**1,100**2,(100**3)/2,100**3,2*100**4]  
def Setdistance(file = 'D:/python/pycharm/pythonProject1/file/x_y.txt'):  
  
    fi = open(file,'rt',encoding = 'UTF-8');txt = fi.readlines()  
    spots = [];X_Y = []  
    for i in range(len(txt)):  
        txt[i] = txt[i].rstrip('\n')  
        if i%2 == 0:  
            spots.append(txt[i])  
        else:  
            X_Y.append(txt[i])  
    for i in range(len(X_Y)):  
  
        x_y =[eval(i) for i in X_Y[i].split(',')]  
        X_Y[i] = x_y  
    global cities  
  
    cities = pd.DataFrame({'spot':spots,'x_y':X_Y})  
Setdistance()  
fi = open('distance.csv','rt');Distance = np.array([[eval(j) for j in i.strip('\n').split(',')] for i in fi.readlines()])  
  
class GA(object):  
    def __init__(self, citys, pc, pm, popsize, ):  
        self.citys = citys  
        self.pc = pc  
        self.pm = pm  
        self.popsize = popsize  
  
        self.pop = np.vstack([np.random.permutation(citys) for _ in range(popsize)])  
  
    def translateDNA(self, DNA, city_position):  
        lineX = np.empty_like(DNA, dtype=np.float64)  
        lineY = np.empty_like(DNA, dtype=np.float64)  
  
        for i, d in enumerate(DNA):  
            city_coord = city_position[d]  
            lineX[i, :] = city_coord[:, 0]  
            lineY[i, :] = city_coord[:, 1]  
        return lineX, lineY  
    def getdist(self,x_y1,x_y2):  
        return R * np.arccos(np.cos(np.radians(x_y1[1])) * np.cos(np.radians(x_y2[1])) * np.cos(np.radians(x_y1[0]- x_y2[0])) + np.sin(np.radians(x_y1[1])) * np.sin(np.radians(x_y2[1])))  
    def getFitness(self, lineX, lineY):  
        totalDis = np.empty((lineX.shape[0],), dtype=np.float64)  
        for j, (xval, yval) in enumerate(zip(lineX, lineY)):  
            sum = 0  
            for i in range(len(xval)-1):  
                sum += self.getdist((xval[i],yval[i]),(xval[i+1],yval[i+1]))  
            sum += self.getdist((xval[len(xval)-1],yval[len(xval)-1]),(xval[0],yval[0]))  
            totalDis[j] = sum  
        TotalDis = totalDis.copy()  
        Dissort = sorted(TotalDis,reverse=True);m1 = Dissort[int(self.popsize/5)];m2 = Dissort[int(self.popsize/3)];m3 = Dissort[int(4*self.popsize/5)];m4 = Dissort[int(99*self.popsize/100)+1];m5 = Dissort[-3]  
        m = [m1,m2,m3,m4,m5]  
        Fitness = np.zeros_like(totalDis)  
        count = 4  
        for i in Fitness_choice[4::-1]:  
            Fitness[TotalDis>m[count]] = i  
            count -= 1  
        Fitness[TotalDis<=m[4]] = Fitness_choice[5]  
        return Fitness, totalDis  
  
    def selection(self, fitness):  
        idx = np.random.choice(np.arange(self.popsize), size=self.popsize, replace=True, p=fitness / fitness.sum())  
        return self.pop[idx]  
  
    def crossover(self, parent, pop):  
        if np.random.rand() < self.pc:  
            i = np.random.randint(0, self.popsize, size=1)  # 随机选取一个个体进行交换  
            if np.random.rand() < 0.3:  
                cross_points = np.random.randint(0, 2, self.citys).astype(np.bool)  # 随机

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值